Keep playback URBs running continuously between open/close cycles via ghost mode
This commit is contained in:
parent
54447e376b
commit
32986d7934
|
|
@ -128,6 +128,7 @@ int tascam_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_
|
||||||
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
||||||
usb_kill_anchored_urbs(&tascam->capture_anchor);
|
usb_kill_anchored_urbs(&tascam->capture_anchor);
|
||||||
atomic_set(&tascam->active_urbs, 0);
|
atomic_set(&tascam->active_urbs, 0);
|
||||||
|
tascam->running_ghost_playback = false;
|
||||||
|
|
||||||
u16 stream_mode = (tascam->dev_id == USB_PID_TASCAM_US200) ? MODE_VAL_STREAM_START_US200 : MODE_VAL_STREAM_START;
|
u16 stream_mode = (tascam->dev_id == USB_PID_TASCAM_US200) ? MODE_VAL_STREAM_START_US200 : MODE_VAL_STREAM_START;
|
||||||
err = us144mkii_configure_device_for_rate(tascam, rate, stream_mode);
|
err = us144mkii_configure_device_for_rate(tascam, rate, stream_mode);
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,6 @@ static int tascam_playback_close(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct tascam_card *tascam = snd_pcm_substream_chip(substream);
|
struct tascam_card *tascam = snd_pcm_substream_chip(substream);
|
||||||
atomic_set(&tascam->playback_active, 0);
|
atomic_set(&tascam->playback_active, 0);
|
||||||
usb_kill_anchored_urbs(&tascam->playback_anchor);
|
|
||||||
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
|
||||||
tascam->playback_substream = NULL;
|
tascam->playback_substream = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -140,18 +138,21 @@ static int tascam_playback_prepare(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct tascam_card *tascam = snd_pcm_substream_chip(substream);
|
struct tascam_card *tascam = snd_pcm_substream_chip(substream);
|
||||||
|
|
||||||
usb_kill_anchored_urbs(&tascam->playback_anchor);
|
|
||||||
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
|
||||||
|
|
||||||
tascam->driver_playback_pos = 0;
|
tascam->driver_playback_pos = 0;
|
||||||
tascam->playback_frames_consumed = 0;
|
tascam->playback_frames_consumed = 0;
|
||||||
tascam->last_pb_period_pos = 0;
|
tascam->last_pb_period_pos = 0;
|
||||||
tascam->feedback_synced = false;
|
tascam->feedback_synced = false;
|
||||||
tascam->running_ghost_playback = false;
|
|
||||||
|
if (tascam->running_ghost_playback)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
usb_kill_anchored_urbs(&tascam->playback_anchor);
|
||||||
|
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
||||||
|
|
||||||
tascam->feedback_urb_skip_count = 4;
|
tascam->feedback_urb_skip_count = 4;
|
||||||
tascam->phase_accum = 0;
|
tascam->phase_accum = 0;
|
||||||
tascam->freq_q16 = div_u64(((u64)tascam->current_rate << 16), 8000);
|
tascam->freq_q16 = div_u64(((u64)tascam->current_rate << 16), 8000);
|
||||||
|
tascam->running_ghost_playback = false;
|
||||||
prepare_urb_descriptors(tascam);
|
prepare_urb_descriptors(tascam);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -181,8 +182,6 @@ static int tascam_playback_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||||
atomic_set(&tascam->playback_active, 0);
|
atomic_set(&tascam->playback_active, 0);
|
||||||
/* Fall back to ghost playback if capture/midi active */
|
|
||||||
if (atomic_read(&tascam->stream_refs) > 0)
|
|
||||||
tascam->running_ghost_playback = true;
|
tascam->running_ghost_playback = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -199,8 +198,15 @@ static snd_pcm_uframes_t tascam_playback_pointer(struct snd_pcm_substream *subst
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u64 pos;
|
u64 pos;
|
||||||
|
|
||||||
if (!atomic_read(&tascam->playback_active))
|
if (!atomic_read(&tascam->playback_active)) {
|
||||||
|
if (tascam->running_ghost_playback) {
|
||||||
|
spin_lock_irqsave(&tascam->lock, flags);
|
||||||
|
pos = tascam->playback_frames_consumed;
|
||||||
|
spin_unlock_irqrestore(&tascam->lock, flags);
|
||||||
|
return (snd_pcm_uframes_t)pos;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&tascam->lock, flags);
|
spin_lock_irqsave(&tascam->lock, flags);
|
||||||
pos = tascam->playback_frames_consumed;
|
pos = tascam->playback_frames_consumed;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue