|
|
|
@@ -360,9 +360,29 @@ int JackAlsaDriver::Open(alsa_driver_info_t info) |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
// ALSA driver may have changed the in/out values |
|
|
|
fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels; |
|
|
|
fPlaybackChannels = ((alsa_driver_t *)fDriver)->playback_nchannels; |
|
|
|
/* this feature caused driver to skip opening alsa devices, therefore populate channels from user input */ |
|
|
|
if (info.features & ALSA_DRIVER_FEAT_START_CLOSED) { |
|
|
|
for (size_t i = 0; i < std::max(info.devices_capture_size, info.devices_playback_size); ++i) { |
|
|
|
if (i < info.devices_capture_size && info.devices[i].capture_channels < 1) { |
|
|
|
jack_error ("invalid or missing channels parameter with '-x' option 'start-closed' for device C: '%s'", info.devices[i].capture_name); |
|
|
|
Close(); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
if (i < info.devices_playback_size && info.devices[i].playback_channels < 1) { |
|
|
|
jack_error ("invalid or missing channels parameter with '-x' option 'start-closed' for device P: '%s'", info.devices[i].playback_name); |
|
|
|
Close(); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
fCaptureChannels += info.devices[i].capture_channels; |
|
|
|
fPlaybackChannels += info.devices[i].playback_channels; |
|
|
|
} |
|
|
|
/* in case we really opened alsa devices, channel information is generated by driver */ |
|
|
|
} else { |
|
|
|
fCaptureChannels = ((alsa_driver_t *)fDriver)->capture_nchannels; |
|
|
|
fPlaybackChannels = ((alsa_driver_t *)fDriver)->playback_nchannels; |
|
|
|
} |
|
|
|
|
|
|
|
#ifndef __QNXNTO__ |
|
|
|
if (JackServerGlobals::on_device_reservation_loop != NULL) { |
|
|
|
@@ -565,7 +585,11 @@ int JackAlsaDriver::TargetState(int init, int connections_count) |
|
|
|
if (connections_count > 0) { |
|
|
|
state = SND_PCM_STATE_RUNNING; |
|
|
|
} else if (init) { |
|
|
|
state = SND_PCM_STATE_RUNNING; |
|
|
|
if (driver->features & ALSA_DRIVER_FEAT_START_CLOSED) { |
|
|
|
state = SND_PCM_STATE_NOTREADY; |
|
|
|
} else { |
|
|
|
state = SND_PCM_STATE_RUNNING; |
|
|
|
} |
|
|
|
} else if (driver->features & ALSA_DRIVER_FEAT_CLOSE_IDLE_DEVS) { |
|
|
|
state = SND_PCM_STATE_NOTREADY; |
|
|
|
} else { |
|
|
|
@@ -838,8 +862,8 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () |
|
|
|
NULL); |
|
|
|
|
|
|
|
strcpy(value.str, "none"); |
|
|
|
jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamString, &value, NULL, "List of device capture channels (defaults to hardware max)", NULL); |
|
|
|
jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamString, &value, NULL, "List of device playback channels (defaults to hardware max)", NULL); |
|
|
|
jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamString, &value, NULL, "List of device capture channels (defaults to hw max)", NULL); |
|
|
|
jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamString, &value, NULL, "List of device playback channels (defaults to hw max)", NULL); |
|
|
|
|
|
|
|
value.i = FALSE; |
|
|
|
jack_driver_descriptor_add_parameter(desc, &filler, "shorts", 'S', JackDriverParamBool, &value, NULL, "Try 16-bit samples before 32-bit", NULL); |
|
|
|
@@ -862,6 +886,9 @@ SERVER_EXPORT const jack_driver_desc_t* driver_get_descriptor () |
|
|
|
"ALSA MIDI driver", |
|
|
|
NULL); |
|
|
|
|
|
|
|
value.i = 0; |
|
|
|
jack_driver_descriptor_add_parameter(desc, &filler, "start-closed", 'x', JackDriverParamBool, &value, NULL, "Start with all devices closed", NULL); |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
@@ -878,8 +905,7 @@ struct array_string_t |
|
|
|
discard_duplicate, |
|
|
|
}; |
|
|
|
|
|
|
|
uint64_t size; |
|
|
|
char **data; |
|
|
|
std::vector<char*> data; |
|
|
|
}; |
|
|
|
|
|
|
|
void array_string_free(struct array_string_t *obj) |
|
|
|
@@ -887,49 +913,35 @@ void array_string_free(struct array_string_t *obj) |
|
|
|
if (obj == NULL) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (obj->data == NULL) { |
|
|
|
return; |
|
|
|
} |
|
|
|
for (size_t i = 0; i < obj->size; ++i) { |
|
|
|
for (size_t i = 0; i < obj->data.size(); ++i) { |
|
|
|
free(obj->data[i]); |
|
|
|
} |
|
|
|
free(obj->data); |
|
|
|
obj->data = NULL; |
|
|
|
obj->size = 0; |
|
|
|
} |
|
|
|
|
|
|
|
struct array_string_t array_string_split(const char *str, const char sep, array_string_t::flags flags = array_string_t::none) |
|
|
|
{ |
|
|
|
struct array_string_t result; |
|
|
|
result.size = 0; |
|
|
|
|
|
|
|
std::stringstream stream; |
|
|
|
stream << std::string(str); |
|
|
|
if (stream.str().find(sep) == std::string::npos) { |
|
|
|
result.data = (char**) calloc(1, sizeof(char*)); |
|
|
|
result.data[0] = (char*) calloc(JACK_CLIENT_NAME_SIZE + 1, sizeof(char)); |
|
|
|
result.size = 1; |
|
|
|
result.data.push_back((char*) calloc(JACK_CLIENT_NAME_SIZE + 1, sizeof(char))); |
|
|
|
strncpy(result.data[0], str, JACK_CLIENT_NAME_SIZE); |
|
|
|
result.data[0][JACK_CLIENT_NAME_SIZE] = '\0'; |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
std::string driver; |
|
|
|
std::vector<char*> drivers; |
|
|
|
while (std::getline(stream, driver, sep)) { |
|
|
|
driver.erase(std::remove_if(driver.begin(), driver.end(), isspace), driver.end()); |
|
|
|
if (std::find(drivers.begin(), drivers.end(), driver) != drivers.end() && (flags & array_string_t::discard_duplicate)) |
|
|
|
if (std::find(result.data.begin(), result.data.end(), driver) != result.data.end() && (flags & array_string_t::discard_duplicate)) |
|
|
|
continue; |
|
|
|
char *str = (char*) calloc(JACK_CLIENT_NAME_SIZE + 1, sizeof(char)); |
|
|
|
strncpy(str, driver.c_str(), JACK_CLIENT_NAME_SIZE); |
|
|
|
str[JACK_CLIENT_NAME_SIZE] = '\0'; |
|
|
|
drivers.push_back(str); |
|
|
|
result.data.push_back(str); |
|
|
|
} |
|
|
|
|
|
|
|
result.data = (char**) calloc(driver.size(), sizeof(char*)); |
|
|
|
result.size = drivers.size(); |
|
|
|
memcpy(result.data, drivers.data(), result.size * sizeof(char*)); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -1059,6 +1071,10 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke |
|
|
|
info.midi_name = strdup(param->value.str); |
|
|
|
break; |
|
|
|
|
|
|
|
case 'x': |
|
|
|
info.features |= param->value.i ? ALSA_DRIVER_FEAT_START_CLOSED : 0; |
|
|
|
break; |
|
|
|
|
|
|
|
case 'c': |
|
|
|
info.features |= param->value.i ? ALSA_DRIVER_FEAT_CLOSE_IDLE_DEVS : 0; |
|
|
|
break; |
|
|
|
@@ -1107,20 +1123,20 @@ SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLocke |
|
|
|
free(playback_channels_param); |
|
|
|
} |
|
|
|
|
|
|
|
info.devices_capture_size = capture_names.size; |
|
|
|
info.devices_playback_size = playback_names.size; |
|
|
|
info.devices_capture_size = capture_names.data.size(); |
|
|
|
info.devices_playback_size = playback_names.data.size(); |
|
|
|
info.devices = (alsa_device_info_t*) calloc(std::max(info.devices_capture_size, info.devices_playback_size), sizeof(alsa_device_info_t)); |
|
|
|
for (size_t i = 0; i < std::max(info.devices_capture_size, info.devices_playback_size); ++i) { |
|
|
|
if (i < capture_names.size) { |
|
|
|
if (i < capture_names.data.size()) { |
|
|
|
info.devices[i].capture_name = strdup(capture_names.data[i]); |
|
|
|
} |
|
|
|
if (i < capture_channels.size) { |
|
|
|
if (i < capture_channels.data.size()) { |
|
|
|
info.devices[i].capture_channels = atoi(capture_channels.data[i]); |
|
|
|
} |
|
|
|
if (i < playback_names.size) { |
|
|
|
if (i < playback_names.data.size()) { |
|
|
|
info.devices[i].playback_name = strdup(playback_names.data[i]); |
|
|
|
} |
|
|
|
if (i < playback_channels.size) { |
|
|
|
if (i < playback_channels.data.size()) { |
|
|
|
info.devices[i].playback_channels = atoi(playback_channels.data[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
|