diff options
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/caiaq/device.c | 8 | ||||
-rw-r--r-- | sound/usb/card.c | 2 | ||||
-rw-r--r-- | sound/usb/pcm.c | 25 |
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}," | |||
48 | "{Native Instruments, Audio 8 DJ}," | 48 | "{Native Instruments, Audio 8 DJ}," |
49 | "{Native Instruments, Traktor Audio 2}," | 49 | "{Native Instruments, Traktor Audio 2}," |
50 | "{Native Instruments, Session I/O}," | 50 | "{Native Instruments, Session I/O}," |
51 | "{Native Instruments, GuitarRig mobile}" | 51 | "{Native Instruments, GuitarRig mobile}," |
52 | "{Native Instruments, Traktor Kontrol X1}" | 52 | "{Native Instruments, Traktor Kontrol X1}," |
53 | "{Native Instruments, Traktor Kontrol S4}" | 53 | "{Native Instruments, Traktor Kontrol S4}," |
54 | "{Native Instruments, Maschine Controller}"); | 54 | "{Native Instruments, Maschine Controller}}"); |
55 | 55 | ||
56 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 56 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
57 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 57 | 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) | |||
646 | as->substream[0].need_setup_ep = | 646 | as->substream[0].need_setup_ep = |
647 | as->substream[1].need_setup_ep = true; | 647 | as->substream[1].need_setup_ep = true; |
648 | } | 648 | } |
649 | } | 649 | } |
650 | } else { | 650 | } else { |
651 | /* | 651 | /* |
652 | * otherwise we keep the rest of the system in the dark | 652 | * 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, | |||
59 | 59 | ||
60 | /* Approximation based on number of samples per USB frame (ms), | 60 | /* Approximation based on number of samples per USB frame (ms), |
61 | some truncation for 44.1 but the estimate is good enough */ | 61 | some truncation for 44.1 but the estimate is good enough */ |
62 | est_delay = subs->last_delay - (frame_diff * rate / 1000); | 62 | est_delay = frame_diff * rate / 1000; |
63 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) | ||
64 | est_delay = subs->last_delay - est_delay; | ||
65 | else | ||
66 | est_delay = subs->last_delay + est_delay; | ||
67 | |||
63 | if (est_delay < 0) | 68 | if (est_delay < 0) |
64 | est_delay = 0; | 69 | est_delay = 0; |
65 | return est_delay; | 70 | return est_delay; |
@@ -78,8 +83,7 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream | |||
78 | return SNDRV_PCM_POS_XRUN; | 83 | return SNDRV_PCM_POS_XRUN; |
79 | spin_lock(&subs->lock); | 84 | spin_lock(&subs->lock); |
80 | hwptr_done = subs->hwptr_done; | 85 | hwptr_done = subs->hwptr_done; |
81 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 86 | substream->runtime->delay = snd_usb_pcm_delay(subs, |
82 | substream->runtime->delay = snd_usb_pcm_delay(subs, | ||
83 | substream->runtime->rate); | 87 | substream->runtime->rate); |
84 | spin_unlock(&subs->lock); | 88 | spin_unlock(&subs->lock); |
85 | return hwptr_done / (substream->runtime->frame_bits >> 3); | 89 | return hwptr_done / (substream->runtime->frame_bits >> 3); |
@@ -1157,6 +1161,10 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1157 | int i, period_elapsed = 0; | 1161 | int i, period_elapsed = 0; |
1158 | unsigned long flags; | 1162 | unsigned long flags; |
1159 | unsigned char *cp; | 1163 | unsigned char *cp; |
1164 | int current_frame_number; | ||
1165 | |||
1166 | /* read frame number here, update pointer in critical section */ | ||
1167 | current_frame_number = usb_get_current_frame_number(subs->dev); | ||
1160 | 1168 | ||
1161 | stride = runtime->frame_bits >> 3; | 1169 | stride = runtime->frame_bits >> 3; |
1162 | 1170 | ||
@@ -1171,9 +1179,7 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1171 | if (!subs->txfr_quirk) | 1179 | if (!subs->txfr_quirk) |
1172 | bytes = frames * stride; | 1180 | bytes = frames * stride; |
1173 | if (bytes % (runtime->sample_bits >> 3) != 0) { | 1181 | if (bytes % (runtime->sample_bits >> 3) != 0) { |
1174 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1175 | int oldbytes = bytes; | 1182 | int oldbytes = bytes; |
1176 | #endif | ||
1177 | bytes = frames * stride; | 1183 | bytes = frames * stride; |
1178 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", | 1184 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", |
1179 | oldbytes, bytes); | 1185 | oldbytes, bytes); |
@@ -1190,6 +1196,15 @@ static void retire_capture_urb(struct snd_usb_substream *subs, | |||
1190 | subs->transfer_done -= runtime->period_size; | 1196 | subs->transfer_done -= runtime->period_size; |
1191 | period_elapsed = 1; | 1197 | period_elapsed = 1; |
1192 | } | 1198 | } |
1199 | /* capture delay is by construction limited to one URB, | ||
1200 | * reset delays here | ||
1201 | */ | ||
1202 | runtime->delay = subs->last_delay = 0; | ||
1203 | |||
1204 | /* realign last_frame_number */ | ||
1205 | subs->last_frame_number = current_frame_number; | ||
1206 | subs->last_frame_number &= 0xFF; /* keep 8 LSBs */ | ||
1207 | |||
1193 | spin_unlock_irqrestore(&subs->lock, flags); | 1208 | spin_unlock_irqrestore(&subs->lock, flags); |
1194 | /* copy a data chunk */ | 1209 | /* copy a data chunk */ |
1195 | if (oldptr + bytes > runtime->buffer_size * stride) { | 1210 | if (oldptr + bytes > runtime->buffer_size * stride) { |