diff --git a/linux/alsa/alsa_driver.c b/linux/alsa/alsa_driver.c index 5e291289..07729c6c 100644 --- a/linux/alsa/alsa_driver.c +++ b/linux/alsa/alsa_driver.c @@ -61,6 +61,7 @@ char* strcasestr(const char* haystack, const char* needle); static int alsa_driver_link (alsa_driver_t *driver); static int alsa_driver_open_device (alsa_driver_t *driver, alsa_device_t *device, bool is_capture); +static int alsa_driver_get_state (snd_pcm_t *handle, int is_capture); void jack_driver_init (jack_driver_t *driver) @@ -1520,20 +1521,22 @@ alsa_driver_start (alsa_driver_t *driver) continue; } - // TODO: amiartus, devices with target state PREPARED should also be prepared, however, - // this makes sense only if alsa_driver_stop alsa_driver_close do not close all devices - // as done in current implementation, once those functions are updated it makes sense to keep - // devices in PREPARED state so they can be started faster on Restart request - if (device->capture_target_state != SND_PCM_STATE_RUNNING) { + if (device->capture_target_state == SND_PCM_STATE_NOTREADY) { continue; } - driver->capture_nfds += snd_pcm_poll_descriptors_count (device->capture_handle); + if (device->capture_target_state == SND_PCM_STATE_RUNNING) { + driver->capture_nfds += snd_pcm_poll_descriptors_count (device->capture_handle); + } if (group_done && device->capture_linked) { continue; } + if (alsa_driver_get_state(device->capture_handle, 1) == SND_PCM_STATE_PREPARED) { + continue; + } + if (device->capture_linked) { group_done = 1; } @@ -1551,16 +1554,22 @@ alsa_driver_start (alsa_driver_t *driver) continue; } - if (device->playback_target_state != SND_PCM_STATE_RUNNING) { + if (device->playback_target_state == SND_PCM_STATE_NOTREADY) { continue; } - driver->playback_nfds += snd_pcm_poll_descriptors_count (device->playback_handle); + if (device->playback_target_state == SND_PCM_STATE_RUNNING) { + driver->playback_nfds += snd_pcm_poll_descriptors_count (device->playback_handle); + } if (group_done && device->playback_linked) { continue; } + if (alsa_driver_get_state(device->playback_handle, 0) == SND_PCM_STATE_PREPARED) { + continue; + } + if (device->playback_linked) { group_done = 1; } @@ -1754,6 +1763,10 @@ alsa_driver_stop (alsa_driver_t *driver) continue; } + if (alsa_driver_get_state(device->capture_handle, 1) != SND_PCM_STATE_RUNNING) { + continue; + } + if (device->capture_linked) { group_done = 1; } @@ -1780,6 +1793,10 @@ alsa_driver_stop (alsa_driver_t *driver) continue; } + if (alsa_driver_get_state(device->playback_handle, 0) != SND_PCM_STATE_RUNNING) { + continue; + } + if (device->playback_linked) { group_done = 1; } @@ -1821,6 +1838,10 @@ alsa_driver_close (alsa_driver_t *driver) device->capture_linked = 0; } + if (device->capture_target_state != SND_PCM_STATE_NOTREADY) { + continue; + } + snd_pcm_close(device->capture_handle); device->capture_handle = NULL; } @@ -1836,6 +1857,10 @@ alsa_driver_close (alsa_driver_t *driver) device->playback_linked = 0; } + if (device->playback_target_state != SND_PCM_STATE_NOTREADY) { + continue; + } + snd_pcm_close(device->playback_handle); device->playback_handle = NULL; }