Browse Source

jack alsa: implement restart request [3/3]

in case ALSA_DRIVER_FEAT_LINK_DEVS is defined, driver will attempt to
snd_pcm_link all devices

Change-Id: I7bd54b8414d0b614786bee1078667a9aa595b58f
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
(cherry picked from commit da45a136f5)
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
pull/608/head
Adam Miartus Timo Wischer 6 years ago
parent
commit
418f4edab2
3 changed files with 142 additions and 0 deletions
  1. +6
    -0
      linux/alsa/JackAlsaDriver.cpp
  2. +135
    -0
      linux/alsa/alsa_driver.c
  3. +1
    -0
      linux/alsa/alsa_driver.h

+ 6
- 0
linux/alsa/JackAlsaDriver.cpp View File

@@ -863,6 +863,9 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor ()
value.i = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "close-idle-devs", 'c', JackDriverParamBool, &value, NULL, "Close idle devices on alsa driver restart request", NULL);

value.i = 0;
jack_driver_descriptor_add_parameter(desc, &filler, "unlinked-devs", 'u', JackDriverParamBool, &value, NULL, "Do not link devices", NULL);

return desc;
}

@@ -1053,6 +1056,9 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke
info.features |= param->value.i ? ALSA_DRIVER_FEAT_CLOSE_IDLE_DEVS : 0;
break;

case 'u':
info.features |= param->value.i ? ALSA_DRIVER_FEAT_UNLINKED_DEVS : 0;
break;
}
}



+ 135
- 0
linux/alsa/alsa_driver.c View File

@@ -1415,6 +1415,81 @@ alsa_driver_open (alsa_driver_t *driver)
}
}

if (driver->features & ALSA_DRIVER_FEAT_UNLINKED_DEVS) {
jack_info ("alsa driver linking disabled");
return 0;
} else {
jack_info ("alsa driver linking enabled");
}

snd_pcm_t *group_handle = NULL;

for (int i = 0; i < driver->devices_c_count; ++i) {
alsa_device_t *device = &driver->devices[i];

if (!device->capture_handle) {
continue;
}

if (device->capture_target_state != SND_PCM_STATE_RUNNING) {
continue;
}

if (group_handle == NULL) {
group_handle = device->capture_handle;
device->capture_linked = 1;
continue;
}

if (device->capture_linked) {
continue;
}

if (group_handle == device->capture_handle) {
device->capture_linked = 1;
continue;
}

if (snd_pcm_link (group_handle, device->capture_handle) != 0) {
jack_error ("failed to add device to link group C: '%s'", device->capture_name);
continue;
}
device->capture_linked = 1;
}

for (int i = 0; i < driver->devices_p_count; ++i) {
alsa_device_t *device = &driver->devices[i];

if (!device->playback_handle) {
continue;
}

if (device->playback_target_state != SND_PCM_STATE_RUNNING) {
continue;
}

if (group_handle == NULL) {
group_handle = device->playback_handle;
device->playback_linked = 1;
continue;
}

if (device->playback_linked) {
continue;
}

if (group_handle == device->playback_handle) {
device->playback_linked = 1;
continue;
}

if (snd_pcm_link (group_handle, device->playback_handle) != 0) {
jack_error ("failed to add device to link group P: '%s'", device->playback_name);
continue;
}
device->playback_linked = 1;
}

return 0;
}

@@ -1446,6 +1521,13 @@ alsa_driver_start (alsa_driver_t *driver)
}

driver->capture_nfds += snd_pcm_poll_descriptors_count (device->capture_handle);

if (group_done && device->capture_linked) {
continue;
}

if (device->capture_linked) {
group_done = 1;
}

if ((err = alsa_driver_prepare (device->capture_handle, SND_PCM_STREAM_CAPTURE)) < 0) {
@@ -1467,6 +1549,14 @@ alsa_driver_start (alsa_driver_t *driver)

driver->playback_nfds += snd_pcm_poll_descriptors_count (device->playback_handle);

if (group_done && device->playback_linked) {
continue;
}

if (device->playback_linked) {
group_done = 1;
}

if ((err = alsa_driver_prepare (device->playback_handle, SND_PCM_STREAM_PLAYBACK)) < 0) {
jack_error ("ALSA: failed to prepare device '%s' (%s)", device->playback_name, snd_strerror(err));
return -1;
@@ -1558,6 +1648,8 @@ alsa_driver_start (alsa_driver_t *driver)
#endif
}

group_done = 0;

for (int i = 0; i < driver->devices_c_count; ++i) {
alsa_device_t *device = &driver->devices[i];

@@ -1569,6 +1661,14 @@ alsa_driver_start (alsa_driver_t *driver)
continue;
}

if (group_done && device->capture_linked) {
continue;
}

if (device->capture_linked) {
group_done = 1;
}

if ((err = alsa_driver_stream_start (device->capture_handle, SND_PCM_STREAM_CAPTURE)) < 0) {
jack_error ("ALSA: failed to start device C: '%s' (%s)", device->capture_name,
snd_strerror(err));
@@ -1587,6 +1687,14 @@ alsa_driver_start (alsa_driver_t *driver)
continue;
}

if (group_done && device->playback_linked) {
continue;
}

if (device->playback_linked) {
group_done = 1;
}

if ((err = alsa_driver_stream_start (device->playback_handle, SND_PCM_STREAM_PLAYBACK)) < 0) {
jack_error ("ALSA: failed to start device P: '%s' (%s)", device->playback_name,
snd_strerror(err));
@@ -1626,6 +1734,7 @@ alsa_driver_stop (alsa_driver_t *driver)
// JACK2
ClearOutput();

int group_done = 0;

for (int i = 0; i < driver->devices_c_count; ++i) {
alsa_device_t *device = &driver->devices[i];
@@ -1633,6 +1742,14 @@ alsa_driver_stop (alsa_driver_t *driver)
continue;
}

if (group_done && device->capture_linked) {
continue;
}

if (device->capture_linked) {
group_done = 1;
}

#ifdef __QNXNTO__
/* In case of capture: Flush discards the frames */
err = snd_pcm_plugin_flush(device->capture_handle, SND_PCM_CHANNEL_CAPTURE);
@@ -1651,6 +1768,14 @@ alsa_driver_stop (alsa_driver_t *driver)
continue;
}

if (group_done && device->playback_linked) {
continue;
}

if (device->playback_linked) {
group_done = 1;
}

#ifdef __QNXNTO__
/* In case of playback: Drain discards the frames */
err = snd_pcm_plugin_playback_drain(device->playback_handle);
@@ -1683,6 +1808,11 @@ alsa_driver_close (alsa_driver_t *driver)
continue;
}

if (device->capture_linked) {
snd_pcm_unlink(device->capture_handle);
device->capture_linked = 0;
}

snd_pcm_close(device->capture_handle);
device->capture_handle = NULL;
}
@@ -1693,6 +1823,11 @@ alsa_driver_close (alsa_driver_t *driver)
continue;
}

if (device->playback_linked) {
snd_pcm_unlink(device->playback_handle);
device->playback_linked = 0;
}

snd_pcm_close(device->playback_handle);
device->playback_handle = NULL;
}


+ 1
- 0
linux/alsa/alsa_driver.h View File

@@ -70,6 +70,7 @@ typedef int32_t alsa_driver_default_format_t;
#endif

#define ALSA_DRIVER_FEAT_CLOSE_IDLE_DEVS (1 << 1)
#define ALSA_DRIVER_FEAT_UNLINKED_DEVS (1 << 2)

#ifdef __cplusplus
extern "C"


Loading…
Cancel
Save