diff options
author | Takashi Iwai <tiwai@suse.de> | 2021-06-01 19:24:54 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2021-06-02 10:01:30 +0300 |
commit | d303c5d38b37eed066c0f704c5a76353bce27284 (patch) | |
tree | 35d8605a4a386798bbf562920d74db789eb8cd18 /sound/usb | |
parent | cdebd5530360cfd6240b1692a4c60212a2e39c8a (diff) | |
download | linux-d303c5d38b37eed066c0f704c5a76353bce27284.tar.xz |
ALSA: usb-audio: Pre-calculate buffer byte size
There are a bunch of lines calculating the buffer size in bytes at
each time. Keep the value in subs->buffer_bytes and use it
consistently for the code simplicity.
Link: https://lore.kernel.org/r/20210601162457.4877-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/card.h | 1 | ||||
-rw-r--r-- | sound/usb/pcm.c | 48 |
2 files changed, 25 insertions, 24 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h index a741e7da83a2..b346653d4b76 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -158,6 +158,7 @@ struct snd_usb_substream { unsigned int running: 1; /* running status */ + unsigned int buffer_bytes; /* buffer size in bytes */ unsigned int hwptr_done; /* processed byte position in the buffer */ unsigned int transfer_done; /* processed frames since last period update */ unsigned int frame_limit; /* limits number of packets in URB */ diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 359c759a7023..e8121af8e1d5 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -600,6 +600,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) goto unlock; /* reset the pointer */ + subs->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size); subs->hwptr_done = 0; subs->transfer_done = 0; subs->last_delay = 0; @@ -1147,8 +1148,8 @@ static void retire_capture_urb(struct snd_usb_substream *subs, spin_lock_irqsave(&subs->lock, flags); oldptr = subs->hwptr_done; subs->hwptr_done += bytes; - if (subs->hwptr_done >= runtime->buffer_size * stride) - subs->hwptr_done -= runtime->buffer_size * stride; + if (subs->hwptr_done >= subs->buffer_bytes) + subs->hwptr_done -= subs->buffer_bytes; frames = (bytes + (oldptr % stride)) / stride; subs->transfer_done += frames; if (subs->transfer_done >= runtime->period_size) { @@ -1166,9 +1167,9 @@ static void retire_capture_urb(struct snd_usb_substream *subs, spin_unlock_irqrestore(&subs->lock, flags); /* copy a data chunk */ - if (oldptr + bytes > runtime->buffer_size * stride) { - unsigned int bytes1 = - runtime->buffer_size * stride - oldptr; + if (oldptr + bytes > subs->buffer_bytes) { + unsigned int bytes1 = subs->buffer_bytes - oldptr; + memcpy(runtime->dma_area + oldptr, cp, bytes1); memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1); } else { @@ -1184,10 +1185,9 @@ static inline void fill_playback_urb_dsd_dop(struct snd_usb_substream *subs, struct urb *urb, unsigned int bytes) { struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; - unsigned int stride = runtime->frame_bits >> 3; unsigned int dst_idx = 0; unsigned int src_idx = subs->hwptr_done; - unsigned int wrap = runtime->buffer_size * stride; + unsigned int wrap = subs->buffer_bytes; u8 *dst = urb->transfer_buffer; u8 *src = runtime->dma_area; u8 marker[] = { 0x05, 0xfa }; @@ -1233,8 +1233,8 @@ static inline void fill_playback_urb_dsd_dop(struct snd_usb_substream *subs, subs->hwptr_done++; } } - if (subs->hwptr_done >= runtime->buffer_size * stride) - subs->hwptr_done -= runtime->buffer_size * stride; + if (subs->hwptr_done >= subs->buffer_bytes) + subs->hwptr_done -= subs->buffer_bytes; } static void copy_to_urb(struct snd_usb_substream *subs, struct urb *urb, @@ -1242,10 +1242,10 @@ static void copy_to_urb(struct snd_usb_substream *subs, struct urb *urb, { struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; - if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { + if (subs->hwptr_done + bytes > subs->buffer_bytes) { /* err, the transferred area goes over buffer boundary. */ - unsigned int bytes1 = - runtime->buffer_size * stride - subs->hwptr_done; + unsigned int bytes1 = subs->buffer_bytes - subs->hwptr_done; + memcpy(urb->transfer_buffer + offset, runtime->dma_area + subs->hwptr_done, bytes1); memcpy(urb->transfer_buffer + offset + bytes1, @@ -1255,8 +1255,8 @@ static void copy_to_urb(struct snd_usb_substream *subs, struct urb *urb, runtime->dma_area + subs->hwptr_done, bytes); } subs->hwptr_done += bytes; - if (subs->hwptr_done >= runtime->buffer_size * stride) - subs->hwptr_done -= runtime->buffer_size * stride; + if (subs->hwptr_done >= subs->buffer_bytes) + subs->hwptr_done -= subs->buffer_bytes; } static unsigned int copy_to_urb_quirk(struct snd_usb_substream *subs, @@ -1295,7 +1295,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, int i, stride, period_elapsed = 0; unsigned long flags; - stride = runtime->frame_bits >> 3; + stride = ep->stride; frames = 0; urb->number_of_packets = 0; @@ -1304,8 +1304,8 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, for (i = 0; i < ctx->packets; i++) { counts = snd_usb_endpoint_next_packet_size(ep, ctx, i); /* set up descriptor */ - urb->iso_frame_desc[i].offset = frames * ep->stride; - urb->iso_frame_desc[i].length = counts * ep->stride; + urb->iso_frame_desc[i].offset = frames * stride; + urb->iso_frame_desc[i].length = counts * stride; frames += counts; urb->number_of_packets++; subs->transfer_done += counts; @@ -1320,14 +1320,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, frames -= subs->transfer_done; counts -= subs->transfer_done; urb->iso_frame_desc[i].length = - counts * ep->stride; + counts * stride; subs->transfer_done = 0; } i++; if (i < ctx->packets) { /* add a transfer delimiter */ urb->iso_frame_desc[i].offset = - frames * ep->stride; + frames * stride; urb->iso_frame_desc[i].length = 0; urb->number_of_packets++; } @@ -1340,7 +1340,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, !snd_usb_endpoint_implicit_feedback_sink(ep)) break; } - bytes = frames * ep->stride; + bytes = frames * stride; if (unlikely(ep->cur_format == SNDRV_PCM_FORMAT_DSD_U16_LE && subs->cur_audiofmt->dsd_dop)) { @@ -1350,14 +1350,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, /* bit-reverse the bytes */ u8 *buf = urb->transfer_buffer; for (i = 0; i < bytes; i++) { - int idx = (subs->hwptr_done + i) - % (runtime->buffer_size * stride); + int idx = (subs->hwptr_done + i) % subs->buffer_bytes; + buf[i] = bitrev8(runtime->dma_area[idx]); } subs->hwptr_done += bytes; - if (subs->hwptr_done >= runtime->buffer_size * stride) - subs->hwptr_done -= runtime->buffer_size * stride; + if (subs->hwptr_done >= subs->buffer_bytes) + subs->hwptr_done -= subs->buffer_bytes; } else { /* usual PCM */ if (!subs->tx_length_quirk) |