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/mixeng.c | |
parent | fbde1edf06dad792ef3e9f51e3f52a49669bdd40 (diff) |
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/mixeng.c')
-rw-r--r-- | audio/mixeng.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/audio/mixeng.c b/audio/mixeng.c index a24c8c45a7..69f6549224 100644 --- a/audio/mixeng.c +++ b/audio/mixeng.c @@ -441,6 +441,47 @@ void st_rate_stop (void *opaque) } /** + * st_rate_frames_out() - returns the number of frames the resampling code + * generates from frames_in frames + * + * @opaque: pointer to struct rate + * @frames_in: number of frames + * + * When upsampling, there may be more than one correct result. In this case, + * the function returns the maximum number of output frames the resampling + * code can generate. + */ +uint32_t st_rate_frames_out(void *opaque, uint32_t frames_in) +{ + struct rate *rate = opaque; + uint64_t opos_end, opos_delta; + uint32_t ipos_end; + uint32_t frames_out; + + if (rate->opos_inc == 1ULL << 32) { + return frames_in; + } + + /* no output frame without at least one input frame */ + if (!frames_in) { + return 0; + } + + /* last frame read was at rate->ipos - 1 */ + ipos_end = rate->ipos - 1 + frames_in; + opos_end = (uint64_t)ipos_end << 32; + + /* last frame written was at rate->opos - rate->opos_inc */ + if (opos_end + rate->opos_inc <= rate->opos) { + return 0; + } + opos_delta = opos_end - rate->opos + rate->opos_inc; + frames_out = opos_delta / rate->opos_inc; + + return opos_delta % rate->opos_inc ? frames_out : frames_out - 1; +} + +/** * st_rate_frames_in() - returns the number of frames needed to * get frames_out frames after resampling * |