diff options
author | Volker Rümelin <vr_qemu@t-online.de> | 2023-02-24 20:05:52 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2023-03-06 10:30:23 +0400 |
commit | a9ea567873ba8d532520f194413ff28f37065c00 (patch) | |
tree | c25cdae272de3f9ffbd94439cc7255496cd9c50f /audio/audio.c | |
parent | fbde1edf06dad792ef3e9f51e3f52a49669bdd40 (diff) | |
download | qemu-a9ea567873ba8d532520f194413ff28f37065c00.zip qemu-a9ea567873ba8d532520f194413ff28f37065c00.tar.gz qemu-a9ea567873ba8d532520f194413ff28f37065c00.tar.bz2 |
audio: make recording packet length calculation exact
Introduce the new function st_rate_frames_out() to calculate the
exact number of audio output frames the resampling code can
generate from a given number of audio input frames. When upsampling,
this function returns the maximum number of output frames.
This new function replaces the audio_frontend_frames_in()
function, which calculated the average number of output frames
rounded down to the nearest integer. The audio_frontend_frames_in()
function was additionally used to limit the number of output frames
to the resample buffer size. In audio_pcm_sw_read() the variable
resample_buf.size replaces the open coded audio_frontend_frames_in()
function. In audio_run_in() an additional MIN() function is
necessary.
After this patch the audio packet length calculation for audio
recording is exact.
Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-Id: <20230224190555.7409-12-vr_qemu@t-online.de>
Diffstat (limited to 'audio/audio.c')
-rw-r--r-- | audio/audio.c | 29 |
1 files changed, 8 insertions, 21 deletions
diff --git a/audio/audio.c b/audio/audio.c index 22c36d6..dad17e5 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -579,7 +579,7 @@ static void audio_pcm_sw_resample_in(SWVoiceIn *sw, static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len) { HWVoiceIn *hw = sw->hw; - size_t live, frames_out_max, swlim, total_in, total_out; + size_t live, frames_out_max, total_in, total_out; live = hw->total_samples_captured - sw->total_hw_samples_acquired; if (!live) { @@ -590,12 +590,10 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t buf_len) return 0; } - frames_out_max = buf_len / sw->info.bytes_per_frame; + frames_out_max = MIN(buf_len / sw->info.bytes_per_frame, + sw->resample_buf.size); - swlim = (live * sw->ratio) >> 32; - swlim = MIN(swlim, frames_out_max); - - audio_pcm_sw_resample_in(sw, live, swlim, &total_in, &total_out); + audio_pcm_sw_resample_in(sw, live, frames_out_max, &total_in, &total_out); if (!hw->pcm_ops->volume_in) { mixeng_volume(sw->resample_buf.buffer, total_out, &sw->vol); @@ -979,18 +977,6 @@ void AUD_set_active_in (SWVoiceIn *sw, int on) } } -/** - * audio_frontend_frames_in() - returns the number of frames the resampling - * code generates from frames_in frames - * - * @sw: audio recording frontend - * @frames_in: number of frames - */ -static size_t audio_frontend_frames_in(SWVoiceIn *sw, size_t frames_in) -{ - return (int64_t)frames_in * sw->ratio >> 32; -} - static size_t audio_get_avail (SWVoiceIn *sw) { size_t live; @@ -1007,9 +993,9 @@ static size_t audio_get_avail (SWVoiceIn *sw) } ldebug ( - "%s: get_avail live %zu frontend frames %zu\n", + "%s: get_avail live %zu frontend frames %u\n", SW_NAME (sw), - live, audio_frontend_frames_in(sw, live) + live, st_rate_frames_out(sw->rate, live) ); return live; @@ -1314,8 +1300,9 @@ static void audio_run_in (AudioState *s) size_t sw_avail = audio_get_avail(sw); size_t avail; - avail = audio_frontend_frames_in(sw, sw_avail); + avail = st_rate_frames_out(sw->rate, sw_avail); if (avail > 0) { + avail = MIN(avail, sw->resample_buf.size); sw->callback.fn(sw->callback.opaque, avail * sw->info.bytes_per_frame); } |