Commit 5974dd63 authored by David Reid's avatar David Reid

Remove old research code.

This code has now been integrated into miniaudio.h.
parent bbe7ff9e
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#define DR_FLAC_IMPLEMENTATION
#include "../../extras/dr_flac.h" /* Enables FLAC decoding. */
#define DR_MP3_IMPLEMENTATION
#include "../../extras/dr_mp3.h" /* Enables MP3 decoding. */
#define DR_WAV_IMPLEMENTATION
#include "../../extras/dr_wav.h" /* Enables WAV decoding. */
#define MA_DEBUG_OUTPUT
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../ma_lpf.h"
ma_lpf g_lpf;
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
{
ma_uint32 framesProcessed = 0;
ma_decoder* pDecoder = (ma_decoder*)pDevice->pUserData;
if (pDecoder == NULL) {
return;
}
/* We need to read into a temporary buffer and then run it through the low pass filter. */
while (framesProcessed < frameCount) {
float tempBuffer[4096];
ma_uint32 framesToProcessThisIteration;
framesToProcessThisIteration = frameCount - framesProcessed;
if (framesToProcessThisIteration > ma_countof(tempBuffer)/pDecoder->internalChannels) {
framesToProcessThisIteration = ma_countof(tempBuffer)/pDecoder->internalChannels;
}
#if 0
ma_decoder_read_pcm_frames(pDecoder, ma_offset_ptr(pOutput, framesProcessed * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels)), framesToProcessThisIteration);
#else
ma_decoder_read_pcm_frames(pDecoder, tempBuffer, framesToProcessThisIteration);
/* Out the results from the low pass filter straight into our output buffer. */
ma_lpf_process(&g_lpf, ma_offset_ptr(pOutput, framesProcessed * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels)), tempBuffer, framesToProcessThisIteration);
#endif
framesProcessed += framesToProcessThisIteration;
}
(void)pInput;
}
int main(int argc, char** argv)
{
ma_result result;
ma_decoder_config decoderConfig;
ma_decoder decoder;
ma_lpf_config lpfConfig;
ma_device_config deviceConfig;
ma_device device;
if (argc < 2) {
printf("No input file.\n");
return -1;
}
decoderConfig = ma_decoder_config_init(ma_format_f32, 0, 0);
result = ma_decoder_init_file(argv[1], &decoderConfig, &decoder);
if (result != MA_SUCCESS) {
return -2;
}
lpfConfig.format = decoderConfig.format;
lpfConfig.channels = decoder.internalChannels;
lpfConfig.sampleRate = decoder.internalSampleRate;
lpfConfig.cutoffFrequency = lpfConfig.sampleRate / 4;
result = ma_lpf_init(&lpfConfig, &g_lpf);
if (result != MA_SUCCESS) {
return -100;
}
deviceConfig = ma_device_config_init(ma_device_type_playback);
deviceConfig.playback.format = decoder.outputFormat;
deviceConfig.playback.channels = decoder.outputChannels;
deviceConfig.sampleRate = decoder.outputSampleRate;
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = &decoder;
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
printf("Failed to open playback device.\n");
ma_decoder_uninit(&decoder);
return -3;
}
if (ma_device_start(&device) != MA_SUCCESS) {
printf("Failed to start playback device.\n");
ma_device_uninit(&device);
ma_decoder_uninit(&decoder);
return -4;
}
printf("Press Enter to quit...");
getchar();
ma_device_uninit(&device);
ma_decoder_uninit(&decoder);
return 0;
}
#define DR_FLAC_IMPLEMENTATION
#include "../../extras/dr_flac.h" /* Enables FLAC decoding. */
#define DR_MP3_IMPLEMENTATION
#include "../../extras/dr_mp3.h" /* Enables MP3 decoding. */
#define DR_WAV_IMPLEMENTATION
#include "../../extras/dr_wav.h" /* Enables WAV decoding. */
#define MA_DEBUG_OUTPUT
#define MINIAUDIO_IMPLEMENTATION
#include "../../miniaudio.h"
#include "../ma_resampler.h"
#define USE_NEW_RESAMPLER 1
ma_uint64 g_outputFrameCount;
void* g_pRunningFrameData;
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
{
ma_uint32 framesToCopy;
framesToCopy = frameCount;
if (framesToCopy > (ma_uint32)g_outputFrameCount) {
framesToCopy = (ma_uint32)g_outputFrameCount;
}
MA_COPY_MEMORY(pOutput, g_pRunningFrameData, framesToCopy * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels));
g_pRunningFrameData = ma_offset_ptr(g_pRunningFrameData, framesToCopy * ma_get_bytes_per_frame(pDevice->playback.format, pDevice->playback.channels));
g_outputFrameCount -= framesToCopy;
(void)pInput;
}
int main(int argc, char** argv)
{
ma_result result;
ma_decoder_config decoderConfig;
ma_uint64 inputFrameCount;
void* pInputFrameData;
ma_uint64 outputFrameCount = 0;
void* pOutputFrameData = NULL;
ma_device_config deviceConfig;
ma_device device;
ma_backend backend;
/* This example just resamples the input file to an exclusive device's native sample rate. */
if (argc < 2) {
printf("No input file.\n");
return -1;
}
decoderConfig = ma_decoder_config_init(ma_format_f32, 1, 0);
result = ma_decode_file(argv[1], &decoderConfig, &inputFrameCount, &pInputFrameData);
if (result != MA_SUCCESS) {
return (int)result;
}
backend = ma_backend_wasapi;
deviceConfig = ma_device_config_init(ma_device_type_playback);
#if USE_NEW_RESAMPLER
deviceConfig.playback.shareMode = ma_share_mode_exclusive; /* <-- We need to use exclusive mode to ensure there's no resampling going on by the OS. */
deviceConfig.sampleRate = 0; /* <-- Always use the device's native sample rate. */
#else
deviceConfig.playback.shareMode = ma_share_mode_shared; /* <-- We need to use exclusive mode to ensure there's no resampling going on by the OS. */
deviceConfig.sampleRate = decoderConfig.sampleRate;
#endif
deviceConfig.playback.format = decoderConfig.format;
deviceConfig.playback.channels = decoderConfig.channels;
deviceConfig.dataCallback = data_callback;
deviceConfig.pUserData = NULL;
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
printf("Failed to open playback device.\n");
ma_free(pInputFrameData);
return -3;
}
#if USE_NEW_RESAMPLER
/* Resample. */
outputFrameCount = ma_calculate_frame_count_after_src(device.sampleRate, decoderConfig.sampleRate, inputFrameCount);
pOutputFrameData = ma_malloc((size_t)(outputFrameCount * ma_get_bytes_per_frame(device.playback.format, device.playback.channels)));
if (pOutputFrameData == NULL) {
printf("Out of memory.\n");
ma_free(pInputFrameData);
ma_device_uninit(&device);
}
ma_resample_f32(ma_resample_algorithm_sinc, device.playback.internalSampleRate, decoderConfig.sampleRate, outputFrameCount, pOutputFrameData, inputFrameCount, pInputFrameData);
g_pRunningFrameData = pOutputFrameData;
g_outputFrameCount = outputFrameCount;
#else
g_pRunningFrameData = pInputFrameData;
g_outputFrameCount = inputFrameCount;
#endif
if (ma_device_start(&device) != MA_SUCCESS) {
printf("Failed to start playback device.\n");
ma_device_uninit(&device);
ma_free(pInputFrameData);
ma_free(pOutputFrameData);
return -4;
}
printf("Press Enter to quit...");
getchar();
ma_device_uninit(&device);
ma_free(pInputFrameData);
ma_free(pOutputFrameData);
return 0;
}
#if 0
#define SAMPLE_RATE_IN 44100
#define SAMPLE_RATE_OUT 44100
#define CHANNELS 1
#define OUTPUT_FILE "output.wav"
ma_sine_wave sineWave;
ma_uint32 on_read(ma_resampler* pResampler, ma_uint32 frameCount, void** ppFramesOut)
{
ma_assert(pResampler->config.format == ma_format_f32);
return (ma_uint32)ma_sine_wave_read_f32_ex(&sineWave, frameCount, pResampler->config.channels, pResampler->config.layout, (float**)ppFramesOut);
}
int main(int argc, char** argv)
{
ma_result result;
ma_resampler_config resamplerConfig;
ma_resampler resampler;
ma_zero_object(&resamplerConfig);
resamplerConfig.format = ma_format_f32;
resamplerConfig.channels = CHANNELS;
resamplerConfig.sampleRateIn = SAMPLE_RATE_IN;
resamplerConfig.sampleRateOut = SAMPLE_RATE_OUT;
resamplerConfig.algorithm = ma_resampler_algorithm_linear;
resamplerConfig.endOfInputMode = ma_resampler_end_of_input_mode_consume;
resamplerConfig.layout = ma_stream_layout_interleaved;
resamplerConfig.onRead = on_read;
resamplerConfig.pUserData = NULL;
result = ma_resampler_init(&resamplerConfig, &resampler);
if (result != MA_SUCCESS) {
printf("Failed to initialize resampler.\n");
return -1;
}
ma_sine_wave_init(0.5, 400, resamplerConfig.sampleRateIn, &sineWave);
// Write to a WAV file. We'll do about 10 seconds worth, making sure we read in chunks to make sure everything is seamless.
drwav_data_format format;
format.container = drwav_container_riff;
format.format = DR_WAVE_FORMAT_IEEE_FLOAT;
format.channels = resampler.config.channels;
format.sampleRate = resampler.config.sampleRateOut;
format.bitsPerSample = 32;
drwav* pWavWriter = drwav_open_file_write(OUTPUT_FILE, &format);
float buffer[SAMPLE_RATE_IN*CHANNELS];
float* pBuffer = buffer;
ma_uint32 iterations = 10;
ma_uint32 framesToReadPerIteration = ma_countof(buffer)/CHANNELS;
for (ma_uint32 i = 0; i < iterations; ++i) {
ma_uint32 framesRead = (ma_uint32)ma_resampler_read(&resampler, framesToReadPerIteration, &pBuffer);
drwav_write(pWavWriter, framesRead*CHANNELS, buffer);
}
//float** test = &buffer;
drwav_close(pWavWriter);
(void)argc;
(void)argv;
return 0;
}
#endif
#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;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment