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