diff options
Diffstat (limited to 'sound/usb/pcm.c')
-rw-r--r-- | sound/usb/pcm.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index a1298f379428..fd5e982fc98c 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -212,7 +212,7 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | static int start_endpoints(struct snd_usb_substream *subs) | 215 | static int start_endpoints(struct snd_usb_substream *subs, int can_sleep) |
216 | { | 216 | { |
217 | int err; | 217 | int err; |
218 | 218 | ||
@@ -225,7 +225,7 @@ static int start_endpoints(struct snd_usb_substream *subs) | |||
225 | snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep); | 225 | snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep); |
226 | 226 | ||
227 | ep->data_subs = subs; | 227 | ep->data_subs = subs; |
228 | err = snd_usb_endpoint_start(ep); | 228 | err = snd_usb_endpoint_start(ep, can_sleep); |
229 | if (err < 0) { | 229 | if (err < 0) { |
230 | clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags); | 230 | clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags); |
231 | return err; | 231 | return err; |
@@ -236,10 +236,25 @@ static int start_endpoints(struct snd_usb_substream *subs) | |||
236 | !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) { | 236 | !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) { |
237 | struct snd_usb_endpoint *ep = subs->sync_endpoint; | 237 | struct snd_usb_endpoint *ep = subs->sync_endpoint; |
238 | 238 | ||
239 | if (subs->data_endpoint->iface != subs->sync_endpoint->iface || | ||
240 | subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) { | ||
241 | err = usb_set_interface(subs->dev, | ||
242 | subs->sync_endpoint->iface, | ||
243 | subs->sync_endpoint->alt_idx); | ||
244 | if (err < 0) { | ||
245 | snd_printk(KERN_ERR | ||
246 | "%d:%d:%d: cannot set interface (%d)\n", | ||
247 | subs->dev->devnum, | ||
248 | subs->sync_endpoint->iface, | ||
249 | subs->sync_endpoint->alt_idx, err); | ||
250 | return -EIO; | ||
251 | } | ||
252 | } | ||
253 | |||
239 | snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep); | 254 | snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep); |
240 | 255 | ||
241 | ep->sync_slave = subs->data_endpoint; | 256 | ep->sync_slave = subs->data_endpoint; |
242 | err = snd_usb_endpoint_start(ep); | 257 | err = snd_usb_endpoint_start(ep, can_sleep); |
243 | if (err < 0) { | 258 | if (err < 0) { |
244 | clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); | 259 | clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); |
245 | return err; | 260 | return err; |
@@ -547,7 +562,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
547 | /* for playback, submit the URBs now; otherwise, the first hwptr_done | 562 | /* for playback, submit the URBs now; otherwise, the first hwptr_done |
548 | * updates for all URBs would happen at the same time when starting */ | 563 | * updates for all URBs would happen at the same time when starting */ |
549 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) | 564 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) |
550 | return start_endpoints(subs); | 565 | return start_endpoints(subs, 1); |
551 | 566 | ||
552 | return 0; | 567 | return 0; |
553 | } | 568 | } |
@@ -1029,6 +1044,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, | |||
1029 | struct urb *urb) | 1044 | struct urb *urb) |
1030 | { | 1045 | { |
1031 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; | 1046 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; |
1047 | struct snd_usb_endpoint *ep = subs->data_endpoint; | ||
1032 | struct snd_urb_ctx *ctx = urb->context; | 1048 | struct snd_urb_ctx *ctx = urb->context; |
1033 | unsigned int counts, frames, bytes; | 1049 | unsigned int counts, frames, bytes; |
1034 | int i, stride, period_elapsed = 0; | 1050 | int i, stride, period_elapsed = 0; |
@@ -1040,7 +1056,11 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, | |||
1040 | urb->number_of_packets = 0; | 1056 | urb->number_of_packets = 0; |
1041 | spin_lock_irqsave(&subs->lock, flags); | 1057 | spin_lock_irqsave(&subs->lock, flags); |
1042 | for (i = 0; i < ctx->packets; i++) { | 1058 | for (i = 0; i < ctx->packets; i++) { |
1043 | counts = ctx->packet_size[i]; | 1059 | if (ctx->packet_size[i]) |
1060 | counts = ctx->packet_size[i]; | ||
1061 | else | ||
1062 | counts = snd_usb_endpoint_next_packet_size(ep); | ||
1063 | |||
1044 | /* set up descriptor */ | 1064 | /* set up descriptor */ |
1045 | urb->iso_frame_desc[i].offset = frames * stride; | 1065 | urb->iso_frame_desc[i].offset = frames * stride; |
1046 | urb->iso_frame_desc[i].length = counts * stride; | 1066 | urb->iso_frame_desc[i].length = counts * stride; |
@@ -1091,7 +1111,16 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, | |||
1091 | subs->hwptr_done += bytes; | 1111 | subs->hwptr_done += bytes; |
1092 | if (subs->hwptr_done >= runtime->buffer_size * stride) | 1112 | if (subs->hwptr_done >= runtime->buffer_size * stride) |
1093 | subs->hwptr_done -= runtime->buffer_size * stride; | 1113 | subs->hwptr_done -= runtime->buffer_size * stride; |
1114 | |||
1115 | /* update delay with exact number of samples queued */ | ||
1116 | runtime->delay = subs->last_delay; | ||
1094 | runtime->delay += frames; | 1117 | runtime->delay += frames; |
1118 | subs->last_delay = runtime->delay; | ||
1119 | |||
1120 | /* realign last_frame_number */ | ||
1121 | subs->last_frame_number = usb_get_current_frame_number(subs->dev); | ||
1122 | subs->last_frame_number &= 0xFF; /* keep 8 LSBs */ | ||
1123 | |||
1095 | spin_unlock_irqrestore(&subs->lock, flags); | 1124 | spin_unlock_irqrestore(&subs->lock, flags); |
1096 | urb->transfer_buffer_length = bytes; | 1125 | urb->transfer_buffer_length = bytes; |
1097 | if (period_elapsed) | 1126 | if (period_elapsed) |
@@ -1109,12 +1138,26 @@ static void retire_playback_urb(struct snd_usb_substream *subs, | |||
1109 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; | 1138 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; |
1110 | int stride = runtime->frame_bits >> 3; | 1139 | int stride = runtime->frame_bits >> 3; |
1111 | int processed = urb->transfer_buffer_length / stride; | 1140 | int processed = urb->transfer_buffer_length / stride; |
1141 | int est_delay; | ||
1112 | 1142 | ||
1113 | spin_lock_irqsave(&subs->lock, flags); | 1143 | spin_lock_irqsave(&subs->lock, flags); |
1114 | if (processed > runtime->delay) | 1144 | est_delay = snd_usb_pcm_delay(subs, runtime->rate); |
1115 | runtime->delay = 0; | 1145 | /* update delay with exact number of samples played */ |
1146 | if (processed > subs->last_delay) | ||
1147 | subs->last_delay = 0; | ||
1116 | else | 1148 | else |
1117 | runtime->delay -= processed; | 1149 | subs->last_delay -= processed; |
1150 | runtime->delay = subs->last_delay; | ||
1151 | |||
1152 | /* | ||
1153 | * Report when delay estimate is off by more than 2ms. | ||
1154 | * The error should be lower than 2ms since the estimate relies | ||
1155 | * on two reads of a counter updated every ms. | ||
1156 | */ | ||
1157 | if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) | ||
1158 | snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n", | ||
1159 | est_delay, subs->last_delay); | ||
1160 | |||
1118 | spin_unlock_irqrestore(&subs->lock, flags); | 1161 | spin_unlock_irqrestore(&subs->lock, flags); |
1119 | } | 1162 | } |
1120 | 1163 | ||
@@ -1172,7 +1215,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream | |||
1172 | 1215 | ||
1173 | switch (cmd) { | 1216 | switch (cmd) { |
1174 | case SNDRV_PCM_TRIGGER_START: | 1217 | case SNDRV_PCM_TRIGGER_START: |
1175 | err = start_endpoints(subs); | 1218 | err = start_endpoints(subs, 0); |
1176 | if (err < 0) | 1219 | if (err < 0) |
1177 | return err; | 1220 | return err; |
1178 | 1221 | ||