[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2 01/15] audio: replace open-coded buffer arithmetic
From: |
Christian Schoenebeck |
Subject: |
Re: [PATCH v2 01/15] audio: replace open-coded buffer arithmetic |
Date: |
Wed, 26 Jan 2022 13:01:49 +0100 |
On Dienstag, 25. Januar 2022 19:57:59 CET Volker Rümelin wrote:
> > On Samstag, 22. Januar 2022 13:57:31 CET Volker Rümelin wrote:
> >> Replace open-coded buffer arithmetic with the new function
> >> audio_ring_posb(). That's the position in backward direction
> >> of a given point at a given distance.
> >>
> >> Signed-off-by: Volker Rümelin<vr_qemu@t-online.de>
> >> ---
> >
> > First of all, getting rid of all those redundant, open coded ringbuffer
> > traversal code places highly makes sense!
> >
> >> audio/audio.c | 25 +++++++------------------
> >> audio/audio_int.h | 6 ++++++
> >> audio/coreaudio.c | 10 ++++------
> >> audio/sdlaudio.c | 11 +++++------
> >> 4 files changed, 22 insertions(+), 30 deletions(-)
> >>
> >> diff --git a/audio/audio.c b/audio/audio.c
> >> index dc28685d22..e7a139e289 100644
> >> --- a/audio/audio.c
> >> +++ b/audio/audio.c
> >> @@ -574,19 +574,13 @@ static size_t audio_pcm_sw_get_rpos_in(SWVoiceIn
> >> *sw)
> >>
> >> {
> >>
> >> HWVoiceIn *hw = sw->hw;
> >> ssize_t live = hw->total_samples_captured -
> >> sw->total_hw_samples_acquired;
> >>
> >> - ssize_t rpos;
> >>
> >> if (audio_bug(__func__, live < 0 || live > hw->conv_buf->size)) {
> >>
> >> dolog("live=%zu hw->conv_buf->size=%zu\n", live,
> >> hw->conv_buf->size);
> >> return 0;
> >>
> >> }
> >>
> >> - rpos = hw->conv_buf->pos - live;
> >> - if (rpos >= 0) {
> >> - return rpos;
> >> - } else {
> >> - return hw->conv_buf->size + rpos;
> >> - }
> >> + return audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size);
> >>
> >> }
> >>
> >> static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
> >>
> >> @@ -1394,12 +1388,10 @@ void audio_generic_run_buffer_in(HWVoiceIn *hw)
> >>
> >> void *audio_generic_get_buffer_in(HWVoiceIn *hw, size_t *size)
> >> {
> >>
> >> - ssize_t start = (ssize_t)hw->pos_emul - hw->pending_emul;
> >> + size_t start;
> >>
> >> - if (start < 0) {
> >> - start += hw->size_emul;
> >> - }
> >> - assert(start >= 0 && start < hw->size_emul);
> >> + start = audio_ring_posb(hw->pos_emul, hw->pending_emul,
> >> hw->size_emul); + assert(start < hw->size_emul);
> >>
> >> *size = MIN(*size, hw->pending_emul);
> >> *size = MIN(*size, hw->size_emul - start);
> >>
> >> @@ -1415,13 +1407,10 @@ void audio_generic_put_buffer_in(HWVoiceIn *hw,
> >> void *buf, size_t size) void audio_generic_run_buffer_out(HWVoiceOut
> >> *hw)>>
> >> {
> >>
> >> while (hw->pending_emul) {
> >>
> >> - size_t write_len, written;
> >> - ssize_t start = ((ssize_t) hw->pos_emul) - hw->pending_emul;
> >> + size_t write_len, written, start;
> >>
> >> - if (start < 0) {
> >> - start += hw->size_emul;
> >> - }
> >> - assert(start >= 0 && start < hw->size_emul);
> >> + start = audio_ring_posb(hw->pos_emul, hw->pending_emul,
> >> hw->size_emul); + assert(start < hw->size_emul);
> >>
> >> write_len = MIN(hw->pending_emul, hw->size_emul - start);
> >
> > Just refactoring so far, which looks good so far.
> >
> >> diff --git a/audio/audio_int.h b/audio/audio_int.h
> >> index 428a091d05..2fb459f34e 100644
> >> --- a/audio/audio_int.h
> >> +++ b/audio/audio_int.h
> >> @@ -266,6 +266,12 @@ static inline size_t audio_ring_dist(size_t dst,
> >> size_t src, size_t len)>>
> >> return (dst >= src) ? (dst - src) : (len - src + dst);
> >>
> >> }
> >
> > You haven't touched this function, but while I am looking at it, all
> > function arguments are unsigned. So probably modulo operator might be
> > used to get rid of a branch here.
>
> That would be "return (len - dist + pos) % len;" but on my x86_64 system
> I always prefer a conditional move instruction to a 64 bit integer
> division instruction.
Nevermind, I just mentioned it as a side note, here in QEMU it probably
doesn't matter at all. In other apps this is sometimes used in tight loops
where it can make a measurable difference to get rid of the branch(es).
>
> >> +/* return new position in backward direction at given distance */
> >> +static inline size_t audio_ring_posb(size_t pos, size_t dist, size_t
> >> len)
> >> +{
> >> + return pos >= dist ? pos - dist : len - dist + pos;
> >> +}
> >> +
> >
> > Which is the exact same code as the already existing audio_ring_dist()
> > function above, and I see that you actually already used this in v1
> > before:
> >
> > #define audio_ring_posb(pos, dist, len) audio_ring_dist(pos, dist, len)
> >
> > I would definitely not copy-paste the body. Thomas just suggested in v1 to
> > add a comment, not to duplicate the actual math code:
> > 20220106111718.0ec25383@tuxfamily.org/">https://lore.kernel.org/qemu-devel/20220106111718.0ec25383@tuxfamily.org/
> >
> > Also for consistency, I would have called the function audio_ring_rpos()
> > and would have commented each argument.
>
> In the audio subsystem rpos is typically the read position. I chose posb
> to distinguish it from read position.
>
> > /**
> >
> > * Returns new position in ringbuffer in backward direction at given
> > distance. * @pos: current position in ringbuffer
> > * @dist: distance in ringbuffer to walk in reverse direction
> > * @len: size of ringbuffer
> > */
>
> This comment is better than my comment. I'll use it in my v3 series.
>
> > static inline size_t audio_ring_rpos(pos, dist, len) {
> >
> > return audio_ring_dist(pos, dist, len);
> >
> > }
>
> I don't think this inline function improves readability compared to my
> macro from v1. To understand the code you still have to replace
> parameter names in your mind. My v2 inline function can be understood at
> first glance.
I didn't mean readability. Believe it or not, it took me a bit to realize that
it was the exact same code as above.
Best regards,
Christian Schoenebeck
- [PATCH v2 00/15] reduce audio playback latency, Volker Rümelin, 2022/01/22
- [PATCH v2 02/15] audio: move function audio_pcm_hw_clip_out(), Volker Rümelin, 2022/01/22
- [PATCH v2 03/15] audio: add function audio_pcm_hw_conv_in(), Volker Rümelin, 2022/01/22
- [PATCH v2 04/15] audio: inline function audio_pcm_sw_get_rpos_in(), Volker Rümelin, 2022/01/22
- [PATCH v2 07/15] audio: copy playback stream in sequential order, Volker Rümelin, 2022/01/22
- [PATCH v2 06/15] jackaudio: use more jack audio buffers, Volker Rümelin, 2022/01/22
- [PATCH v2 08/15] audio: add pcm_ops function table for capture backend, Volker Rümelin, 2022/01/22
- [PATCH v2 10/15] audio: restore mixing-engine playback buffer size, Volker Rümelin, 2022/01/22
- [PATCH v2 05/15] paaudio: increase default latency to 46ms, Volker Rümelin, 2022/01/22
- [PATCH v2 09/15] Revert "audio: fix wavcapture segfault", Volker Rümelin, 2022/01/22