|
|
|
@@ -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; |
|
|
|
} |
|
|
|
|