summaryrefslogtreecommitdiffstats
path: root/sound/usb/usbaudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r--sound/usb/usbaudio.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index a1bd8040dea4..d5013383fad7 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,
/*
* 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,
struct snd_pcm_runtime *runtime,
struct urb *urb)
{
- unsigned int i;
+ unsigned int i, offs, counts;
struct snd_urb_ctx *ctx = urb->context;
+ int stride = runtime->frame_bits >> 3;
+ offs = 0;
urb->dev = ctx->subs->dev;
urb->number_of_packets = subs->packs_per_ms;
for (i = 0; i < subs->packs_per_ms; ++i) {
- urb->iso_frame_desc[i].offset = 0;
- urb->iso_frame_desc[i].length = 0;
+ /* calculate the size of a packet */
+ 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;
}
@@ -2477,12 +2493,13 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
if (err < 0)
return err;
#if 1
- /* FIXME: temporary hack for extigy/audigy 2 nx */
+ /* FIXME: temporary hack for extigy/audigy 2 nx/zs */
/* extigy apparently supports sample rates other than 48k
* but not in ordinary way. so we enable only 48k atm.
*/
if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
- chip->usb_id == USB_ID(0x041e, 0x3020)) {
+ chip->usb_id == USB_ID(0x041e, 0x3020) ||
+ chip->usb_id == USB_ID(0x041e, 0x3061)) {
if (fmt[3] == USB_FORMAT_TYPE_I &&
fp->rates != SNDRV_PCM_RATE_48000 &&
fp->rates != SNDRV_PCM_RATE_96000)