mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
[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>
This commit is contained in:
parent
54c63cfc15
commit
4b28492834
@ -478,22 +478,38 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
|
|||||||
/*
|
/*
|
||||||
* Prepare urb for streaming before playback starts.
|
* Prepare urb for streaming before playback starts.
|
||||||
*
|
*
|
||||||
* We don't care about (or have) any data, so we just send a transfer delimiter.
|
* We don't yet have data, so we send a frame of silence.
|
||||||
*/
|
*/
|
||||||
static int prepare_startup_playback_urb(struct snd_usb_substream *subs,
|
static int prepare_startup_playback_urb(struct snd_usb_substream *subs,
|
||||||
struct snd_pcm_runtime *runtime,
|
struct snd_pcm_runtime *runtime,
|
||||||
struct urb *urb)
|
struct urb *urb)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i, offs, counts;
|
||||||
struct snd_urb_ctx *ctx = urb->context;
|
struct snd_urb_ctx *ctx = urb->context;
|
||||||
|
int stride = runtime->frame_bits >> 3;
|
||||||
|
|
||||||
|
offs = 0;
|
||||||
urb->dev = ctx->subs->dev;
|
urb->dev = ctx->subs->dev;
|
||||||
urb->number_of_packets = subs->packs_per_ms;
|
urb->number_of_packets = subs->packs_per_ms;
|
||||||
for (i = 0; i < subs->packs_per_ms; ++i) {
|
for (i = 0; i < subs->packs_per_ms; ++i) {
|
||||||
urb->iso_frame_desc[i].offset = 0;
|
/* calculate the size of a packet */
|
||||||
urb->iso_frame_desc[i].length = 0;
|
if (subs->fill_max)
|
||||||
|
counts = subs->maxframesize; /* fixed */
|
||||||
|
else {
|
||||||
|
subs->phase = (subs->phase & 0xffff)
|
||||||
|
+ (subs->freqm << subs->datainterval);
|
||||||
|
counts = subs->phase >> 16;
|
||||||
|
if (counts > subs->maxframesize)
|
||||||
|
counts = subs->maxframesize;
|
||||||
|
}
|
||||||
|
urb->iso_frame_desc[i].offset = offs * stride;
|
||||||
|
urb->iso_frame_desc[i].length = counts * stride;
|
||||||
|
offs += counts;
|
||||||
}
|
}
|
||||||
urb->transfer_buffer_length = 0;
|
urb->transfer_buffer_length = offs * stride;
|
||||||
|
memset(urb->transfer_buffer,
|
||||||
|
subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
|
||||||
|
offs * stride);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user