ALSA: line6: Do clipping in volume / monitor manipulations
authorTakashi Iwai <tiwai@suse.de>
Fri, 23 Jan 2015 15:54:36 +0000 (16:54 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 28 Jan 2015 06:21:45 +0000 (07:21 +0100)
Tested-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/line6/playback.c

index 750d91dced576ec26f146c0a184dd50bffb41545..cbcd97f5d629c99f46af45ffc3a11cb9fdeef62a 100644 (file)
@@ -37,7 +37,8 @@ static void change_volume(struct urb *urb_out, int volume[],
                buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
 
                for (; p < buf_end; ++p) {
-                       *p = (*p * volume[chn & 1]) >> 8;
+                       int val = (*p * volume[chn & 1]) >> 8;
+                       *p = clamp(val, 0x7fff, -0x8000);
                        ++chn;
                }
        } else if (bytes_per_frame == 6) {
@@ -51,6 +52,7 @@ static void change_volume(struct urb *urb_out, int volume[],
 
                        val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
                        val = (val * volume[chn & 1]) >> 8;
+                       val = clamp(val, 0x7fffff, -0x800000);
                        p[0] = val;
                        p[1] = val >> 8;
                        p[2] = val >> 16;
@@ -118,8 +120,10 @@ static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
                po = (short *)urb_out->transfer_buffer;
                buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
 
-               for (; po < buf_end; ++pi, ++po)
-                       *po += (*pi * volume) >> 8;
+               for (; po < buf_end; ++pi, ++po) {
+                       int val = *po + ((*pi * volume) >> 8);
+                       *po = clamp(val, 0x7fff, -0x8000);
+               }
        }
 
        /*