ALSA: usb-audio: Pre-calculate buffer byte size
authorTakashi Iwai <tiwai@suse.de>
Tue, 1 Jun 2021 16:24:54 +0000 (18:24 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 2 Jun 2021 07:01:30 +0000 (09:01 +0200)
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>
sound/usb/card.h
sound/usb/pcm.c

index a741e7d..b346653 100644 (file)
@@ -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 */
index 359c759..e8121af 100644 (file)
@@ -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)