aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2006-01-12 02:17:49 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-22 10:24:09 -0500
commit4b2849283461a64c6d8cc6c7e72c62d7b4d91b43 (patch)
treefc3b053257c89bc1afd2796ef29411fc5cad2d90
parent54c63cfc153c6909a5d5dbe6072e8704b091f30e (diff)
[ALSA] usb-audio: don't use empty packets at start of playback
Modules: USB generic driver Some widespread USB interface chips with adaptive iso endpoints hang after receiving a series of empty packets when they expect data (ALSA bug#1585). To avoid this, we have to send packets containing silence (zero samples) instead. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
-rw-r--r--sound/usb/usbaudio.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index a1bd8040dea4..95729730bcdc 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -478,22 +478,38 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
478/* 478/*
479 * Prepare urb for streaming before playback starts. 479 * Prepare urb for streaming before playback starts.
480 * 480 *
481 * We don't care about (or have) any data, so we just send a transfer delimiter. 481 * We don't yet have data, so we send a frame of silence.
482 */ 482 */
483static int prepare_startup_playback_urb(struct snd_usb_substream *subs, 483static int prepare_startup_playback_urb(struct snd_usb_substream *subs,
484 struct snd_pcm_runtime *runtime, 484 struct snd_pcm_runtime *runtime,
485 struct urb *urb) 485 struct urb *urb)
486{ 486{
487 unsigned int i; 487 unsigned int i, offs, counts;
488 struct snd_urb_ctx *ctx = urb->context; 488 struct snd_urb_ctx *ctx = urb->context;
489 int stride = runtime->frame_bits >> 3;
489 490
491 offs = 0;
490 urb->dev = ctx->subs->dev; 492 urb->dev = ctx->subs->dev;
491 urb->number_of_packets = subs->packs_per_ms; 493 urb->number_of_packets = subs->packs_per_ms;
492 for (i = 0; i < subs->packs_per_ms; ++i) { 494 for (i = 0; i < subs->packs_per_ms; ++i) {
493 urb->iso_frame_desc[i].offset = 0; 495 /* calculate the size of a packet */
494 urb->iso_frame_desc[i].length = 0; 496 if (subs->fill_max)
497 counts = subs->maxframesize; /* fixed */
498 else {
499 subs->phase = (subs->phase & 0xffff)
500 + (subs->freqm << subs->datainterval);
501 counts = subs->phase >> 16;
502 if (counts > subs->maxframesize)
503 counts = subs->maxframesize;
504 }
505 urb->iso_frame_desc[i].offset = offs * stride;
506 urb->iso_frame_desc[i].length = counts * stride;
507 offs += counts;
495 } 508 }
496 urb->transfer_buffer_length = 0; 509 urb->transfer_buffer_length = offs * stride;
510 memset(urb->transfer_buffer,
511 subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
512 offs * stride);
497 return 0; 513 return 0;
498} 514}
499 515