| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
-
- #include "../testTools.h"
- #include "../../DFPSR/api/soundAPI.h"
- #include "../../DFPSR/api/fileAPI.h"
- #include "../../DFPSR/api/randomAPI.h"
- #include <math.h>
- void compareSoundBuffers(const SoundBuffer &given, const SoundBuffer &expected, float tolerance) {
- ASSERT_EQUAL(sound_getSamplesPerChannel(given), sound_getSamplesPerChannel(expected));
- ASSERT_EQUAL(sound_getChannelCount(given), sound_getChannelCount(expected));
- ASSERT_EQUAL(sound_getSampleRate(given), sound_getSampleRate(expected));
- SafePointer<float> givenSamples = sound_getSafePointer(given);
- SafePointer<float> expectedSamples = sound_getSafePointer(expected);
- float maxGiven = 0.0f;
- float minGiven = 0.0f;
- float maxExpected = 0.0f;
- float minExpected = 0.0f;
- float maxOffset = -1000000.0f;
- float minOffset = 1000000.0f;
- for (int t = 0; t < sound_getSamplesPerChannel(given); t++) {
- float givenValue = givenSamples[t];
- float expectedValue = expectedSamples[t];
- float offset = givenSamples[t] - expectedSamples[t];
- if (offset > maxOffset) maxOffset = offset;
- if (offset < minOffset) minOffset = offset;
- if (givenValue > maxGiven) maxGiven = givenValue;
- if (givenValue < minGiven) minGiven = givenValue;
- if (expectedValue > maxExpected) maxExpected = expectedValue;
- if (expectedValue < minExpected) minExpected = expectedValue;
- }
- ASSERT_LESSER(maxOffset, tolerance);
- ASSERT_GREATER(minOffset, -tolerance);
- }
- static const double pi = 3.1415926535897932384626433832795;
- static const double cyclesToRadians = pi * 2.0;
- // TODO: Implement basic sound generation functions and move them to the sound API.
- // Both in-place functions and allocating new buffers as needed to expand.
- // Generation functions, multiplying masks, fade masks, echo effects, frequency filters, equalization, resampling...
- void sound_setNoise(SoundBuffer &sound, float minimum = -1.0f, float maximum = 1.0f) {
- RandomGenerator generator = random_createGenerator(917542);
- SafePointer<float> target = sound_getSafePointer(sound);
- intptr_t totalSamples = sound_getSamplesPerChannel(sound) * sound_getChannelCount(sound);
- for (intptr_t s = 0; s < totalSamples; s++) {
- target[s] = random_generate_range(generator, minimum, maximum);
- }
- }
- START_TEST(Sound)
- String folderPath = file_combinePaths(U".", U"resources", U"sounds");
- // Check that we have a valid folder path to the resources.
- ASSERT_EQUAL(file_getEntryType(folderPath), EntryType::Folder);
- { // Single channel wave files.
- // Generate the reference sine wave.
- static const int sampleRate = 44100;
- static const int samplesPerChannel = 441;
- static const int frequency = 100;
- SoundBuffer referenceSine = sound_create(samplesPerChannel, 1, sampleRate);
- SafePointer<float> target = sound_getSafePointer(referenceSine);
- static const double radiansPerElement = cyclesToRadians * (double)frequency / (double)sampleRate;
- for (int t = 0; t < samplesPerChannel; t++) {
- target[t] = (float)sin(double(t) * radiansPerElement);
- }
- // Load wave files that were exported from a 10 millisecond sine wave in the Audacity sound editor for reference.
- // Because Audacity truncates towards zero instead of rounding to nearest, the worst case accuracy has twice the error.
- SoundBuffer sineU8 = sound_load(file_combinePaths(folderPath, U"SineU8.wav"));
- ASSERT(sound_exists(sineU8));
- compareSoundBuffers(sineU8, referenceSine, 0.02f);
- SoundBuffer sineI16 = sound_load(file_combinePaths(folderPath, U"SineI16.wav"));
- ASSERT(sound_exists(sineI16));
- compareSoundBuffers(sineI16, referenceSine, 0.0002f);
- SoundBuffer sineI24 = sound_load(file_combinePaths(folderPath, U"SineI24.wav"));
- ASSERT(sound_exists(sineI24));
- compareSoundBuffers(sineI24, referenceSine, 0.000002f);
- SoundBuffer sineI32 = sound_load(file_combinePaths(folderPath, U"SineI32.wav"));
- ASSERT(sound_exists(sineI32));
- compareSoundBuffers(sineI32, referenceSine, 0.00000001f);
- SoundBuffer sineF32 = sound_load(file_combinePaths(folderPath, U"SineF32.wav"));
- ASSERT(sound_exists(sineF32));
- compareSoundBuffers(sineF32, referenceSine, 0.00000001f);
- SoundBuffer sineF64 = sound_load(file_combinePaths(folderPath, U"SineF64.wav"));
- ASSERT(sound_exists(sineF64));
- compareSoundBuffers(sineF64, referenceSine, 0.00000001f);
- //sound_save_RiffWave(file_combinePaths(folderPath, U"SineI16_2.wav"), sineI16, RiffWaveFormat::RawI16);
- //sound_save_RiffWave(file_combinePaths(folderPath, U"SineI24_2.wav"), sineI24, RiffWaveFormat::RawI24);
- //sound_save_RiffWave(file_combinePaths(folderPath, U"SineI32_2.wav"), sineI32, RiffWaveFormat::RawI24);
- }
- { // Brute-force encode and decode test with random noise.
- RandomGenerator generator = random_createGenerator(12345);
- for (uint32_t channelCount = 1; channelCount <= 16; channelCount++) {
- SoundBuffer original = sound_create(1024, channelCount, 44100);
- sound_setNoise(original);
- Buffer encodedU8_truncate = sound_encode_RiffWave(original, RiffWaveFormat::RawU8 , RoundingMethod::Truncate);
- Buffer encodedU8_nearest = sound_encode_RiffWave(original, RiffWaveFormat::RawU8 , RoundingMethod::Nearest);
- Buffer encodedI16_truncate = sound_encode_RiffWave(original, RiffWaveFormat::RawI16, RoundingMethod::Truncate);
- Buffer encodedI16_nearest = sound_encode_RiffWave(original, RiffWaveFormat::RawI16, RoundingMethod::Nearest);
- Buffer encodedI24_nearest = sound_encode_RiffWave(original, RiffWaveFormat::RawI24, RoundingMethod::Nearest);
- Buffer encodedI32_nearest = sound_encode_RiffWave(original, RiffWaveFormat::RawI32, RoundingMethod::Nearest);
- SoundBuffer decodedU8_truncate = sound_decode_RiffWave(encodedU8_truncate);
- SoundBuffer decodedU8_nearest = sound_decode_RiffWave(encodedU8_nearest );
- SoundBuffer decodedI16_truncate = sound_decode_RiffWave(encodedI16_truncate);
- SoundBuffer decodedI16_nearest = sound_decode_RiffWave(encodedI16_nearest);
- SoundBuffer decodedI24_nearest = sound_decode_RiffWave(encodedI24_nearest);
- SoundBuffer decodedI32_nearest = sound_decode_RiffWave(encodedI32_nearest);
- compareSoundBuffers(decodedU8_truncate , original, 2.02 / 256.0);
- compareSoundBuffers(decodedU8_nearest , original, 1.01 / 256.0);
- compareSoundBuffers(decodedI16_truncate, original, 2.02 / 65536.0);
- compareSoundBuffers(decodedI16_nearest , original, 1.01 / 65536.0);
- compareSoundBuffers(decodedI24_nearest , original, 1.01 / 8388608.0);
- compareSoundBuffers(decodedI32_nearest , original, 1.01 / 2147483648.0);
- if (failed) break;
- }
- }
- // TODO: Test saving sounds to files.
- END_TEST
|