Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 0 additions & 96 deletions modules/yup_audio_basics/buffers/yup_AudioChannelSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1159,100 +1159,4 @@ int AudioChannelSet::getAmbisonicOrderForNumChannels (int numChannels, int maxOr
return -1;
}

//==============================================================================
//==============================================================================
#if YUP_UNIT_TESTS

class AudioChannelSetUnitTest final : public UnitTest
{
public:
AudioChannelSetUnitTest()
: UnitTest ("AudioChannelSetUnitTest", UnitTestCategories::audio)
{
}

void runTest() override
{
auto max = AudioChannelSet::maxChannelsOfNamedLayout;

beginTest ("maxChannelsOfNamedLayout is non-discrete");
expect (AudioChannelSet::channelSetsWithNumberOfChannels (max).size() >= 2);

beginTest ("channelSetsWithNumberOfChannels returns correct speaker count");
{
for (auto ch = 1; ch <= max; ++ch)
{
auto channelSets = AudioChannelSet::channelSetsWithNumberOfChannels (ch);

for (auto set : channelSets)
expect (set.size() == ch);
}
}

beginTest ("Ambisonics");
{
uint64 mask = 0;

mask |= (1ull << AudioChannelSet::ambisonicACN0);
checkAmbisonic (mask, 0, "0th Order Ambisonics");

mask |= (1ull << AudioChannelSet::ambisonicACN1) | (1ull << AudioChannelSet::ambisonicACN2) | (1ull << AudioChannelSet::ambisonicACN3);
checkAmbisonic (mask, 1, "1st Order Ambisonics");

mask |= (1ull << AudioChannelSet::ambisonicACN4) | (1ull << AudioChannelSet::ambisonicACN5) | (1ull << AudioChannelSet::ambisonicACN6)
| (1ull << AudioChannelSet::ambisonicACN7) | (1ull << AudioChannelSet::ambisonicACN8);
checkAmbisonic (mask, 2, "2nd Order Ambisonics");

mask |= (1ull << AudioChannelSet::ambisonicACN9) | (1ull << AudioChannelSet::ambisonicACN10) | (1ull << AudioChannelSet::ambisonicACN11)
| (1ull << AudioChannelSet::ambisonicACN12) | (1ull << AudioChannelSet::ambisonicACN13) | (1ull << AudioChannelSet::ambisonicACN14)
| (1ull << AudioChannelSet::ambisonicACN15);
checkAmbisonic (mask, 3, "3rd Order Ambisonics");

mask |= (1ull << AudioChannelSet::ambisonicACN16) | (1ull << AudioChannelSet::ambisonicACN17) | (1ull << AudioChannelSet::ambisonicACN18)
| (1ull << AudioChannelSet::ambisonicACN19) | (1ull << AudioChannelSet::ambisonicACN20) | (1ull << AudioChannelSet::ambisonicACN21)
| (1ull << AudioChannelSet::ambisonicACN22) | (1ull << AudioChannelSet::ambisonicACN23) | (1ull << AudioChannelSet::ambisonicACN24);
checkAmbisonic (mask, 4, "4th Order Ambisonics");

mask |= (1ull << AudioChannelSet::ambisonicACN25) | (1ull << AudioChannelSet::ambisonicACN26) | (1ull << AudioChannelSet::ambisonicACN27)
| (1ull << AudioChannelSet::ambisonicACN28) | (1ull << AudioChannelSet::ambisonicACN29) | (1ull << AudioChannelSet::ambisonicACN30)
| (1ull << AudioChannelSet::ambisonicACN31) | (1ull << AudioChannelSet::ambisonicACN32) | (1ull << AudioChannelSet::ambisonicACN33)
| (1ull << AudioChannelSet::ambisonicACN34) | (1ull << AudioChannelSet::ambisonicACN35);
checkAmbisonic (mask, 5, "5th Order Ambisonics");
}
}

private:
void checkAmbisonic (uint64 mask, int order, const char* layoutName)
{
auto expected = AudioChannelSet::ambisonic (order);
auto numChannels = expected.size();

expect (numChannels == BigInteger ((int64) mask).countNumberOfSetBits());
expect (channelSetFromMask (mask) == expected);

expect (order == expected.getAmbisonicOrder());
expect (expected.getDescription() == layoutName);

auto layouts = AudioChannelSet::channelSetsWithNumberOfChannels (numChannels);
expect (layouts.contains (expected));

for (auto layout : layouts)
expect (layout.getAmbisonicOrder() == (layout == expected ? order : -1));
}

static AudioChannelSet channelSetFromMask (uint64 mask)
{
Array<AudioChannelSet::ChannelType> channels;
for (int bit = 0; bit <= 62; ++bit)
if ((mask & (1ull << bit)) != 0)
channels.add (static_cast<AudioChannelSet::ChannelType> (bit));

return AudioChannelSet::channelSetWithChannels (channels);
}
};

static AudioChannelSetUnitTest audioChannelSetUnitTest;

#endif

} // namespace yup
182 changes: 0 additions & 182 deletions modules/yup_audio_basics/buffers/yup_AudioDataConverters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,188 +501,6 @@ void AudioDataConverters::deinterleaveSamples (const float* source, float** dest
numSamples);
}

//==============================================================================
//==============================================================================
#if YUP_UNIT_TESTS

class AudioConversionTests final : public UnitTest
{
public:
AudioConversionTests()
: UnitTest ("Audio data conversion", UnitTestCategories::audio)
{
}

template <class F1, class E1, class F2, class E2>
struct Test5
{
static void test (UnitTest& unitTest, Random& r)
{
test (unitTest, false, r);
test (unitTest, true, r);
}

YUP_BEGIN_IGNORE_WARNINGS_MSVC (6262)

static void test (UnitTest& unitTest, bool inPlace, Random& r)
{
const int numSamples = 2048;
int32 original[(size_t) numSamples],
converted[(size_t) numSamples],
reversed[(size_t) numSamples];

{
AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original);
bool clippingFailed = false;

for (int i = 0; i < numSamples / 2; ++i)
{
d.setAsFloat (r.nextFloat() * 2.2f - 1.1f);

if (! d.isFloatingPoint())
clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed;

++d;
d.setAsInt32 (r.nextInt());
++d;
}

unitTest.expect (! clippingFailed);
}

// convert data from the source to dest format..
std::unique_ptr<AudioData::Converter> conv (new AudioData::ConverterInstance<AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>,
AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::NonConst>>());
conv->convertSamples (inPlace ? reversed : converted, original, numSamples);

// ..and back again..
conv.reset (new AudioData::ConverterInstance<AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>,
AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst>>());
if (! inPlace)
zeromem (reversed, sizeof (reversed));

conv->convertSamples (reversed, inPlace ? reversed : converted, numSamples);

{
int biggestDiff = 0;
AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d1 (original);
AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d2 (reversed);

const int errorMargin = 2 * AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution()
+ AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution();

for (int i = 0; i < numSamples; ++i)
{
biggestDiff = jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32()));
++d1;
++d2;
}

unitTest.expect (biggestDiff <= errorMargin);
}
}

YUP_END_IGNORE_WARNINGS_MSVC
};

template <class F1, class E1, class FormatType>
struct Test3
{
static void test (UnitTest& unitTest, Random& r)
{
Test5<F1, E1, FormatType, AudioData::BigEndian>::test (unitTest, r);
Test5<F1, E1, FormatType, AudioData::LittleEndian>::test (unitTest, r);
}
};

template <class FormatType, class Endianness>
struct Test2
{
static void test (UnitTest& unitTest, Random& r)
{
Test3<FormatType, Endianness, AudioData::Int8>::test (unitTest, r);
Test3<FormatType, Endianness, AudioData::UInt8>::test (unitTest, r);
Test3<FormatType, Endianness, AudioData::Int16>::test (unitTest, r);
Test3<FormatType, Endianness, AudioData::Int24>::test (unitTest, r);
Test3<FormatType, Endianness, AudioData::Int32>::test (unitTest, r);
Test3<FormatType, Endianness, AudioData::Float32>::test (unitTest, r);
}
};

template <class FormatType>
struct Test1
{
static void test (UnitTest& unitTest, Random& r)
{
Test2<FormatType, AudioData::BigEndian>::test (unitTest, r);
Test2<FormatType, AudioData::LittleEndian>::test (unitTest, r);
}
};

void runTest() override
{
auto r = getRandom();
beginTest ("Round-trip conversion: Int8");
Test1<AudioData::Int8>::test (*this, r);
beginTest ("Round-trip conversion: Int16");
Test1<AudioData::Int16>::test (*this, r);
beginTest ("Round-trip conversion: Int24");
Test1<AudioData::Int24>::test (*this, r);
beginTest ("Round-trip conversion: Int32");
Test1<AudioData::Int32>::test (*this, r);
beginTest ("Round-trip conversion: Float32");
Test1<AudioData::Float32>::test (*this, r);

using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;

beginTest ("Interleaving");
{
constexpr auto numChannels = 4;
constexpr auto numSamples = 512;

AudioBuffer<float> sourceBuffer { numChannels, numSamples },
destBuffer { 1, numChannels * numSamples };

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
sourceBuffer.setSample (ch, i, r.nextFloat());

AudioData::interleaveSamples (AudioData::NonInterleavedSource<Format> { sourceBuffer.getArrayOfReadPointers(), numChannels },
AudioData::InterleavedDest<Format> { destBuffer.getWritePointer (0), numChannels },
numSamples);

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
expectEquals (destBuffer.getSample (0, ch + (i * numChannels)), sourceBuffer.getSample (ch, i));
}

beginTest ("Deinterleaving");
{
constexpr auto numChannels = 4;
constexpr auto numSamples = 512;

AudioBuffer<float> sourceBuffer { 1, numChannels * numSamples },
destBuffer { numChannels, numSamples };

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
sourceBuffer.setSample (0, ch + (i * numChannels), r.nextFloat());

AudioData::deinterleaveSamples (AudioData::InterleavedSource<Format> { sourceBuffer.getReadPointer (0), numChannels },
AudioData::NonInterleavedDest<Format> { destBuffer.getArrayOfWritePointers(), numChannels },
numSamples);

for (int ch = 0; ch < numChannels; ++ch)
for (int i = 0; i < numSamples; ++i)
expectEquals (sourceBuffer.getSample (0, ch + (i * numChannels)), destBuffer.getSample (ch, i));
}
}
};

static AudioConversionTests audioConversionUnitTests;

#endif

YUP_END_IGNORE_DEPRECATION_WARNINGS

} // namespace yup
Loading
Loading