linux/sound/usb/line6/playback.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Line 6 Linux USB driver
   4 *
   5 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
   6 */
   7
   8#include <linux/slab.h>
   9#include <sound/core.h>
  10#include <sound/pcm.h>
  11#include <sound/pcm_params.h>
  12
  13#include "capture.h"
  14#include "driver.h"
  15#include "pcm.h"
  16#include "playback.h"
  17
  18/*
  19        Software stereo volume control.
  20*/
  21static void change_volume(struct urb *urb_out, int volume[],
  22                          int bytes_per_frame)
  23{
  24        int chn = 0;
  25
  26        if (volume[0] == 256 && volume[1] == 256)
  27                return;         /* maximum volume - no change */
  28
  29        if (bytes_per_frame == 4) {
  30                __le16 *p, *buf_end;
  31
  32                p = (__le16 *)urb_out->transfer_buffer;
  33                buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
  34
  35                for (; p < buf_end; ++p) {
  36                        short pv = le16_to_cpu(*p);
  37                        int val = (pv * volume[chn & 1]) >> 8;
  38                        pv = clamp(val, -0x8000, 0x7fff);
  39                        *p = cpu_to_le16(pv);
  40                        ++chn;
  41                }
  42        } else if (bytes_per_frame == 6) {
  43                unsigned char *p, *buf_end;
  44
  45                p = (unsigned char *)urb_out->transfer_buffer;
  46                buf_end = p + urb_out->transfer_buffer_length;
  47
  48                for (; p < buf_end; p += 3) {
  49                        int val;
  50
  51                        val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
  52                        val = (val * volume[chn & 1]) >> 8;
  53                        val = clamp(val, -0x800000, 0x7fffff);
  54                        p[0] = val;
  55                        p[1] = val >> 8;
  56                        p[2] = val >> 16;
  57                        ++chn;
  58                }
  59        }
  60}
  61
  62/*
  63        Create signal for impulse response test.
  64*/
  65static void create_impulse_test_signal(struct snd_line6_pcm *line6pcm,
  66                                       struct urb *urb_out, int bytes_per_frame)
  67{
  68        int frames = urb_out->transfer_buffer_length / bytes_per_frame;
  69
  70        if (bytes_per_frame == 4) {
  71                int i;
  72                short *pi = (short *)line6pcm->prev_fbuf;
  73                short *po = (short *)urb_out->transfer_buffer;
  74
  75                for (i = 0; i < frames; ++i) {
  76                        po[0] = pi[0];
  77                        po[1] = 0;
  78                        pi += 2;
  79                        po += 2;
  80                }
  81        } else if (bytes_per_frame == 6) {
  82                int i, j;
  83                unsigned char *pi = line6pcm->prev_fbuf;
  84                unsigned char *po = urb_out->transfer_buffer;
  85
  86                for (i = 0; i < frames; ++i) {
  87                        for (j = 0; j < bytes_per_frame / 2; ++j)
  88                                po[j] = pi[j];
  89
  90                        for (; j < bytes_per_frame; ++j)
  91                                po[j] = 0;
  92
  93                        pi += bytes_per_frame;
  94                        po += bytes_per_frame;
  95                }
  96        }
  97        if (--line6pcm->impulse_count <= 0) {
  98                ((unsigned char *)(urb_out->transfer_buffer))[bytes_per_frame -
  99                                                              1] =
 100                    line6pcm->impulse_volume;
 101                line6pcm->impulse_count = line6pcm->impulse_period;
 102        }
 103}
 104
 105/*
 106        Add signal to buffer for software monitoring.
 107*/
 108static void add_monitor_signal(struct urb *urb_out, unsigned char *signal,
 109                               int volume, int bytes_per_frame)
 110{
 111        if (volume == 0)
 112                return;         /* zero volume - no change */
 113
 114        if (bytes_per_frame == 4) {
 115                __le16 *pi, *po, *buf_end;
 116
 117                pi = (__le16 *)signal;
 118                po = (__le16 *)urb_out->transfer_buffer;
 119                buf_end = po + urb_out->transfer_buffer_length / sizeof(*po);
 120
 121                for (; po < buf_end; ++pi, ++po) {
 122                        short pov = le16_to_cpu(*po);
 123                        short piv = le16_to_cpu(*pi);
 124                        int val = pov + ((piv * volume) >> 8);
 125                        pov = clamp(val, -0x8000, 0x7fff);
 126                        *po = cpu_to_le16(pov);
 127                }
 128        }
 129
 130        /*
 131           We don't need to handle devices with 6 bytes per frame here
 132           since they all support hardware monitoring.
 133         */
 134}
 135
 136/*
 137        Find a free URB, prepare audio data, and submit URB.
 138        must be called in line6pcm->out.lock context
 139*/
 140static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm)
 141{
 142        int index;
 143        int i, urb_size, urb_frames;
 144        int ret;
 145        const int bytes_per_frame =
 146                line6pcm->properties->bytes_per_channel *
 147                line6pcm->properties->playback_hw.channels_max;
 148        const int frame_increment =
 149                line6pcm->properties->rates.rats[0].num_min;
 150        const int frame_factor =
 151                line6pcm->properties->rates.rats[0].den *
 152                (line6pcm->line6->intervals_per_second / LINE6_ISO_INTERVAL);
 153        struct urb *urb_out;
 154
 155        index = find_first_zero_bit(&line6pcm->out.active_urbs,
 156                                    line6pcm->line6->iso_buffers);
 157
 158        if (index < 0 || index >= line6pcm->line6->iso_buffers) {
 159                dev_err(line6pcm->line6->ifcdev, "no free URB found\n");
 160                return -EINVAL;
 161        }
 162
 163        urb_out = line6pcm->out.urbs[index];
 164        urb_size = 0;
 165
 166        /* TODO: this may not work for LINE6_ISO_PACKETS != 1 */
 167        for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
 168                /* compute frame size for given sampling rate */
 169                int fsize = 0;
 170                struct usb_iso_packet_descriptor *fout =
 171                    &urb_out->iso_frame_desc[i];
 172
 173                fsize = line6pcm->prev_fsize;
 174                if (fsize == 0) {
 175                        int n;
 176
 177                        line6pcm->out.count += frame_increment;
 178                        n = line6pcm->out.count / frame_factor;
 179                        line6pcm->out.count -= n * frame_factor;
 180                        fsize = n;
 181                }
 182
 183                fsize *= bytes_per_frame;
 184
 185                fout->offset = urb_size;
 186                fout->length = fsize;
 187                urb_size += fsize;
 188        }
 189
 190        if (urb_size == 0) {
 191                /* can't determine URB size */
 192                dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n");
 193                return -EINVAL;
 194        }
 195
 196        urb_frames = urb_size / bytes_per_frame;
 197        urb_out->transfer_buffer =
 198            line6pcm->out.buffer +
 199            index * LINE6_ISO_PACKETS * line6pcm->max_packet_size_out;
 200        urb_out->transfer_buffer_length = urb_size;
 201        urb_out->context = line6pcm;
 202
 203        if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running) &&
 204            !test_bit(LINE6_FLAG_PAUSE_PLAYBACK, &line6pcm->flags)) {
 205                struct snd_pcm_runtime *runtime =
 206                    get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK)->runtime;
 207
 208                if (line6pcm->out.pos + urb_frames > runtime->buffer_size) {
 209                        /*
 210                           The transferred area goes over buffer boundary,
 211                           copy the data to the temp buffer.
 212                         */
 213                        int len;
 214
 215                        len = runtime->buffer_size - line6pcm->out.pos;
 216
 217                        if (len > 0) {
 218                                memcpy(urb_out->transfer_buffer,
 219                                       runtime->dma_area +
 220                                       line6pcm->out.pos * bytes_per_frame,
 221                                       len * bytes_per_frame);
 222                                memcpy(urb_out->transfer_buffer +
 223                                       len * bytes_per_frame, runtime->dma_area,
 224                                       (urb_frames - len) * bytes_per_frame);
 225                        } else
 226                                dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n",
 227                                        len);
 228                } else {
 229                        memcpy(urb_out->transfer_buffer,
 230                               runtime->dma_area +
 231                               line6pcm->out.pos * bytes_per_frame,
 232                               urb_out->transfer_buffer_length);
 233                }
 234
 235                line6pcm->out.pos += urb_frames;
 236                if (line6pcm->out.pos >= runtime->buffer_size)
 237                        line6pcm->out.pos -= runtime->buffer_size;
 238
 239                change_volume(urb_out, line6pcm->volume_playback,
 240                              bytes_per_frame);
 241        } else {
 242                memset(urb_out->transfer_buffer, 0,
 243                       urb_out->transfer_buffer_length);
 244        }
 245
 246        spin_lock_nested(&line6pcm->in.lock, SINGLE_DEPTH_NESTING);
 247        if (line6pcm->prev_fbuf) {
 248                if (test_bit(LINE6_STREAM_IMPULSE, &line6pcm->out.running)) {
 249                        create_impulse_test_signal(line6pcm, urb_out,
 250                                                   bytes_per_frame);
 251                        if (test_bit(LINE6_STREAM_PCM, &line6pcm->in.running)) {
 252                                line6_capture_copy(line6pcm,
 253                                                   urb_out->transfer_buffer,
 254                                                   urb_out->
 255                                                   transfer_buffer_length);
 256                                line6_capture_check_period(line6pcm,
 257                                        urb_out->transfer_buffer_length);
 258                        }
 259                } else {
 260                        if (!(line6pcm->line6->properties->capabilities & LINE6_CAP_HWMON)
 261                            && line6pcm->out.running && line6pcm->in.running)
 262                                add_monitor_signal(urb_out, line6pcm->prev_fbuf,
 263                                                   line6pcm->volume_monitor,
 264                                                   bytes_per_frame);
 265                }
 266                line6pcm->prev_fbuf = NULL;
 267                line6pcm->prev_fsize = 0;
 268        }
 269        spin_unlock(&line6pcm->in.lock);
 270
 271        ret = usb_submit_urb(urb_out, GFP_ATOMIC);
 272
 273        if (ret == 0)
 274                set_bit(index, &line6pcm->out.active_urbs);
 275        else
 276                dev_err(line6pcm->line6->ifcdev,
 277                        "URB out #%d submission failed (%d)\n", index, ret);
 278
 279        return 0;
 280}
 281
 282/*
 283        Submit all currently available playback URBs.
 284        must be called in line6pcm->out.lock context
 285 */
 286int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
 287{
 288        int ret = 0, i;
 289
 290        for (i = 0; i < line6pcm->line6->iso_buffers; ++i) {
 291                ret = submit_audio_out_urb(line6pcm);
 292                if (ret < 0)
 293                        break;
 294        }
 295
 296        return ret;
 297}
 298
 299/*
 300        Callback for completed playback URB.
 301*/
 302static void audio_out_callback(struct urb *urb)
 303{
 304        int i, index, length = 0, shutdown = 0;
 305        unsigned long flags;
 306        struct snd_line6_pcm *line6pcm = (struct snd_line6_pcm *)urb->context;
 307        struct snd_pcm_substream *substream =
 308            get_substream(line6pcm, SNDRV_PCM_STREAM_PLAYBACK);
 309        const int bytes_per_frame =
 310                line6pcm->properties->bytes_per_channel *
 311                line6pcm->properties->playback_hw.channels_max;
 312
 313#if USE_CLEAR_BUFFER_WORKAROUND
 314        memset(urb->transfer_buffer, 0, urb->transfer_buffer_length);
 315#endif
 316
 317        line6pcm->out.last_frame = urb->start_frame;
 318
 319        /* find index of URB */
 320        for (index = 0; index < line6pcm->line6->iso_buffers; index++)
 321                if (urb == line6pcm->out.urbs[index])
 322                        break;
 323
 324        if (index >= line6pcm->line6->iso_buffers)
 325                return;         /* URB has been unlinked asynchronously */
 326
 327        for (i = 0; i < LINE6_ISO_PACKETS; i++)
 328                length += urb->iso_frame_desc[i].length;
 329
 330        spin_lock_irqsave(&line6pcm->out.lock, flags);
 331
 332        if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
 333                struct snd_pcm_runtime *runtime = substream->runtime;
 334
 335                line6pcm->out.pos_done +=
 336                    length / bytes_per_frame;
 337
 338                if (line6pcm->out.pos_done >= runtime->buffer_size)
 339                        line6pcm->out.pos_done -= runtime->buffer_size;
 340        }
 341
 342        clear_bit(index, &line6pcm->out.active_urbs);
 343
 344        for (i = 0; i < LINE6_ISO_PACKETS; i++)
 345                if (urb->iso_frame_desc[i].status == -EXDEV) {
 346                        shutdown = 1;
 347                        break;
 348                }
 349
 350        if (test_and_clear_bit(index, &line6pcm->out.unlink_urbs))
 351                shutdown = 1;
 352
 353        if (!shutdown) {
 354                submit_audio_out_urb(line6pcm);
 355
 356                if (test_bit(LINE6_STREAM_PCM, &line6pcm->out.running)) {
 357                        line6pcm->out.bytes += length;
 358                        if (line6pcm->out.bytes >= line6pcm->out.period) {
 359                                line6pcm->out.bytes %= line6pcm->out.period;
 360                                spin_unlock(&line6pcm->out.lock);
 361                                snd_pcm_period_elapsed(substream);
 362                                spin_lock(&line6pcm->out.lock);
 363                        }
 364                }
 365        }
 366        spin_unlock_irqrestore(&line6pcm->out.lock, flags);
 367}
 368
 369/* open playback callback */
 370static int snd_line6_playback_open(struct snd_pcm_substream *substream)
 371{
 372        int err;
 373        struct snd_pcm_runtime *runtime = substream->runtime;
 374        struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 375
 376        err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 377                                            &line6pcm->properties->rates);
 378        if (err < 0)
 379                return err;
 380
 381        runtime->hw = line6pcm->properties->playback_hw;
 382        return 0;
 383}
 384
 385/* close playback callback */
 386static int snd_line6_playback_close(struct snd_pcm_substream *substream)
 387{
 388        return 0;
 389}
 390
 391/* playback operators */
 392const struct snd_pcm_ops snd_line6_playback_ops = {
 393        .open = snd_line6_playback_open,
 394        .close = snd_line6_playback_close,
 395        .hw_params = snd_line6_hw_params,
 396        .hw_free = snd_line6_hw_free,
 397        .prepare = snd_line6_prepare,
 398        .trigger = snd_line6_trigger,
 399        .pointer = snd_line6_pointer,
 400};
 401
 402int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
 403{
 404        struct usb_line6 *line6 = line6pcm->line6;
 405        int i;
 406
 407        line6pcm->out.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *),
 408                                     GFP_KERNEL);
 409        if (line6pcm->out.urbs == NULL)
 410                return -ENOMEM;
 411
 412        /* create audio URBs and fill in constant values: */
 413        for (i = 0; i < line6->iso_buffers; ++i) {
 414                struct urb *urb;
 415
 416                /* URB for audio out: */
 417                urb = line6pcm->out.urbs[i] =
 418                    usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
 419
 420                if (urb == NULL)
 421                        return -ENOMEM;
 422
 423                urb->dev = line6->usbdev;
 424                urb->pipe =
 425                    usb_sndisocpipe(line6->usbdev,
 426                                    line6->properties->ep_audio_w &
 427                                    USB_ENDPOINT_NUMBER_MASK);
 428                urb->transfer_flags = URB_ISO_ASAP;
 429                urb->start_frame = -1;
 430                urb->number_of_packets = LINE6_ISO_PACKETS;
 431                urb->interval = LINE6_ISO_INTERVAL;
 432                urb->error_count = 0;
 433                urb->complete = audio_out_callback;
 434                if (usb_urb_ep_type_check(urb))
 435                        return -EINVAL;
 436        }
 437
 438        return 0;
 439}
 440