diff --git a/extras/speex_resampler/ma_speex_resampler.h b/extras/speex_resampler/ma_speex_resampler.h index 7696b4f8..388aa59f 100644 --- a/extras/speex_resampler/ma_speex_resampler.h +++ b/extras/speex_resampler/ma_speex_resampler.h @@ -9,6 +9,7 @@ #define spx_uint64_t unsigned long long int ma_speex_resampler_get_required_input_frame_count(SpeexResamplerState* st, spx_uint64_t out_len, spx_uint64_t* in_len); +int ma_speex_resampler_get_expected_output_frame_count(SpeexResamplerState* st, spx_uint64_t in_len, spx_uint64_t* out_len); #endif /* ma_speex_resampler_h */ @@ -54,4 +55,45 @@ EXPORT int ma_speex_resampler_get_required_input_frame_count(SpeexResamplerState return RESAMPLER_ERR_SUCCESS; } + +EXPORT int ma_speex_resampler_get_expected_output_frame_count(SpeexResamplerState* st, spx_uint64_t in_len, spx_uint64_t* out_len) +{ + spx_uint64_t count; + spx_uint64_t last_sample; + spx_uint32_t samp_frac_num; + + if (st == NULL || out_len == NULL) { + return RESAMPLER_ERR_INVALID_ARG; + } + + *out_len = 0; + + if (out_len == 0) { + return RESAMPLER_ERR_SUCCESS; /* Nothing to do. */ + } + + /* miniaudio only uses interleaved APIs so we can safely just use channel index 0 for the calculations. */ + if (st->nb_channels == 0) { + return RESAMPLER_ERR_BAD_STATE; + } + + count = 0; + last_sample = st->last_sample[0]; + samp_frac_num = st->samp_frac_num[0]; + + while (!(last_sample >= in_len)) { + count += 1; + + last_sample += st->int_advance; + samp_frac_num += st->frac_advance; + if (samp_frac_num >= st->den_rate) { + samp_frac_num -= st->den_rate; + last_sample += 1; + } + } + + *out_len = count; + + return RESAMPLER_ERR_SUCCESS; +} #endif \ No newline at end of file diff --git a/research/ma_resampler.h b/research/ma_resampler.h index eff13703..0f56c4f3 100644 --- a/research/ma_resampler.h +++ b/research/ma_resampler.h @@ -802,8 +802,13 @@ ma_uint64 ma_resampler_get_expected_output_frame_count(ma_resampler* pResampler, case ma_resample_algorithm_speex: { #if defined(MA_HAS_SPEEX_RESAMPLER) - /* TODO: Implement me. */ - return 0; + ma_uint64 count; + int speexErr = ma_speex_resampler_get_expected_output_frame_count((SpeexResamplerState*)pResampler->state.speex.pSpeexResamplerState, inputFrameCount, &count); + if (speexErr != RESAMPLER_ERR_SUCCESS) { + return 0; + } + + return count; #else break; #endif