diff --git a/miniaudio.h b/miniaudio.h index d418f406..2d560d7c 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -5160,6 +5160,11 @@ Calculates a buffer size in frames from the specified number of milliseconds and */ MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 bufferSizeInMilliseconds, ma_uint32 sampleRate); +/* +Copies PCM frames from one buffer to another. +*/ +MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels); + /* Copies silent frames into the given buffer. */ @@ -8840,6 +8845,11 @@ MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 return bufferSizeInMilliseconds * (sampleRate/1000); } +MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels) +{ + ma_copy_memory_64(dst, src, frameCount * ma_get_bytes_per_frame(format, channels)); +} + MA_API void ma_zero_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels) { ma_zero_memory_64(p, frameCount * ma_get_bytes_per_frame(format, channels)); @@ -32759,7 +32769,11 @@ MA_API ma_linear_resampler_config ma_linear_resampler_config_init(ma_format form static ma_result ma_linear_resampler_set_rate_internal(ma_linear_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut, ma_bool32 isResamplerAlreadyInitialized) { + ma_result result; ma_uint32 gcf; + ma_uint32 lpfSampleRate; + double lpfCutoffFrequency; + ma_lpf_config lpfConfig; if (pResampler == NULL) { return MA_INVALID_ARGS; @@ -32777,34 +32791,28 @@ static ma_result ma_linear_resampler_set_rate_internal(ma_linear_resampler* pRes pResampler->config.sampleRateIn /= gcf; pResampler->config.sampleRateOut /= gcf; - if (pResampler->config.lpfOrder > 0) { - ma_result result; - ma_uint32 lpfSampleRate; - double lpfCutoffFrequency; - ma_lpf_config lpfConfig; + /* Always initialize the low-pass filter, even when the order is 0. */ + if (pResampler->config.lpfOrder > MA_MAX_FILTER_ORDER) { + return MA_INVALID_ARGS; + } - if (pResampler->config.lpfOrder > MA_MAX_FILTER_ORDER) { - return MA_INVALID_ARGS; - } + lpfSampleRate = (ma_uint32)(ma_max(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut)); + lpfCutoffFrequency = ( double)(ma_min(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut) * 0.5 * pResampler->config.lpfNyquistFactor); - lpfSampleRate = (ma_uint32)(ma_max(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut)); - lpfCutoffFrequency = ( double)(ma_min(pResampler->config.sampleRateIn, pResampler->config.sampleRateOut) * 0.5 * pResampler->config.lpfNyquistFactor); + lpfConfig = ma_lpf_config_init(pResampler->config.format, pResampler->config.channels, lpfSampleRate, lpfCutoffFrequency, pResampler->config.lpfOrder); - lpfConfig = ma_lpf_config_init(pResampler->config.format, pResampler->config.channels, lpfSampleRate, lpfCutoffFrequency, pResampler->config.lpfOrder); + /* + If the resampler is alreay initialized we don't want to do a fresh initialization of the low-pass filter because it will result in the cached frames + getting cleared. Instead we re-initialize the filter which will maintain any cached frames. + */ + if (isResamplerAlreadyInitialized) { + result = ma_lpf_reinit(&lpfConfig, &pResampler->lpf); + } else { + result = ma_lpf_init(&lpfConfig, &pResampler->lpf); + } - /* - If the resampler is alreay initialized we don't want to do a fresh initialization of the low-pass filter because it will result in the cached frames - getting cleared. Instead we re-initialize the filter which will maintain any cached frames. - */ - if (isResamplerAlreadyInitialized) { - result = ma_lpf_reinit(&lpfConfig, &pResampler->lpf); - } else { - result = ma_lpf_init(&lpfConfig, &pResampler->lpf); - } - - if (result != MA_SUCCESS) { - return result; - } + if (result != MA_SUCCESS) { + return result; } pResampler->inAdvanceInt = pResampler->config.sampleRateIn / pResampler->config.sampleRateOut; @@ -42484,10 +42492,12 @@ REVISION HISTORY ================ v0.10.5 - TBD - Change ma_zero_pcm_frames() to take a 64-bit frame count. + - Add ma_copy_pcm_frames(). - Add MA_NO_GENERATION build option to exclude the `ma_waveform` and `ma_noise` APIs from the build. - Add support for formatted logging to the VC6 build. - - Minor documentation updates. + - Fix a crash in the linear resampler when LPF order is 0. - Fix compilation errors and warnings with older versions of Visual Studio. + - Minor documentation updates. v0.10.4 - 2020-04-12 - Fix a data conversion bug when converting from the client format to the native device format.