diff --git a/tests/test_common/ma_test_common.c b/tests/test_common/ma_test_common.c index ad47e09a..d9f10181 100644 --- a/tests/test_common/ma_test_common.c +++ b/tests/test_common/ma_test_common.c @@ -1,3 +1,10 @@ +#define DR_FLAC_IMPLEMENTATION +#include "../../extras/dr_flac.h" +#define DR_MP3_IMPLEMENTATION +#include "../../extras/dr_mp3.h" +#define DR_WAV_IMPLEMENTATION +#include "../../extras/dr_wav.h" + #define MINIAUDIO_IMPLEMENTATION #include "../../miniaudio.h" @@ -34,4 +41,22 @@ ma_result ma_register_test(const char* pName, ma_test_entry_proc onEntry) g_Tests.count += 1; return MA_SUCCESS; -} \ No newline at end of file +} + +static drwav_data_format drwav_data_format_from_minaudio_format(ma_format format, ma_uint32 channels, ma_uint32 sampleRate) +{ + drwav_data_format wavFormat; + + wavFormat.container = drwav_container_riff; + wavFormat.channels = channels; + wavFormat.sampleRate = sampleRate; + wavFormat.bitsPerSample = ma_get_bytes_per_sample(format) * 8; + + if (format == ma_format_f32) { + wavFormat.format = DR_WAVE_FORMAT_IEEE_FLOAT; + } else { + wavFormat.format = DR_WAVE_FORMAT_PCM; + } + + return wavFormat; +} diff --git a/tests/test_filtering/ma_test_filtering.c b/tests/test_filtering/ma_test_filtering.c new file mode 100644 index 00000000..5c6d35dc --- /dev/null +++ b/tests/test_filtering/ma_test_filtering.c @@ -0,0 +1,52 @@ +#include "../test_common/ma_test_common.c" + +#include "ma_test_filtering_dithering.c" +#include "ma_test_filtering_lpf.c" +#include "ma_test_filtering_hpf.c" +#include "ma_test_filtering_bpf.c" + +int main(int argc, char** argv) +{ + ma_result result; + ma_bool32 hasError = MA_FALSE; + size_t iTest; + + (void)argc; + (void)argv; + + result = ma_register_test("Dithering", test_entry__dithering); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + result = ma_register_test("Low-Pass Filtering", test_entry__lpf); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + result = ma_register_test("High-Pass Filtering", test_entry__hpf); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + result = ma_register_test("Band-Pass Filtering", test_entry__bpf); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + for (iTest = 0; iTest < g_Tests.count; iTest += 1) { + printf("=== BEGIN %s ===\n", g_Tests.pTests[iTest].pName); + result = g_Tests.pTests[iTest].onEntry(argc, argv); + printf("=== END %s : %s ===\n", g_Tests.pTests[iTest].pName, (result == 0) ? "PASSED" : "FAILED"); + + if (result != 0) { + hasError = MA_TRUE; + } + } + + if (hasError) { + return -1; /* Something failed. */ + } else { + return 0; /* Everything passed. */ + } +} diff --git a/tests/test_filtering/ma_test_filtering_bpf.c b/tests/test_filtering/ma_test_filtering_bpf.c new file mode 100644 index 00000000..314cdfc1 --- /dev/null +++ b/tests/test_filtering/ma_test_filtering_bpf.c @@ -0,0 +1,81 @@ + +ma_result test_bpf__f32(const char* pInputFilePath) +{ + const char* pOutputFilePath = "output/bpf_f32.wav"; + ma_result result; + ma_decoder_config decoderConfig; + ma_decoder decoder; + drwav_data_format wavFormat; + drwav wav; + ma_bpf_config bpfConfig; + ma_bpf bpf; + + decoderConfig = ma_decoder_config_init(ma_format_f32, 0, 0); + result = ma_decoder_init_file(pInputFilePath, &decoderConfig, &decoder); + if (result != MA_SUCCESS) { + return result; + } + + bpfConfig = ma_bpf_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000); + result = ma_bpf_init(&bpfConfig, &bpf); + if (result != MA_SUCCESS) { + ma_decoder_uninit(&decoder); + return result; + } + + wavFormat = drwav_data_format_from_minaudio_format(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate); + if (!drwav_init_file_write(&wav, pOutputFilePath, &wavFormat, NULL)) { + ma_decoder_uninit(&decoder); + return MA_ERROR; + } + + for (;;) { + ma_uint8 tempIn[4096]; + ma_uint8 tempOut[4096]; + ma_uint64 tempCapIn = sizeof(tempIn) / ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels); + ma_uint64 tempCapOut = sizeof(tempOut) / ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels); + ma_uint64 framesToRead; + ma_uint64 framesJustRead; + + framesToRead = ma_min(tempCapIn, tempCapOut); + framesJustRead = ma_decoder_read_pcm_frames(&decoder, tempIn, framesToRead); + + /* Filter */ + ma_bpf_process_pcm_frames(&bpf, tempOut, tempIn, framesJustRead); + + /* Write to the WAV file. */ + drwav_write_pcm_frames(&wav, framesJustRead, tempOut); + + if (framesJustRead < framesToRead) { + break; + } + } + + drwav_uninit(&wav); + return MA_SUCCESS; +} + +int test_entry__bpf(int argc, char** argv) +{ + ma_result result; + ma_bool32 hasError = MA_FALSE; + const char* pInputFilePath; + + if (argc < 2) { + printf("No input file.\n"); + return -1; + } + + pInputFilePath = argv[1]; + + result = test_bpf__f32(pInputFilePath); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + if (hasError) { + return -1; + } else { + return 0; + } +} diff --git a/tests/test_filtering/ma_test_filtering_dithering.c b/tests/test_filtering/ma_test_filtering_dithering.c new file mode 100644 index 00000000..0790bf12 --- /dev/null +++ b/tests/test_filtering/ma_test_filtering_dithering.c @@ -0,0 +1,72 @@ + +ma_result test_dithering__u8(const char* pInputFilePath) +{ + const char* pOutputFilePath = "output/dithering_u8.wav"; + ma_result result; + ma_decoder_config decoderConfig; + ma_decoder decoder; + drwav_data_format wavFormat; + drwav wav; + + decoderConfig = ma_decoder_config_init(ma_format_f32, 0, 0); + result = ma_decoder_init_file(pInputFilePath, &decoderConfig, &decoder); + if (result != MA_SUCCESS) { + return result; + } + + wavFormat = drwav_data_format_from_minaudio_format(ma_format_u8, decoder.outputChannels, decoder.outputSampleRate); + if (!drwav_init_file_write(&wav, pOutputFilePath, &wavFormat, NULL)) { + ma_decoder_uninit(&decoder); + return MA_ERROR; + } + + for (;;) { + ma_uint8 tempIn[4096]; + ma_uint8 tempOut[4096]; + ma_uint64 tempCapIn = sizeof(tempIn) / ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels); + ma_uint64 tempCapOut = sizeof(tempOut) / ma_get_bytes_per_frame(ma_format_u8, decoder.outputChannels); + ma_uint64 framesToRead; + ma_uint64 framesJustRead; + + framesToRead = ma_min(tempCapIn, tempCapOut); + framesJustRead = ma_decoder_read_pcm_frames(&decoder, tempIn, framesToRead); + + /* Convert, with dithering. */ + ma_convert_pcm_frames_format(tempOut, ma_format_u8, tempIn, decoder.outputFormat, framesJustRead, decoder.outputChannels, ma_dither_mode_triangle); + + /* Write to the WAV file. */ + drwav_write_pcm_frames(&wav, framesJustRead, tempOut); + + if (framesJustRead < framesToRead) { + break; + } + } + + drwav_uninit(&wav); + return MA_SUCCESS; +} + +int test_entry__dithering(int argc, char** argv) +{ + ma_result result; + ma_bool32 hasError = MA_FALSE; + const char* pInputFilePath; + + if (argc < 2) { + printf("No input file.\n"); + return -1; + } + + pInputFilePath = argv[1]; + + result = test_dithering__u8(pInputFilePath); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + if (hasError) { + return -1; + } else { + return 0; + } +} diff --git a/tests/test_filtering/ma_test_filtering_hpf.c b/tests/test_filtering/ma_test_filtering_hpf.c new file mode 100644 index 00000000..71a7e6c7 --- /dev/null +++ b/tests/test_filtering/ma_test_filtering_hpf.c @@ -0,0 +1,81 @@ + +ma_result test_hpf__f32(const char* pInputFilePath) +{ + const char* pOutputFilePath = "output/hpf_f32.wav"; + ma_result result; + ma_decoder_config decoderConfig; + ma_decoder decoder; + drwav_data_format wavFormat; + drwav wav; + ma_hpf_config hpfConfig; + ma_hpf hpf; + + decoderConfig = ma_decoder_config_init(ma_format_f32, 0, 0); + result = ma_decoder_init_file(pInputFilePath, &decoderConfig, &decoder); + if (result != MA_SUCCESS) { + return result; + } + + hpfConfig = ma_hpf_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000); + result = ma_hpf_init(&hpfConfig, &hpf); + if (result != MA_SUCCESS) { + ma_decoder_uninit(&decoder); + return result; + } + + wavFormat = drwav_data_format_from_minaudio_format(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate); + if (!drwav_init_file_write(&wav, pOutputFilePath, &wavFormat, NULL)) { + ma_decoder_uninit(&decoder); + return MA_ERROR; + } + + for (;;) { + ma_uint8 tempIn[4096]; + ma_uint8 tempOut[4096]; + ma_uint64 tempCapIn = sizeof(tempIn) / ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels); + ma_uint64 tempCapOut = sizeof(tempOut) / ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels); + ma_uint64 framesToRead; + ma_uint64 framesJustRead; + + framesToRead = ma_min(tempCapIn, tempCapOut); + framesJustRead = ma_decoder_read_pcm_frames(&decoder, tempIn, framesToRead); + + /* Filter */ + ma_hpf_process_pcm_frames(&hpf, tempOut, tempIn, framesJustRead); + + /* Write to the WAV file. */ + drwav_write_pcm_frames(&wav, framesJustRead, tempOut); + + if (framesJustRead < framesToRead) { + break; + } + } + + drwav_uninit(&wav); + return MA_SUCCESS; +} + +int test_entry__hpf(int argc, char** argv) +{ + ma_result result; + ma_bool32 hasError = MA_FALSE; + const char* pInputFilePath; + + if (argc < 2) { + printf("No input file.\n"); + return -1; + } + + pInputFilePath = argv[1]; + + result = test_hpf__f32(pInputFilePath); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + if (hasError) { + return -1; + } else { + return 0; + } +} diff --git a/tests/test_filtering/ma_test_filtering_lpf.c b/tests/test_filtering/ma_test_filtering_lpf.c new file mode 100644 index 00000000..24fc45fb --- /dev/null +++ b/tests/test_filtering/ma_test_filtering_lpf.c @@ -0,0 +1,81 @@ + +ma_result test_lpf__f32(const char* pInputFilePath) +{ + const char* pOutputFilePath = "output/lpf_f32.wav"; + ma_result result; + ma_decoder_config decoderConfig; + ma_decoder decoder; + drwav_data_format wavFormat; + drwav wav; + ma_lpf_config lpfConfig; + ma_lpf lpf; + + decoderConfig = ma_decoder_config_init(ma_format_f32, 0, 0); + result = ma_decoder_init_file(pInputFilePath, &decoderConfig, &decoder); + if (result != MA_SUCCESS) { + return result; + } + + lpfConfig = ma_lpf_config_init(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate, 2000); + result = ma_lpf_init(&lpfConfig, &lpf); + if (result != MA_SUCCESS) { + ma_decoder_uninit(&decoder); + return result; + } + + wavFormat = drwav_data_format_from_minaudio_format(decoder.outputFormat, decoder.outputChannels, decoder.outputSampleRate); + if (!drwav_init_file_write(&wav, pOutputFilePath, &wavFormat, NULL)) { + ma_decoder_uninit(&decoder); + return MA_ERROR; + } + + for (;;) { + ma_uint8 tempIn[4096]; + ma_uint8 tempOut[4096]; + ma_uint64 tempCapIn = sizeof(tempIn) / ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels); + ma_uint64 tempCapOut = sizeof(tempOut) / ma_get_bytes_per_frame(decoder.outputFormat, decoder.outputChannels); + ma_uint64 framesToRead; + ma_uint64 framesJustRead; + + framesToRead = ma_min(tempCapIn, tempCapOut); + framesJustRead = ma_decoder_read_pcm_frames(&decoder, tempIn, framesToRead); + + /* Filter */ + ma_lpf_process_pcm_frames(&lpf, tempOut, tempIn, framesJustRead); + + /* Write to the WAV file. */ + drwav_write_pcm_frames(&wav, framesJustRead, tempOut); + + if (framesJustRead < framesToRead) { + break; + } + } + + drwav_uninit(&wav); + return MA_SUCCESS; +} + +int test_entry__lpf(int argc, char** argv) +{ + ma_result result; + ma_bool32 hasError = MA_FALSE; + const char* pInputFilePath; + + if (argc < 2) { + printf("No input file.\n"); + return -1; + } + + pInputFilePath = argv[1]; + + result = test_lpf__f32(pInputFilePath); + if (result != MA_SUCCESS) { + hasError = MA_TRUE; + } + + if (hasError) { + return -1; + } else { + return 0; + } +} diff --git a/tests/test_generation/ma_test_generation.c b/tests/test_generation/ma_test_generation.c index f2b1a416..78babc99 100644 --- a/tests/test_generation/ma_test_generation.c +++ b/tests/test_generation/ma_test_generation.c @@ -1,26 +1,5 @@ #include "../test_common/ma_test_common.c" -#define DR_WAV_IMPLEMENTATION -#include "../../extras/dr_wav.h" - -static drwav_data_format drwav_data_format_from_minaudio_format(ma_format format, ma_uint32 channels, ma_uint32 sampleRate) -{ - drwav_data_format wavFormat; - - wavFormat.container = drwav_container_riff; - wavFormat.channels = channels; - wavFormat.sampleRate = sampleRate; - wavFormat.bitsPerSample = ma_get_bytes_per_sample(format) * 8; - - if (format == ma_format_f32) { - wavFormat.format = DR_WAVE_FORMAT_IEEE_FLOAT; - } else { - wavFormat.format = DR_WAVE_FORMAT_PCM; - } - - return wavFormat; -} - #include "ma_test_generation_noise.c" #include "ma_test_generation_waveform.c"