summaryrefslogtreecommitdiff
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/caiaq/device.c8
-rw-r--r--sound/usb/card.c2
-rw-r--r--sound/usb/pcm.c25
3 files changed, 25 insertions, 10 deletions
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index c828f8189c25..e4d6dbb0342d 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -48,10 +48,10 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, Audio 8 DJ},"
"{Native Instruments, Traktor Audio 2},"
"{Native Instruments, Session I/O},"
- "{Native Instruments, GuitarRig mobile}"
- "{Native Instruments, Traktor Kontrol X1}"
- "{Native Instruments, Traktor Kontrol S4}"
- "{Native Instruments, Maschine Controller}");
+ "{Native Instruments, GuitarRig mobile},"
+ "{Native Instruments, Traktor Kontrol X1},"
+ "{Native Instruments, Traktor Kontrol S4},"
+ "{Native Instruments, Maschine Controller}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
diff --git a/sound/usb/card.c b/sound/usb/card.c
index ccf95cfe186f..803953a9bff3 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -646,7 +646,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
as->substream[0].need_setup_ep =
as->substream[1].need_setup_ep = true;
}
- }
+ }
} else {
/*
* otherwise we keep the rest of the system in the dark
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index d82e378d37cb..81f70a719bb9 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -59,7 +59,12 @@ snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs,
/* Approximation based on number of samples per USB frame (ms),
some truncation for 44.1 but the estimate is good enough */
- est_delay = subs->last_delay - (frame_diff * rate / 1000);
+ est_delay = frame_diff * rate / 1000;
+ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
+ est_delay = subs->last_delay - est_delay;
+ else
+ est_delay = subs->last_delay + est_delay;
+
if (est_delay < 0)
est_delay = 0;
return est_delay;
@@ -78,8 +83,7 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream
return SNDRV_PCM_POS_XRUN;
spin_lock(&subs->lock);
hwptr_done = subs->hwptr_done;
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- substream->runtime->delay = snd_usb_pcm_delay(subs,
+ substream->runtime->delay = snd_usb_pcm_delay(subs,
substream->runtime->rate);
spin_unlock(&subs->lock);
return hwptr_done / (substream->runtime->frame_bits >> 3);
@@ -1157,6 +1161,10 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
int i, period_elapsed = 0;
unsigned long flags;
unsigned char *cp;
+ int current_frame_number;
+
+ /* read frame number here, update pointer in critical section */
+ current_frame_number = usb_get_current_frame_number(subs->dev);
stride = runtime->frame_bits >> 3;
@@ -1171,9 +1179,7 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
if (!subs->txfr_quirk)
bytes = frames * stride;
if (bytes % (runtime->sample_bits >> 3) != 0) {
-#ifdef CONFIG_SND_DEBUG_VERBOSE
int oldbytes = bytes;
-#endif
bytes = frames * stride;
snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n",
oldbytes, bytes);
@@ -1190,6 +1196,15 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
subs->transfer_done -= runtime->period_size;
period_elapsed = 1;
}
+ /* capture delay is by construction limited to one URB,
+ * reset delays here
+ */
+ runtime->delay = subs->last_delay = 0;
+
+ /* realign last_frame_number */
+ subs->last_frame_number = current_frame_number;
+ subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
+
spin_unlock_irqrestore(&subs->lock, flags);
/* copy a data chunk */
if (oldptr + bytes > runtime->buffer_size * stride) {