Files
miniaudio/research/tests/ma_resampler_test_1.c
T
David Reid a9e7d6d8c9 Add some documentation for the new resampler.
This commit also renames ma_resampler_process() to
ma_resampler_process_pcm_frames().
2020-01-19 21:23:57 +10:00

317 lines
9.2 KiB
C

#define MINIAUDIO_SPEEX_RESAMPLER_IMPLEMENTATION
#include "../../extras/speex_resampler/ma_speex_resampler.h"
#define MA_DEBUG_OUTPUT
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../ma_resampler.h"
int init_resampler(ma_uint32 rateIn, ma_uint32 rateOut, ma_resample_algorithm algorithm, ma_resampler* pResampler)
{
ma_result result;
ma_resampler_config config;
config = ma_resampler_config_init(ma_format_s16, 1, rateIn, rateOut, algorithm);
result = ma_resampler_init(&config, pResampler);
if (result != MA_SUCCESS) {
return (int)result;
}
return 0;
}
int do_count_query_test__required_input__fixed_interval(ma_resampler* pResampler, ma_uint64 frameCountPerIteration)
{
int result = 0;
ma_int16 input[4096];
ma_int16 i;
MA_ASSERT(frameCountPerIteration < ma_countof(input));
/* Fill the input buffer with sequential numbers so we can get an idea on the state of things. Useful for inspecting the linear backend in particular. */
for (i = 0; i < ma_countof(input); i += 1) {
input[i] = i;
}
for (i = 0; i < ma_countof(input); i += (ma_int16)frameCountPerIteration) {
ma_int16 output[4096];
ma_uint64 outputFrameCount;
ma_uint64 inputFrameCount;
ma_uint64 requiredInputFrameCount;
/* We retrieve the required number of input frames for the specified number of output frames, and then compare with what we actually get when reading. */
requiredInputFrameCount = ma_resampler_get_required_input_frame_count(pResampler, frameCountPerIteration);
outputFrameCount = frameCountPerIteration;
inputFrameCount = ma_countof(input);
result = ma_resampler_process_pcm_frames(pResampler, input, &inputFrameCount, output, &outputFrameCount);
if (result != MA_SUCCESS) {
printf("Failed to process frames.");
return result;
}
if (inputFrameCount != requiredInputFrameCount) {
printf("ERROR: Predicted vs actual input count mismatch: predicted=%d, actual=%d\n", (int)requiredInputFrameCount, (int)inputFrameCount);
result = -1;
}
}
if (result != 0) {
printf("FAILED\n");
} else {
printf("PASSED\n");
}
return result;
}
int do_count_query_test__required_input__by_algorithm_and_rate__fixed_interval(ma_resample_algorithm algorithm, ma_uint32 rateIn, ma_uint32 rateOut, ma_uint64 frameCountPerIteration)
{
int result;
ma_resampler resampler;
result = init_resampler(rateIn, rateOut, algorithm, &resampler);
if (result != 0) {
return 0;
}
result = do_count_query_test__required_input__fixed_interval(&resampler, frameCountPerIteration);
ma_resampler_uninit(&resampler);
return result;
}
int do_count_query_test__required_input__by_algorithm__fixed_interval(ma_resample_algorithm algorithm, ma_uint64 frameCountPerIteration)
{
int result;
result = do_count_query_test__required_input__by_algorithm_and_rate__fixed_interval(algorithm, 44100, 48000, frameCountPerIteration);
if (result != 0) {
return result;
}
result = do_count_query_test__required_input__by_algorithm_and_rate__fixed_interval(algorithm, 48000, 44100, frameCountPerIteration);
if (result != 0) {
return result;
}
result = do_count_query_test__required_input__by_algorithm_and_rate__fixed_interval(algorithm, 44100, 192000, frameCountPerIteration);
if (result != 0) {
return result;
}
result = do_count_query_test__required_input__by_algorithm_and_rate__fixed_interval(algorithm, 192000, 44100, frameCountPerIteration);
if (result != 0) {
return result;
}
return result;
}
int do_count_query_tests__required_input__by_algorithm(ma_resample_algorithm algorithm)
{
int result;
result = do_count_query_test__required_input__by_algorithm__fixed_interval(algorithm, 1);
if (result != 0) {
return result;
}
result = do_count_query_test__required_input__by_algorithm__fixed_interval(algorithm, 16);
if (result != 0) {
return result;
}
result = do_count_query_test__required_input__by_algorithm__fixed_interval(algorithm, 127);
if (result != 0) {
return result;
}
return 0;
}
int do_count_query_tests__required_input()
{
int result;
printf("Linear\n");
result = do_count_query_tests__required_input__by_algorithm(ma_resample_algorithm_linear);
if (result != 0) {
return result;
}
printf("Speex\n");
result = do_count_query_tests__required_input__by_algorithm(ma_resample_algorithm_speex);
if (result != 0) {
return result;
}
return 0;
}
int do_count_query_test__expected_output__fixed_interval(ma_resampler* pResampler, ma_uint64 frameCountPerIteration)
{
int result = 0;
ma_int16 input[4096];
ma_int16 i;
MA_ASSERT(frameCountPerIteration < ma_countof(input));
/* Fill the input buffer with sequential numbers so we can get an idea on the state of things. Useful for inspecting the linear backend in particular. */
for (i = 0; i < ma_countof(input); i += 1) {
input[i] = i;
}
for (i = 0; i < ma_countof(input); i += (ma_int16)frameCountPerIteration) {
ma_int16 output[4096];
ma_uint64 outputFrameCount;
ma_uint64 inputFrameCount;
ma_uint64 expectedOutputFrameCount;
/* We retrieve the required number of input frames for the specified number of output frames, and then compare with what we actually get when reading. */
expectedOutputFrameCount = ma_resampler_get_expected_output_frame_count(pResampler, frameCountPerIteration);
outputFrameCount = ma_countof(output);
inputFrameCount = frameCountPerIteration;
result = ma_resampler_process_pcm_frames(pResampler, input, &inputFrameCount, output, &outputFrameCount);
if (result != MA_SUCCESS) {
printf("Failed to process frames.");
return result;
}
if (outputFrameCount != expectedOutputFrameCount) {
printf("ERROR: Predicted vs actual output count mismatch: predicted=%d, actual=%d\n", (int)expectedOutputFrameCount, (int)outputFrameCount);
result = -1;
}
}
if (result != 0) {
printf("FAILED\n");
} else {
printf("PASSED\n");
}
return result;
}
int do_count_query_test__expected_output__by_algorithm_and_rate__fixed_interval(ma_resample_algorithm algorithm, ma_uint32 rateIn, ma_uint32 rateOut, ma_uint64 frameCountPerIteration)
{
int result;
ma_resampler resampler;
result = init_resampler(rateIn, rateOut, algorithm, &resampler);
if (result != 0) {
return 0;
}
result = do_count_query_test__expected_output__fixed_interval(&resampler, frameCountPerIteration);
ma_resampler_uninit(&resampler);
return result;
}
int do_count_query_test__expected_output__by_algorithm__fixed_interval(ma_resample_algorithm algorithm, ma_uint64 frameCountPerIteration)
{
int result;
result = do_count_query_test__expected_output__by_algorithm_and_rate__fixed_interval(algorithm, 44100, 48000, frameCountPerIteration);
if (result != 0) {
return result;
}
result = do_count_query_test__expected_output__by_algorithm_and_rate__fixed_interval(algorithm, 48000, 44100, frameCountPerIteration);
if (result != 0) {
return result;
}
result = do_count_query_test__expected_output__by_algorithm_and_rate__fixed_interval(algorithm, 44100, 192000, frameCountPerIteration);
if (result != 0) {
return result;
}
result = do_count_query_test__expected_output__by_algorithm_and_rate__fixed_interval(algorithm, 192000, 44100, frameCountPerIteration);
if (result != 0) {
return result;
}
return result;
}
int do_count_query_tests__expected_output__by_algorithm(ma_resample_algorithm algorithm)
{
int result;
result = do_count_query_test__expected_output__by_algorithm__fixed_interval(algorithm, 1);
if (result != 0) {
return result;
}
result = do_count_query_test__expected_output__by_algorithm__fixed_interval(algorithm, 16);
if (result != 0) {
return result;
}
result = do_count_query_test__expected_output__by_algorithm__fixed_interval(algorithm, 127);
if (result != 0) {
return result;
}
return 0;
}
int do_count_query_tests__expected_output()
{
int result;
printf("Linear\n");
result = do_count_query_tests__expected_output__by_algorithm(ma_resample_algorithm_linear);
if (result != 0) {
return result;
}
printf("Speex\n");
result = do_count_query_tests__expected_output__by_algorithm(ma_resample_algorithm_speex);
if (result != 0) {
return result;
}
return 0;
}
int do_count_query_tests()
{
int result;
result = do_count_query_tests__expected_output();
if (result != 0) {
return result;
}
result = do_count_query_tests__required_input();
if (result != 0) {
return result;
}
return 0;
}
int main(int argc, char** argv)
{
int result;
(void)argc;
(void)argv;
result = do_count_query_tests();
if (result != 0) {
return result;
}
return 0;
}