#define MA_NO_THREADING #define MA_NO_DEVICE_IO #include "../common/common.c" ma_result init_data_converter(ma_uint32 rateIn, ma_uint32 rateOut, ma_resample_algorithm algorithm, ma_data_converter* pDataConverter) { ma_result result; ma_data_converter_config config; config = ma_data_converter_config_init(ma_format_s16, ma_format_s16, 1, 1, rateIn, rateOut); config.resampling.algorithm = algorithm; result = ma_data_converter_init(&config, NULL, pDataConverter); if (result != MA_SUCCESS) { return result; } return MA_SUCCESS; } #if 0 ma_result test_data_converter__passthrough() { /* Notes: - The isPassthrough flag should be set to true. Both the positive and negative cases need to be tested. - ma_data_converter_set_rate() should fail with MA_INVALID_OPERATION. - The output should be identical to the input. */ printf("Passthrough\n"); return MA_SUCCESS; } #endif ma_result test_data_converter__resampling_expected_output_fixed_interval(ma_data_converter* pDataConverter, ma_uint64 frameCountPerIteration) { ma_result result = MA_SUCCESS; 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_int16)ma_countof(input); i += 1) { input[i] = i; } for (i = 0; i < (ma_int16)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. */ ma_data_converter_get_expected_output_frame_count(pDataConverter, frameCountPerIteration, &expectedOutputFrameCount); outputFrameCount = ma_countof(output); inputFrameCount = frameCountPerIteration; result = ma_data_converter_process_pcm_frames(pDataConverter, input, &inputFrameCount, output, &outputFrameCount); if (result != MA_SUCCESS) { printf("Failed to process frames."); break; } if (outputFrameCount != expectedOutputFrameCount) { printf("ERROR: Predicted vs actual output count mismatch: predicted=%d, actual=%d\n", (int)expectedOutputFrameCount, (int)outputFrameCount); result = MA_ERROR; } } if (result != MA_SUCCESS) { printf("FAILED\n"); } else { printf("PASSED\n"); } return result; } ma_result test_data_converter__resampling_expected_output_by_algorithm_and_rate_fixed_interval(ma_resample_algorithm algorithm, ma_uint32 rateIn, ma_uint32 rateOut, ma_uint64 frameCountPerIteration) { ma_result result; ma_bool32 hasError = MA_FALSE; ma_data_converter converter; result = init_data_converter(rateIn, rateOut, algorithm, &converter); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_expected_output_fixed_interval(&converter, frameCountPerIteration); ma_data_converter_uninit(&converter, NULL); if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling_expected_output_by_algorithm_fixed_interval(ma_resample_algorithm algorithm, ma_uint64 frameCountPerIteration) { ma_result result; ma_bool32 hasError = MA_FALSE; result = test_data_converter__resampling_expected_output_by_algorithm_and_rate_fixed_interval(algorithm, 44100, 48000, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_expected_output_by_algorithm_and_rate_fixed_interval(algorithm, 48000, 44100, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_expected_output_by_algorithm_and_rate_fixed_interval(algorithm, 44100, 192000, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_expected_output_by_algorithm_and_rate_fixed_interval(algorithm, 192000, 44100, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling_expected_output_by_algorithm(ma_resample_algorithm algorithm) { ma_result result; ma_bool32 hasError = MA_FALSE; result = test_data_converter__resampling_expected_output_by_algorithm_fixed_interval(algorithm, 1); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_expected_output_by_algorithm_fixed_interval(algorithm, 16); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_expected_output_by_algorithm_fixed_interval(algorithm, 127); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling_expected_output(void) { ma_result result; ma_bool32 hasError = MA_FALSE; printf("Linear\n"); result = test_data_converter__resampling_expected_output_by_algorithm(ma_resample_algorithm_linear); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling_required_input_fixed_interval(ma_data_converter* pDataConverter, ma_uint64 frameCountPerIteration) { ma_result result = MA_SUCCESS; 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_int16)ma_countof(input); i += 1) { input[i] = i; } for (i = 0; i < (ma_int16)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. */ ma_data_converter_get_required_input_frame_count(pDataConverter, frameCountPerIteration, &requiredInputFrameCount); outputFrameCount = frameCountPerIteration; inputFrameCount = ma_countof(input); result = ma_data_converter_process_pcm_frames(pDataConverter, input, &inputFrameCount, output, &outputFrameCount); if (result != MA_SUCCESS) { printf("Failed to process frames."); break; } if (inputFrameCount != requiredInputFrameCount) { printf("ERROR: Predicted vs actual input count mismatch: predicted=%d, actual=%d\n", (int)requiredInputFrameCount, (int)inputFrameCount); result = MA_ERROR; } } if (result != MA_SUCCESS) { printf("FAILED\n"); } else { printf("PASSED\n"); } return result; } ma_result test_data_converter__resampling_required_input_by_algorithm_and_rate_fixed_interval(ma_resample_algorithm algorithm, ma_uint32 rateIn, ma_uint32 rateOut, ma_uint64 frameCountPerIteration) { ma_result result; ma_bool32 hasError = MA_FALSE; ma_data_converter converter; result = init_data_converter(rateIn, rateOut, algorithm, &converter); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_required_input_fixed_interval(&converter, frameCountPerIteration); ma_data_converter_uninit(&converter, NULL); if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling_required_input_by_algorithm_fixed_interval(ma_resample_algorithm algorithm, ma_uint64 frameCountPerIteration) { ma_result result; ma_bool32 hasError = MA_FALSE; result = test_data_converter__resampling_required_input_by_algorithm_and_rate_fixed_interval(algorithm, 44100, 48000, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_required_input_by_algorithm_and_rate_fixed_interval(algorithm, 48000, 44100, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_required_input_by_algorithm_and_rate_fixed_interval(algorithm, 44100, 192000, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_required_input_by_algorithm_and_rate_fixed_interval(algorithm, 192000, 44100, frameCountPerIteration); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling_required_input_by_algorithm(ma_resample_algorithm algorithm) { ma_result result; ma_bool32 hasError = MA_FALSE; result = test_data_converter__resampling_required_input_by_algorithm_fixed_interval(algorithm, 1); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_required_input_by_algorithm_fixed_interval(algorithm, 16); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_required_input_by_algorithm_fixed_interval(algorithm, 127); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling_required_input(void) { ma_result result; ma_bool32 hasError = MA_FALSE; printf("Linear\n"); result = test_data_converter__resampling_required_input_by_algorithm(ma_resample_algorithm_linear); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } ma_result test_data_converter__resampling(void) { ma_result result; ma_bool32 hasError = MA_FALSE; result = test_data_converter__resampling_expected_output(); if (result != MA_SUCCESS) { hasError = MA_TRUE; } result = test_data_converter__resampling_required_input(); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return MA_ERROR; } else { return MA_SUCCESS; } } int test_entry__data_converter(int argc, char** argv) { ma_result result; ma_bool32 hasError = MA_FALSE; (void)argc; (void)argv; #if 0 result = test_data_converter__passthrough(); if (result != MA_SUCCESS) { hasError = MA_TRUE; } #endif result = test_data_converter__resampling(); if (result != MA_SUCCESS) { hasError = MA_TRUE; } if (hasError) { return -1; } else { return 0; } } int main(int argc, char** argv) { ma_register_test("Data Conversion", test_entry__data_converter); return ma_run_tests(argc, argv); }