mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Fixed an iOS stat call and an image loading bug.
This commit is contained in:
parent
e387132522
commit
769e6d185d
8 changed files with 806 additions and 34 deletions
|
|
@ -27180,6 +27180,111 @@ void AudioDataConverters::deinterleaveSamples (const float* const source,
|
|||
}
|
||||
}
|
||||
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
/*class AudioConversionTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
AudioConversionTests() : UnitTest ("Audio data conversion") {}
|
||||
|
||||
template <class SourceType, class DestType>
|
||||
struct Test5
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
const int numSamples = 2048;
|
||||
int32 original [numSamples], converted [numSamples], reversed [numSamples];
|
||||
|
||||
{
|
||||
SourceType d (original);
|
||||
|
||||
for (int i = 0; i < numSamples / 2; ++i)
|
||||
{
|
||||
d.setAsFloat (Random::getSystemRandom().nextFloat() * 2.0f - 1.0f);
|
||||
d.advance();
|
||||
d.setAsInt32 (Random::getSystemRandom().nextInt());
|
||||
d.advance();
|
||||
}
|
||||
}
|
||||
|
||||
// convert data from the source to dest format..
|
||||
ScopedPointer<AudioData::Converter> conv (new AudioData::ConverterInstance <SourceType, DestType>());
|
||||
conv->copySamples (converted, original, numSamples);
|
||||
|
||||
// ..and back again..
|
||||
conv = new AudioData::ConverterInstance <DestType, SourceType>();
|
||||
zerostruct (reversed);
|
||||
conv->copySamples (reversed, converted, numSamples);
|
||||
|
||||
{
|
||||
int biggestDiff = 0;
|
||||
SourceType d1 (original);
|
||||
SourceType d2 (reversed);
|
||||
|
||||
const int errorMargin = 2 * DestType::get32BitResolution() + SourceType::get32BitResolution();
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
biggestDiff = jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32()));
|
||||
d1.advance();
|
||||
d2.advance();
|
||||
}
|
||||
|
||||
unitTest.expect (biggestDiff <= errorMargin);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class SourceType, class FormatType>
|
||||
struct Test3
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
Test5 <SourceType, AudioData::Pointer <FormatType, AudioData::BigEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
Test5 <SourceType, AudioData::Pointer <FormatType, AudioData::LittleEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
}
|
||||
};
|
||||
|
||||
template <class SourceType>
|
||||
struct Test2
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
Test3 <SourceType, AudioData::Int16>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Int24>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Int32>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Float32>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Int8>::test (unitTest);
|
||||
}
|
||||
};
|
||||
|
||||
template <class FormatType>
|
||||
struct Test1
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
Test2 <AudioData::Pointer <FormatType, AudioData::BigEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
Test2 <AudioData::Pointer <FormatType, AudioData::LittleEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
}
|
||||
};
|
||||
|
||||
void runTest()
|
||||
{
|
||||
beginTest ("Round-trip conversion");
|
||||
|
||||
Test1 <AudioData::Int8>::test (*this);
|
||||
Test1 <AudioData::Int16>::test (*this);
|
||||
Test1 <AudioData::Int24>::test (*this);
|
||||
Test1 <AudioData::Int32>::test (*this);
|
||||
Test1 <AudioData::Float32>::test (*this);
|
||||
}
|
||||
};
|
||||
|
||||
static AudioConversionTests audioConversionUnitTests;
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
/*** End of inlined file: juce_AudioDataConverters.cpp ***/
|
||||
|
||||
|
|
@ -254969,15 +255074,25 @@ bool File::setAsCurrentWorkingDirectory() const
|
|||
return chdir (getFullPathName().toUTF8()) == 0;
|
||||
}
|
||||
|
||||
static bool juce_stat (const String& fileName, struct stat& info)
|
||||
#if JUCE_IOS
|
||||
typedef struct stat64 juce_statStruct; // (need to use the 64-bit version to work around a simulator bug)
|
||||
#else
|
||||
typedef struct stat juce_statStruct;
|
||||
#endif
|
||||
|
||||
static bool juce_stat (const String& fileName, juce_statStruct& info)
|
||||
{
|
||||
return fileName.isNotEmpty()
|
||||
#if JUCE_IOS
|
||||
&& (stat64 (fileName.toUTF8(), &info) == 0);
|
||||
#else
|
||||
&& (stat (fileName.toUTF8(), &info) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool File::isDirectory() const
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
|
||||
return fullPath.isEmpty()
|
||||
|| (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
|
||||
|
|
@ -254996,7 +255111,7 @@ bool File::existsAsFile() const
|
|||
|
||||
int64 File::getSize() const
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
return juce_stat (fullPath, info) ? info.st_size : 0;
|
||||
}
|
||||
|
||||
|
|
@ -255013,9 +255128,8 @@ bool File::hasWriteAccess() const
|
|||
|
||||
bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const
|
||||
{
|
||||
struct stat info;
|
||||
const int res = stat (fullPath.toUTF8(), &info);
|
||||
if (res != 0)
|
||||
juce_statStruct info;
|
||||
if (! juce_stat (fullPath, info))
|
||||
return false;
|
||||
|
||||
info.st_mode &= 0777; // Just permissions
|
||||
|
|
@ -255035,9 +255149,8 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int
|
|||
accessTime = 0;
|
||||
creationTime = 0;
|
||||
|
||||
struct stat info;
|
||||
const int res = stat (fullPath.toUTF8(), &info);
|
||||
if (res == 0)
|
||||
juce_statStruct info;
|
||||
if (juce_stat (fullPath, info))
|
||||
{
|
||||
modificationTime = (int64) info.st_mtime * 1000;
|
||||
accessTime = (int64) info.st_atime * 1000;
|
||||
|
|
@ -264762,15 +264875,25 @@ bool File::setAsCurrentWorkingDirectory() const
|
|||
return chdir (getFullPathName().toUTF8()) == 0;
|
||||
}
|
||||
|
||||
static bool juce_stat (const String& fileName, struct stat& info)
|
||||
#if JUCE_IOS
|
||||
typedef struct stat64 juce_statStruct; // (need to use the 64-bit version to work around a simulator bug)
|
||||
#else
|
||||
typedef struct stat juce_statStruct;
|
||||
#endif
|
||||
|
||||
static bool juce_stat (const String& fileName, juce_statStruct& info)
|
||||
{
|
||||
return fileName.isNotEmpty()
|
||||
#if JUCE_IOS
|
||||
&& (stat64 (fileName.toUTF8(), &info) == 0);
|
||||
#else
|
||||
&& (stat (fileName.toUTF8(), &info) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool File::isDirectory() const
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
|
||||
return fullPath.isEmpty()
|
||||
|| (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
|
||||
|
|
@ -264789,7 +264912,7 @@ bool File::existsAsFile() const
|
|||
|
||||
int64 File::getSize() const
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
return juce_stat (fullPath, info) ? info.st_size : 0;
|
||||
}
|
||||
|
||||
|
|
@ -264806,9 +264929,8 @@ bool File::hasWriteAccess() const
|
|||
|
||||
bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const
|
||||
{
|
||||
struct stat info;
|
||||
const int res = stat (fullPath.toUTF8(), &info);
|
||||
if (res != 0)
|
||||
juce_statStruct info;
|
||||
if (! juce_stat (fullPath, info))
|
||||
return false;
|
||||
|
||||
info.st_mode &= 0777; // Just permissions
|
||||
|
|
@ -264828,9 +264950,8 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int
|
|||
accessTime = 0;
|
||||
creationTime = 0;
|
||||
|
||||
struct stat info;
|
||||
const int res = stat (fullPath.toUTF8(), &info);
|
||||
if (res == 0)
|
||||
juce_statStruct info;
|
||||
if (juce_stat (fullPath, info))
|
||||
{
|
||||
modificationTime = (int64) info.st_mtime * 1000;
|
||||
accessTime = (int64) info.st_atime * 1000;
|
||||
|
|
@ -265548,7 +265669,7 @@ public:
|
|||
|
||||
if (isDir != 0 || fileSize != 0 || modTime != 0 || creationTime != 0)
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
const bool statOk = juce_stat (path, info);
|
||||
|
||||
if (isDir != 0) *isDir = statOk && ((info.st_mode & S_IFDIR) != 0);
|
||||
|
|
@ -267393,7 +267514,9 @@ const Image juce_loadWithCoreImage (InputStream& input)
|
|||
|
||||
#if JUCE_IOS
|
||||
JUCE_AUTORELEASEPOOL
|
||||
UIImage* image = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData() length: data.getSize()]];
|
||||
UIImage* image = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData()
|
||||
length: data.getSize()
|
||||
freeWhenDone: NO]];
|
||||
|
||||
if (image != nil)
|
||||
{
|
||||
|
|
@ -272073,7 +272196,9 @@ const Image juce_loadWithCoreImage (InputStream& input)
|
|||
|
||||
#if JUCE_IOS
|
||||
JUCE_AUTORELEASEPOOL
|
||||
UIImage* image = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData() length: data.getSize()]];
|
||||
UIImage* image = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData()
|
||||
length: data.getSize()
|
||||
freeWhenDone: NO]];
|
||||
|
||||
if (image != nil)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 67
|
||||
#define JUCE_BUILDNUMBER 68
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -37771,6 +37771,267 @@ private:
|
|||
#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
||||
#define __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
||||
|
||||
/**
|
||||
|
||||
*/
|
||||
/*
|
||||
struct JUCE_API AudioData
|
||||
{
|
||||
xxx need to add int range limiting..
|
||||
|
||||
struct BigEndian
|
||||
{
|
||||
template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) throw() { return s.getAsFloatBE(); }
|
||||
template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) throw() { s.setAsFloatBE (newValue); }
|
||||
template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) throw() { return s.getAsInt32BE(); }
|
||||
template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) throw() { s.setAsInt32BE (newValue); }
|
||||
template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) throw() { dest.copyFromBE (source); }
|
||||
};
|
||||
|
||||
struct LittleEndian
|
||||
{
|
||||
template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) throw() { return s.getAsFloatLE(); }
|
||||
template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) throw() { s.setAsFloatLE (newValue); }
|
||||
template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) throw() { return s.getAsInt32LE(); }
|
||||
template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) throw() { s.setAsInt32LE (newValue); }
|
||||
template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) throw() { dest.copyFromLE (source); }
|
||||
};
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
typedef BigEndian NativeEndian;
|
||||
#else
|
||||
typedef LittleEndian NativeEndian;
|
||||
#endif
|
||||
|
||||
struct Int8
|
||||
{
|
||||
inline Int8 (void* data_) : data (static_cast <int8*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
inline float getAsFloatLE() const throw() { return (float) (*data * (1.0 / maxValue)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) (*data * (1.0 / maxValue)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = (int8) roundToInt (newValue * (double) maxValue); }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = (int8) roundToInt (newValue * (double) maxValue); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int) (*data << 24); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int) (*data << 24); }
|
||||
inline void setAsInt32LE (int newValue) throw() { *data = (int8) (newValue >> 24); }
|
||||
inline void setAsInt32BE (int newValue) throw() { *data = (int8) (newValue >> 24); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int8& source) throw() { *data = *source.data; }
|
||||
|
||||
int8* data;
|
||||
enum { maxValue = 0x80, resolution = 0x1000000, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Int16
|
||||
{
|
||||
inline Int16 (void* data_) : data (static_cast <uint16*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
inline float getAsFloatLE() const throw() { return (float) ((1.0 / maxValue) * (int16) ByteOrder::swapIfBigEndian (*data)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) ((1.0 / maxValue) * (int16) ByteOrder::swapIfLittleEndian (*data)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint16) roundToInt (newValue * (double) maxValue)); }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint16) roundToInt (newValue * (double) maxValue)); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) (ByteOrder::swapIfBigEndian ((uint16) *data) << 16); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) (ByteOrder::swapIfLittleEndian ((uint16) *data) << 16); }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint16) (newValue >> 16)); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint16) (newValue >> 16)); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int16& source) throw() { *data = *source.data; }
|
||||
|
||||
uint16* data;
|
||||
enum { maxValue = 0x8000, resolution = 0x10000, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Int24
|
||||
{
|
||||
inline Int24 (void* data_) : data (static_cast <char*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { data += 3; }
|
||||
inline void skip (int numSamples) throw() { data += 3 * numSamples; }
|
||||
|
||||
inline float getAsFloatLE() const throw() { return (float) (ByteOrder::littleEndian24Bit (data) * (1.0 / maxValue)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) (ByteOrder::bigEndian24Bit (data) * (1.0 / maxValue)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { ByteOrder::littleEndian24BitToChars (roundToInt (newValue * (double) maxValue), data); }
|
||||
inline void setAsFloatBE (float newValue) throw() { ByteOrder::bigEndian24BitToChars (roundToInt (newValue * (double) maxValue), data); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) ByteOrder::littleEndian24Bit (data) << 8; }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) ByteOrder::bigEndian24Bit (data) << 8; }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { ByteOrder::littleEndian24BitToChars (newValue >> 8, data); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { ByteOrder::bigEndian24BitToChars (newValue >> 8, data); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int24& source) throw() { data[0] = source.data[0]; data[1] = source.data[1]; data[2] = source.data[2]; }
|
||||
|
||||
char* data;
|
||||
enum { maxValue = 0x800000, resolution = 0x100, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Int32
|
||||
{
|
||||
inline Int32 (void* data_) : data (static_cast <uint32*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
inline float getAsFloatLE() const throw() { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint32) roundToInt (newValue * (1.0 + maxValue))); }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (newValue * (1.0 + maxValue))); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) ByteOrder::swapIfBigEndian (*data); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) ByteOrder::swapIfLittleEndian (*data); }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint32) newValue); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint32) newValue); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int32& source) throw() { *data = *source.data; }
|
||||
|
||||
uint32* data;
|
||||
enum { maxValue = 0x7fffffff, resolution = 1, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Float32
|
||||
{
|
||||
inline Float32 (void* data_) : data (static_cast <float*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
inline float getAsFloatBE() const throw() { return *data; }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = newValue; }
|
||||
inline float getAsFloatLE() const throw() { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; }
|
||||
inline void setAsFloatLE (float newValue) throw() { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
|
||||
#else
|
||||
inline float getAsFloatLE() const throw() { return *data; }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = newValue; }
|
||||
inline float getAsFloatBE() const throw() { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; }
|
||||
inline void setAsFloatBE (float newValue) throw() { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
|
||||
#endif
|
||||
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) roundToInt (getAsFloatLE() * (1.0 + maxValue)); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) roundToInt (getAsFloatBE() * (1.0 + maxValue)); }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { setAsFloatLE ((float) (newValue * (1.0 / (1.0 + maxValue)))); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { setAsFloatBE ((float) (newValue * (1.0 / (1.0 + maxValue)))); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsFloatLE (source.getAsFloat()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsFloatBE (source.getAsFloat()); }
|
||||
inline void copyFromSameType (Float32& source) throw() { *data = *source.data; }
|
||||
|
||||
float* data;
|
||||
enum { maxValue = 0x7fffffff, resolution = 0x100, isFloat = 1 };
|
||||
};
|
||||
|
||||
struct NonInterleaved
|
||||
{
|
||||
inline NonInterleaved () throw() {}
|
||||
inline NonInterleaved (const int numChannels) throw()
|
||||
{ jassert (numChannels == 1); } // If you hit this assert, you're trying to create a non-interleaved pointer with more than one interleaved channel..
|
||||
|
||||
template <class SampleFormatType> inline void advance (SampleFormatType& s) throw() { s.advance(); }
|
||||
};
|
||||
|
||||
struct Interleaved
|
||||
{
|
||||
inline Interleaved () throw() : numChannels (1) {}
|
||||
inline Interleaved (const int numChannels_) throw() : numChannels (numChannels_) {}
|
||||
template <class SampleFormatType> inline void advance (SampleFormatType& s) throw() { s.skip (numChannels); }
|
||||
|
||||
const int numChannels;
|
||||
};
|
||||
|
||||
template <class SampleFormat,
|
||||
class Endianness,
|
||||
class InterleavingType>
|
||||
class Pointer
|
||||
{
|
||||
public:
|
||||
Pointer (const void* sourceData)
|
||||
: data (const_cast <void*> (sourceData))
|
||||
{
|
||||
}
|
||||
|
||||
Pointer (const void* sourceData, int numInterleavedChannels)
|
||||
: data (const_cast <void*> (sourceData)),
|
||||
interleaving (numInterleavedChannels)
|
||||
{
|
||||
}
|
||||
|
||||
inline float getAsFloat() const throw() { return Endianness::getAsFloat (data); }
|
||||
inline void setAsFloat (float newValue) throw() { Endianness::setAsFloat (data, newValue); }
|
||||
|
||||
inline int32 getAsInt32() const throw() { return Endianness::getAsInt32 (data); }
|
||||
inline void setAsInt32 (int32 newValue) throw() { Endianness::setAsInt32 (data, newValue); }
|
||||
|
||||
inline void advance() throw() { interleaving.advance (data); }
|
||||
|
||||
void copySamples (Pointer& source, int numSamples)
|
||||
{
|
||||
while (--numSamples >= 0)
|
||||
{
|
||||
data.copyFromSameType (source.data);
|
||||
advance();
|
||||
source.advance();
|
||||
}
|
||||
}
|
||||
|
||||
template <class OtherPointerType>
|
||||
void copySamples (OtherPointerType& source, int numSamples)
|
||||
{
|
||||
while (--numSamples >= 0)
|
||||
{
|
||||
Endianness::copyFrom (data, source);
|
||||
advance();
|
||||
source.advance();
|
||||
}
|
||||
}
|
||||
|
||||
bool isFloatingPoint() const throw() { return (bool) SampleFormat::isFloat; }
|
||||
static int get32BitResolution() throw() { return (int) SampleFormat::resolution; }
|
||||
|
||||
typedef Endianness EndiannessType;
|
||||
|
||||
private:
|
||||
|
||||
SampleFormat data;
|
||||
InterleavingType interleaving;
|
||||
};
|
||||
|
||||
class Converter
|
||||
{
|
||||
public:
|
||||
virtual ~Converter() {}
|
||||
|
||||
virtual void copySamples (void* dest, const void* source, int numSamples) const = 0;
|
||||
};
|
||||
|
||||
template <class SourceSampleType, class DestSampleType>
|
||||
class ConverterInstance : public Converter
|
||||
{
|
||||
public:
|
||||
ConverterInstance() {}
|
||||
~ConverterInstance() {}
|
||||
|
||||
void copySamples (void* const dest, const void* const source, const int numSamples) const
|
||||
{
|
||||
SourceSampleType s (source);
|
||||
DestSampleType d (dest);
|
||||
d.copySamples (s, numSamples);
|
||||
}
|
||||
|
||||
private:
|
||||
ConverterInstance (const ConverterInstance&);
|
||||
ConverterInstance& operator= (const ConverterInstance&);
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
A set of routines to convert buffers of 32-bit floating point data to and from
|
||||
various integer formats.
|
||||
|
|
|
|||
|
|
@ -531,5 +531,113 @@ void AudioDataConverters::deinterleaveSamples (const float* const source,
|
|||
}
|
||||
}
|
||||
|
||||
#if JUCE_UNIT_TESTS
|
||||
|
||||
#include "../../utilities/juce_UnitTest.h"
|
||||
#include "../../core/juce_Random.h"
|
||||
|
||||
/*class AudioConversionTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
AudioConversionTests() : UnitTest ("Audio data conversion") {}
|
||||
|
||||
template <class SourceType, class DestType>
|
||||
struct Test5
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
const int numSamples = 2048;
|
||||
int32 original [numSamples], converted [numSamples], reversed [numSamples];
|
||||
|
||||
{
|
||||
SourceType d (original);
|
||||
|
||||
for (int i = 0; i < numSamples / 2; ++i)
|
||||
{
|
||||
d.setAsFloat (Random::getSystemRandom().nextFloat() * 2.0f - 1.0f);
|
||||
d.advance();
|
||||
d.setAsInt32 (Random::getSystemRandom().nextInt());
|
||||
d.advance();
|
||||
}
|
||||
}
|
||||
|
||||
// convert data from the source to dest format..
|
||||
ScopedPointer<AudioData::Converter> conv (new AudioData::ConverterInstance <SourceType, DestType>());
|
||||
conv->copySamples (converted, original, numSamples);
|
||||
|
||||
// ..and back again..
|
||||
conv = new AudioData::ConverterInstance <DestType, SourceType>();
|
||||
zerostruct (reversed);
|
||||
conv->copySamples (reversed, converted, numSamples);
|
||||
|
||||
{
|
||||
int biggestDiff = 0;
|
||||
SourceType d1 (original);
|
||||
SourceType d2 (reversed);
|
||||
|
||||
const int errorMargin = 2 * DestType::get32BitResolution() + SourceType::get32BitResolution();
|
||||
|
||||
for (int i = 0; i < numSamples; ++i)
|
||||
{
|
||||
biggestDiff = jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32()));
|
||||
d1.advance();
|
||||
d2.advance();
|
||||
}
|
||||
|
||||
unitTest.expect (biggestDiff <= errorMargin);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class SourceType, class FormatType>
|
||||
struct Test3
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
Test5 <SourceType, AudioData::Pointer <FormatType, AudioData::BigEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
Test5 <SourceType, AudioData::Pointer <FormatType, AudioData::LittleEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
}
|
||||
};
|
||||
|
||||
template <class SourceType>
|
||||
struct Test2
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
Test3 <SourceType, AudioData::Int16>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Int24>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Int32>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Float32>::test (unitTest);
|
||||
Test3 <SourceType, AudioData::Int8>::test (unitTest);
|
||||
}
|
||||
};
|
||||
|
||||
template <class FormatType>
|
||||
struct Test1
|
||||
{
|
||||
static void test (UnitTest& unitTest)
|
||||
{
|
||||
Test2 <AudioData::Pointer <FormatType, AudioData::BigEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
Test2 <AudioData::Pointer <FormatType, AudioData::LittleEndian, AudioData::NonInterleaved> >::test (unitTest);
|
||||
}
|
||||
};
|
||||
|
||||
void runTest()
|
||||
{
|
||||
beginTest ("Round-trip conversion");
|
||||
|
||||
Test1 <AudioData::Int8>::test (*this);
|
||||
Test1 <AudioData::Int16>::test (*this);
|
||||
Test1 <AudioData::Int24>::test (*this);
|
||||
Test1 <AudioData::Int32>::test (*this);
|
||||
Test1 <AudioData::Float32>::test (*this);
|
||||
}
|
||||
};
|
||||
|
||||
static AudioConversionTests audioConversionUnitTests;
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -26,6 +26,274 @@
|
|||
#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
||||
#define __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
|
||||
*/
|
||||
/*
|
||||
struct JUCE_API AudioData
|
||||
{
|
||||
xxx need to add int range limiting..
|
||||
//==============================================================================
|
||||
struct BigEndian
|
||||
{
|
||||
template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) throw() { return s.getAsFloatBE(); }
|
||||
template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) throw() { s.setAsFloatBE (newValue); }
|
||||
template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) throw() { return s.getAsInt32BE(); }
|
||||
template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) throw() { s.setAsInt32BE (newValue); }
|
||||
template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) throw() { dest.copyFromBE (source); }
|
||||
};
|
||||
|
||||
struct LittleEndian
|
||||
{
|
||||
template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) throw() { return s.getAsFloatLE(); }
|
||||
template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) throw() { s.setAsFloatLE (newValue); }
|
||||
template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) throw() { return s.getAsInt32LE(); }
|
||||
template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) throw() { s.setAsInt32LE (newValue); }
|
||||
template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) throw() { dest.copyFromLE (source); }
|
||||
};
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
typedef BigEndian NativeEndian;
|
||||
#else
|
||||
typedef LittleEndian NativeEndian;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
struct Int8
|
||||
{
|
||||
inline Int8 (void* data_) : data (static_cast <int8*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
inline float getAsFloatLE() const throw() { return (float) (*data * (1.0 / maxValue)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) (*data * (1.0 / maxValue)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = (int8) roundToInt (newValue * (double) maxValue); }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = (int8) roundToInt (newValue * (double) maxValue); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int) (*data << 24); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int) (*data << 24); }
|
||||
inline void setAsInt32LE (int newValue) throw() { *data = (int8) (newValue >> 24); }
|
||||
inline void setAsInt32BE (int newValue) throw() { *data = (int8) (newValue >> 24); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int8& source) throw() { *data = *source.data; }
|
||||
|
||||
int8* data;
|
||||
enum { maxValue = 0x80, resolution = 0x1000000, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Int16
|
||||
{
|
||||
inline Int16 (void* data_) : data (static_cast <uint16*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
inline float getAsFloatLE() const throw() { return (float) ((1.0 / maxValue) * (int16) ByteOrder::swapIfBigEndian (*data)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) ((1.0 / maxValue) * (int16) ByteOrder::swapIfLittleEndian (*data)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint16) roundToInt (newValue * (double) maxValue)); }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint16) roundToInt (newValue * (double) maxValue)); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) (ByteOrder::swapIfBigEndian ((uint16) *data) << 16); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) (ByteOrder::swapIfLittleEndian ((uint16) *data) << 16); }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint16) (newValue >> 16)); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint16) (newValue >> 16)); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int16& source) throw() { *data = *source.data; }
|
||||
|
||||
uint16* data;
|
||||
enum { maxValue = 0x8000, resolution = 0x10000, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Int24
|
||||
{
|
||||
inline Int24 (void* data_) : data (static_cast <char*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { data += 3; }
|
||||
inline void skip (int numSamples) throw() { data += 3 * numSamples; }
|
||||
|
||||
inline float getAsFloatLE() const throw() { return (float) (ByteOrder::littleEndian24Bit (data) * (1.0 / maxValue)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) (ByteOrder::bigEndian24Bit (data) * (1.0 / maxValue)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { ByteOrder::littleEndian24BitToChars (roundToInt (newValue * (double) maxValue), data); }
|
||||
inline void setAsFloatBE (float newValue) throw() { ByteOrder::bigEndian24BitToChars (roundToInt (newValue * (double) maxValue), data); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) ByteOrder::littleEndian24Bit (data) << 8; }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) ByteOrder::bigEndian24Bit (data) << 8; }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { ByteOrder::littleEndian24BitToChars (newValue >> 8, data); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { ByteOrder::bigEndian24BitToChars (newValue >> 8, data); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int24& source) throw() { data[0] = source.data[0]; data[1] = source.data[1]; data[2] = source.data[2]; }
|
||||
|
||||
char* data;
|
||||
enum { maxValue = 0x800000, resolution = 0x100, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Int32
|
||||
{
|
||||
inline Int32 (void* data_) : data (static_cast <uint32*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
inline float getAsFloatLE() const throw() { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); }
|
||||
inline float getAsFloatBE() const throw() { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint32) roundToInt (newValue * (1.0 + maxValue))); }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (newValue * (1.0 + maxValue))); }
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) ByteOrder::swapIfBigEndian (*data); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) ByteOrder::swapIfLittleEndian (*data); }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { *data = ByteOrder::swapIfBigEndian ((uint32) newValue); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { *data = ByteOrder::swapIfLittleEndian ((uint32) newValue); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsInt32LE (source.getAsInt32()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsInt32BE (source.getAsInt32()); }
|
||||
inline void copyFromSameType (Int32& source) throw() { *data = *source.data; }
|
||||
|
||||
uint32* data;
|
||||
enum { maxValue = 0x7fffffff, resolution = 1, isFloat = 0 };
|
||||
};
|
||||
|
||||
struct Float32
|
||||
{
|
||||
inline Float32 (void* data_) : data (static_cast <float*> (data_)) {}
|
||||
|
||||
inline void advance() throw() { ++data; }
|
||||
inline void skip (int numSamples) throw() { data += numSamples; }
|
||||
|
||||
#if JUCE_BIG_ENDIAN
|
||||
inline float getAsFloatBE() const throw() { return *data; }
|
||||
inline void setAsFloatBE (float newValue) throw() { *data = newValue; }
|
||||
inline float getAsFloatLE() const throw() { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; }
|
||||
inline void setAsFloatLE (float newValue) throw() { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
|
||||
#else
|
||||
inline float getAsFloatLE() const throw() { return *data; }
|
||||
inline void setAsFloatLE (float newValue) throw() { *data = newValue; }
|
||||
inline float getAsFloatBE() const throw() { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; }
|
||||
inline void setAsFloatBE (float newValue) throw() { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
|
||||
#endif
|
||||
|
||||
inline int32 getAsInt32LE() const throw() { return (int32) roundToInt (getAsFloatLE() * (1.0 + maxValue)); }
|
||||
inline int32 getAsInt32BE() const throw() { return (int32) roundToInt (getAsFloatBE() * (1.0 + maxValue)); }
|
||||
inline void setAsInt32LE (int32 newValue) throw() { setAsFloatLE ((float) (newValue * (1.0 / (1.0 + maxValue)))); }
|
||||
inline void setAsInt32BE (int32 newValue) throw() { setAsFloatBE ((float) (newValue * (1.0 / (1.0 + maxValue)))); }
|
||||
|
||||
template <class SourceType> inline void copyFromLE (SourceType& source) throw() { setAsFloatLE (source.getAsFloat()); }
|
||||
template <class SourceType> inline void copyFromBE (SourceType& source) throw() { setAsFloatBE (source.getAsFloat()); }
|
||||
inline void copyFromSameType (Float32& source) throw() { *data = *source.data; }
|
||||
|
||||
float* data;
|
||||
enum { maxValue = 0x7fffffff, resolution = 0x100, isFloat = 1 };
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct NonInterleaved
|
||||
{
|
||||
inline NonInterleaved () throw() {}
|
||||
inline NonInterleaved (const int numChannels) throw()
|
||||
{ jassert (numChannels == 1); } // If you hit this assert, you're trying to create a non-interleaved pointer with more than one interleaved channel..
|
||||
|
||||
template <class SampleFormatType> inline void advance (SampleFormatType& s) throw() { s.advance(); }
|
||||
};
|
||||
|
||||
struct Interleaved
|
||||
{
|
||||
inline Interleaved () throw() : numChannels (1) {}
|
||||
inline Interleaved (const int numChannels_) throw() : numChannels (numChannels_) {}
|
||||
template <class SampleFormatType> inline void advance (SampleFormatType& s) throw() { s.skip (numChannels); }
|
||||
|
||||
const int numChannels;
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
template <class SampleFormat,
|
||||
class Endianness,
|
||||
class InterleavingType>
|
||||
class Pointer
|
||||
{
|
||||
public:
|
||||
Pointer (const void* sourceData)
|
||||
: data (const_cast <void*> (sourceData))
|
||||
{
|
||||
}
|
||||
|
||||
Pointer (const void* sourceData, int numInterleavedChannels)
|
||||
: data (const_cast <void*> (sourceData)),
|
||||
interleaving (numInterleavedChannels)
|
||||
{
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
inline float getAsFloat() const throw() { return Endianness::getAsFloat (data); }
|
||||
inline void setAsFloat (float newValue) throw() { Endianness::setAsFloat (data, newValue); }
|
||||
|
||||
inline int32 getAsInt32() const throw() { return Endianness::getAsInt32 (data); }
|
||||
inline void setAsInt32 (int32 newValue) throw() { Endianness::setAsInt32 (data, newValue); }
|
||||
|
||||
inline void advance() throw() { interleaving.advance (data); }
|
||||
|
||||
void copySamples (Pointer& source, int numSamples)
|
||||
{
|
||||
while (--numSamples >= 0)
|
||||
{
|
||||
data.copyFromSameType (source.data);
|
||||
advance();
|
||||
source.advance();
|
||||
}
|
||||
}
|
||||
|
||||
template <class OtherPointerType>
|
||||
void copySamples (OtherPointerType& source, int numSamples)
|
||||
{
|
||||
while (--numSamples >= 0)
|
||||
{
|
||||
Endianness::copyFrom (data, source);
|
||||
advance();
|
||||
source.advance();
|
||||
}
|
||||
}
|
||||
|
||||
bool isFloatingPoint() const throw() { return (bool) SampleFormat::isFloat; }
|
||||
static int get32BitResolution() throw() { return (int) SampleFormat::resolution; }
|
||||
|
||||
typedef Endianness EndiannessType;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
SampleFormat data;
|
||||
InterleavingType interleaving;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class Converter
|
||||
{
|
||||
public:
|
||||
virtual ~Converter() {}
|
||||
|
||||
virtual void copySamples (void* dest, const void* source, int numSamples) const = 0;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
template <class SourceSampleType, class DestSampleType>
|
||||
class ConverterInstance : public Converter
|
||||
{
|
||||
public:
|
||||
ConverterInstance() {}
|
||||
~ConverterInstance() {}
|
||||
|
||||
void copySamples (void* const dest, const void* const source, const int numSamples) const
|
||||
{
|
||||
SourceSampleType s (source);
|
||||
DestSampleType d (dest);
|
||||
d.copySamples (s, numSamples);
|
||||
}
|
||||
|
||||
private:
|
||||
ConverterInstance (const ConverterInstance&);
|
||||
ConverterInstance& operator= (const ConverterInstance&);
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 67
|
||||
#define JUCE_BUILDNUMBER 68
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
|
|
@ -220,15 +220,25 @@ bool File::setAsCurrentWorkingDirectory() const
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool juce_stat (const String& fileName, struct stat& info)
|
||||
#if JUCE_IOS
|
||||
typedef struct stat64 juce_statStruct; // (need to use the 64-bit version to work around a simulator bug)
|
||||
#else
|
||||
typedef struct stat juce_statStruct;
|
||||
#endif
|
||||
|
||||
static bool juce_stat (const String& fileName, juce_statStruct& info)
|
||||
{
|
||||
return fileName.isNotEmpty()
|
||||
#if JUCE_IOS
|
||||
&& (stat64 (fileName.toUTF8(), &info) == 0);
|
||||
#else
|
||||
&& (stat (fileName.toUTF8(), &info) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool File::isDirectory() const
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
|
||||
return fullPath.isEmpty()
|
||||
|| (juce_stat (fullPath, info) && ((info.st_mode & S_IFDIR) != 0));
|
||||
|
|
@ -247,7 +257,7 @@ bool File::existsAsFile() const
|
|||
|
||||
int64 File::getSize() const
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
return juce_stat (fullPath, info) ? info.st_size : 0;
|
||||
}
|
||||
|
||||
|
|
@ -265,9 +275,8 @@ bool File::hasWriteAccess() const
|
|||
|
||||
bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const
|
||||
{
|
||||
struct stat info;
|
||||
const int res = stat (fullPath.toUTF8(), &info);
|
||||
if (res != 0)
|
||||
juce_statStruct info;
|
||||
if (! juce_stat (fullPath, info))
|
||||
return false;
|
||||
|
||||
info.st_mode &= 0777; // Just permissions
|
||||
|
|
@ -287,9 +296,8 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int
|
|||
accessTime = 0;
|
||||
creationTime = 0;
|
||||
|
||||
struct stat info;
|
||||
const int res = stat (fullPath.toUTF8(), &info);
|
||||
if (res == 0)
|
||||
juce_statStruct info;
|
||||
if (juce_stat (fullPath, info))
|
||||
{
|
||||
modificationTime = (int64) info.st_mtime * 1000;
|
||||
accessTime = (int64) info.st_atime * 1000;
|
||||
|
|
|
|||
|
|
@ -779,7 +779,9 @@ const Image juce_loadWithCoreImage (InputStream& input)
|
|||
|
||||
#if JUCE_IOS
|
||||
JUCE_AUTORELEASEPOOL
|
||||
UIImage* image = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData() length: data.getSize()]];
|
||||
UIImage* image = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData()
|
||||
length: data.getSize()
|
||||
freeWhenDone: NO]];
|
||||
|
||||
if (image != nil)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ public:
|
|||
|
||||
if (isDir != 0 || fileSize != 0 || modTime != 0 || creationTime != 0)
|
||||
{
|
||||
struct stat info;
|
||||
juce_statStruct info;
|
||||
const bool statOk = juce_stat (path, info);
|
||||
|
||||
if (isDir != 0) *isDir = statOk && ((info.st_mode & S_IFDIR) != 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue