Files
miniaudio/research/tests/ma_resampler_test_0.c
T
2019-10-19 07:40:46 +10:00

187 lines
6.2 KiB
C

#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