audio: remove sw->ratio

Simplify the resample buffer size calculation.

For audio playback we have
sw->ratio = ((int64_t)sw->hw->info.freq << 32) / sw->info.freq;
samples = ((int64_t)sw->HWBUF.size << 32) / sw->ratio;

This can be simplified to
samples = muldiv64(sw->HWBUF.size, sw->info.freq, sw->hw->info.freq);

For audio recording we have
sw->ratio = ((int64_t)sw->info.freq << 32) / sw->hw->info.freq;
samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32;

This can be simplified to
samples = muldiv64(sw->HWBUF.size, sw->info.freq, sw->hw->info.freq);

With hw = sw->hw this becomes in both cases
samples = muldiv64(HWBUF.size, sw->info.freq, hw->info.freq);

Now that sw->ratio is no longer needed, remove sw->ratio.

Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20230224190555.7409-15-vr_qemu@t-online.de>
This commit is contained in:
Volker Rümelin 2023-02-24 20:05:55 +01:00 committed by Marc-André Lureau
parent 148392abef
commit 2f886a34bb
3 changed files with 9 additions and 24 deletions

View File

@ -478,7 +478,6 @@ static int audio_attach_capture (HWVoiceOut *hw)
sw->info = hw->info; sw->info = hw->info;
sw->empty = 1; sw->empty = 1;
sw->active = hw->enabled; sw->active = hw->enabled;
sw->ratio = ((int64_t) hw_cap->info.freq << 32) / sw->info.freq;
sw->vol = nominal_volume; sw->vol = nominal_volume;
sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq); sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries); QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);

View File

@ -108,7 +108,6 @@ struct SWVoiceOut {
AudioState *s; AudioState *s;
struct audio_pcm_info info; struct audio_pcm_info info;
t_sample *conv; t_sample *conv;
int64_t ratio;
STSampleBuffer resample_buf; STSampleBuffer resample_buf;
void *rate; void *rate;
size_t total_hw_samples_mixed; size_t total_hw_samples_mixed;
@ -126,7 +125,6 @@ struct SWVoiceIn {
AudioState *s; AudioState *s;
int active; int active;
struct audio_pcm_info info; struct audio_pcm_info info;
int64_t ratio;
void *rate; void *rate;
size_t total_hw_samples_acquired; size_t total_hw_samples_acquired;
STSampleBuffer resample_buf; STSampleBuffer resample_buf;

View File

@ -108,32 +108,23 @@ static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw) static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
{ {
HW *hw = sw->hw; HW *hw = sw->hw;
int samples; uint64_t samples;
if (!glue(audio_get_pdo_, TYPE)(sw->s->dev)->mixing_engine) { if (!glue(audio_get_pdo_, TYPE)(sw->s->dev)->mixing_engine) {
return 0; return 0;
} }
#ifdef DAC samples = muldiv64(HWBUF.size, sw->info.freq, hw->info.freq);
samples = ((int64_t)sw->HWBUF.size << 32) / sw->ratio;
#else
samples = (int64_t)sw->HWBUF.size * sw->ratio >> 32;
#endif
if (audio_bug(__func__, samples < 0)) {
dolog("Can not allocate buffer for `%s' (%d samples)\n",
SW_NAME(sw), samples);
return -1;
}
if (samples == 0) { if (samples == 0) {
size_t f_fe_min; uint64_t f_fe_min;
uint64_t f_be = (uint32_t)hw->info.freq;
/* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */ /* f_fe_min = ceil(1 [frames] * f_be [Hz] / size_be [frames]) */
f_fe_min = (hw->info.freq + HWBUF.size - 1) / HWBUF.size; f_fe_min = (f_be + HWBUF.size - 1) / HWBUF.size;
qemu_log_mask(LOG_UNIMP, qemu_log_mask(LOG_UNIMP,
AUDIO_CAP ": The guest selected a " NAME " sample rate" AUDIO_CAP ": The guest selected a " NAME " sample rate"
" of %d Hz for %s. Only sample rates >= %zu Hz are" " of %d Hz for %s. Only sample rates >= %" PRIu64 " Hz"
" supported.\n", " are supported.\n",
sw->info.freq, sw->name, f_fe_min); sw->info.freq, sw->name, f_fe_min);
return -1; return -1;
} }
@ -141,9 +132,9 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
/* /*
* Allocate one additional audio frame that is needed for upsampling * Allocate one additional audio frame that is needed for upsampling
* if the resample buffer size is small. For large buffer sizes take * if the resample buffer size is small. For large buffer sizes take
* care of overflows. * care of overflows and truncation.
*/ */
samples = samples < INT_MAX ? samples + 1 : INT_MAX; samples = samples < SIZE_MAX ? samples + 1 : SIZE_MAX;
sw->resample_buf.buffer = g_new0(st_sample, samples); sw->resample_buf.buffer = g_new0(st_sample, samples);
sw->resample_buf.size = samples; sw->resample_buf.size = samples;
sw->resample_buf.pos = 0; sw->resample_buf.pos = 0;
@ -170,11 +161,8 @@ static int glue (audio_pcm_sw_init_, TYPE) (
sw->hw = hw; sw->hw = hw;
sw->active = 0; sw->active = 0;
#ifdef DAC #ifdef DAC
sw->ratio = ((int64_t) sw->hw->info.freq << 32) / sw->info.freq;
sw->total_hw_samples_mixed = 0; sw->total_hw_samples_mixed = 0;
sw->empty = 1; sw->empty = 1;
#else
sw->ratio = ((int64_t) sw->info.freq << 32) / sw->hw->info.freq;
#endif #endif
if (sw->info.is_float) { if (sw->info.is_float) {