@@ -20,12 +20,17 @@ Michael Voigt | |||
Torben Hohn | |||
Paul Davis | |||
Peter L Jones | |||
Devin Anderson | |||
Devin Anderson | |||
Josh Green | |||
--------------------------- | |||
Jackdmp changes log | |||
--------------------------- | |||
2009-12-08 Stephane Letz <letz@grame.fr> | |||
* Josh Green ALSA driver capture only patch. | |||
2009-12-03 Stephane Letz <letz@grame.fr> | |||
* Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). | |||
@@ -119,7 +119,7 @@ static void usage(FILE* file) | |||
" Available backends may include: portaudio, dummy or net.\n\n" | |||
#endif | |||
#ifdef __linux__ | |||
" Available backends may include: alsa, dummy, freebob, firewire, net, oss or sun.\n\n" | |||
" Available backends may include: alsa, dummy, freebob, firewire or net\n\n" | |||
#endif | |||
#if defined(__sun__) || defined(sun) | |||
" Available backends may include: boomer, oss, dummy or net.\n\n" | |||
@@ -283,8 +283,11 @@ jack_control_run_method( | |||
return true; | |||
not_started: | |||
jack_dbus_error (call, JACK_DBUS_ERROR_SERVER_NOT_RUNNING, | |||
"Can't execute method '%s' with stopped JACK server", call->method_name); | |||
jack_dbus_only_error( | |||
call, | |||
JACK_DBUS_ERROR_SERVER_NOT_RUNNING, | |||
"Can't execute method '%s' with stopped JACK server", | |||
call->method_name); | |||
exit: | |||
return true; | |||
@@ -281,6 +281,35 @@ jack_controller_patchbay_send_signal_ports_disconnected( | |||
DBUS_TYPE_INVALID); | |||
} | |||
void | |||
jack_controller_patchbay_send_signal_port_renamed( | |||
dbus_uint64_t new_graph_version, | |||
dbus_uint64_t client_id, | |||
const char * client_name, | |||
dbus_uint64_t port_id, | |||
const char * port_old_name, | |||
const char * port_new_name) | |||
{ | |||
jack_dbus_send_signal( | |||
JACK_CONTROLLER_OBJECT_PATH, | |||
JACK_DBUS_IFACE_NAME, | |||
"PortRenamed", | |||
DBUS_TYPE_UINT64, | |||
&new_graph_version, | |||
DBUS_TYPE_UINT64, | |||
&client_id, | |||
DBUS_TYPE_STRING, | |||
&client_name, | |||
DBUS_TYPE_UINT64, | |||
&port_id, | |||
DBUS_TYPE_STRING, | |||
&port_old_name, | |||
DBUS_TYPE_STRING, | |||
&port_new_name, | |||
DBUS_TYPE_INVALID); | |||
} | |||
static | |||
struct jack_graph_client * | |||
jack_controller_patchbay_find_client( | |||
@@ -1618,6 +1647,65 @@ jack_controller_port_connect_callback( | |||
} | |||
} | |||
int jack_controller_port_rename_callback(jack_port_id_t port, const char * old_name, const char * new_name, void * context) | |||
{ | |||
struct jack_graph_port * port_ptr; | |||
const char * port_new_short_name; | |||
const char * port_old_short_name; | |||
char * name_buffer; | |||
jack_info("port renamed: '%s' -> '%s'", old_name, new_name); | |||
port_new_short_name = strchr(new_name, ':'); | |||
if (port_new_short_name == NULL) | |||
{ | |||
jack_error("renamed port new name '%s' does not contain ':' separator char", new_name); | |||
return -1; | |||
} | |||
port_new_short_name++; /* skip ':' separator char */ | |||
port_old_short_name = strchr(old_name, ':'); | |||
if (port_old_short_name == NULL) | |||
{ | |||
jack_error("renamed port old name '%s' does not contain ':' separator char", old_name); | |||
return -1; | |||
} | |||
port_old_short_name++; /* skip ':' separator char */ | |||
port_ptr = jack_controller_patchbay_find_port_by_full_name(patchbay_ptr, old_name); | |||
if (port_ptr == NULL) | |||
{ | |||
jack_error("renamed port '%s' not found", old_name); | |||
return -1; | |||
} | |||
name_buffer = strdup(port_new_short_name); | |||
if (name_buffer == NULL) | |||
{ | |||
jack_error("strdup() call for port name '%s' failed.", port_new_short_name); | |||
return 1; | |||
} | |||
free(port_ptr->name); | |||
port_ptr->name = name_buffer; | |||
pthread_mutex_lock(&patchbay_ptr->lock); | |||
patchbay_ptr->graph.version++; | |||
jack_controller_patchbay_send_signal_port_renamed( | |||
patchbay_ptr->graph.version, | |||
port_ptr->client->id, | |||
port_ptr->client->name, | |||
port_ptr->id, | |||
port_old_short_name, | |||
port_ptr->name); | |||
jack_controller_patchbay_send_signal_graph_changed(patchbay_ptr->graph.version); | |||
pthread_mutex_unlock(&patchbay_ptr->lock); | |||
return 0; | |||
} | |||
#undef controller_ptr | |||
void | |||
@@ -1714,6 +1802,13 @@ jack_controller_patchbay_init( | |||
goto fail_uninit_mutex; | |||
} | |||
ret = jack_set_port_rename_callback(controller_ptr->client, jack_controller_port_rename_callback, controller_ptr); | |||
if (ret != 0) | |||
{ | |||
jack_error("jack_set_port_rename_callback() failed with error %d", ret); | |||
goto fail_uninit_mutex; | |||
} | |||
return true; | |||
fail_uninit_mutex: | |||
@@ -1838,6 +1933,15 @@ JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(PortsDisconnected) | |||
JACK_DBUS_SIGNAL_ARGUMENT("connection_id", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENTS_END | |||
JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(PortRenamed) | |||
JACK_DBUS_SIGNAL_ARGUMENT("new_graph_version", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("port_id", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("client_id", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("client_name", DBUS_TYPE_STRING_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("port_old_name", DBUS_TYPE_STRING_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("port_new_name", DBUS_TYPE_STRING_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENTS_END | |||
JACK_DBUS_SIGNALS_BEGIN | |||
JACK_DBUS_SIGNAL_DESCRIBE(GraphChanged) | |||
JACK_DBUS_SIGNAL_DESCRIBE(ClientAppeared) | |||
@@ -1846,6 +1950,7 @@ JACK_DBUS_SIGNALS_BEGIN | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortDisappeared) | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortsConnected) | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortsDisconnected) | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortRenamed) | |||
JACK_DBUS_SIGNALS_END | |||
JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_patchbay, JACK_DBUS_IFACE_NAME) | |||
@@ -765,6 +765,34 @@ jack_dbus_error( | |||
va_end(ap); | |||
} | |||
void | |||
jack_dbus_only_error( | |||
void *dbus_call_context_ptr, | |||
const char *error_name, | |||
const char *format, | |||
...) | |||
{ | |||
va_list ap; | |||
char buffer[300]; | |||
va_start(ap, format); | |||
vsnprintf(buffer, sizeof(buffer), format, ap); | |||
if (((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply != NULL) | |||
{ | |||
dbus_message_unref(((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply); | |||
((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = NULL; | |||
} | |||
((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error( | |||
((struct jack_dbus_method_call *)dbus_call_context_ptr)->message, | |||
error_name, | |||
buffer); | |||
va_end(ap); | |||
} | |||
int | |||
main (int argc, char **argv) | |||
{ | |||
@@ -257,6 +257,13 @@ jack_dbus_error( | |||
const char *format, | |||
...); | |||
void | |||
jack_dbus_only_error( | |||
void *dbus_call_context_ptr, | |||
const char *error_name, | |||
const char *format, | |||
...); | |||
bool | |||
jack_dbus_get_method_args( | |||
struct jack_dbus_method_call *call, | |||
@@ -263,102 +263,106 @@ JackAlsaDriver::alsa_driver_hw_specific (alsa_driver_t *driver, int hw_monitorin | |||
void | |||
JackAlsaDriver::alsa_driver_setup_io_function_pointers (alsa_driver_t *driver) | |||
{ | |||
if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { | |||
if (driver->playback_interleaved) { | |||
driver->channel_copy = memcpy_interleave_d32_s32; | |||
} else { | |||
driver->channel_copy = memcpy_fake; | |||
} | |||
driver->read_via_copy = sample_move_floatLE_sSs; | |||
driver->write_via_copy = sample_move_dS_floatLE; | |||
} else { | |||
switch (driver->playback_sample_bytes) { | |||
case 2: | |||
if (driver->playback_handle) { | |||
if (SND_PCM_FORMAT_FLOAT_LE == driver->playback_sample_format) { | |||
if (driver->playback_interleaved) { | |||
driver->channel_copy = memcpy_interleave_d16_s16; | |||
driver->channel_copy = memcpy_interleave_d32_s32; | |||
} else { | |||
driver->channel_copy = memcpy_fake; | |||
} | |||
driver->read_via_copy = sample_move_floatLE_sSs; | |||
driver->write_via_copy = sample_move_dS_floatLE; | |||
} else { | |||
switch (driver->playback_sample_bytes) { | |||
case 2: | |||
if (driver->playback_interleaved) { | |||
driver->channel_copy = memcpy_interleave_d16_s16; | |||
} else { | |||
driver->channel_copy = memcpy_fake; | |||
} | |||
switch (driver->dither) { | |||
case Rectangular: | |||
jack_info("Rectangular dithering at 16 bits"); | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_dither_rect_d16_sSs: | |||
sample_move_dither_rect_d16_sS; | |||
break; | |||
switch (driver->dither) { | |||
case Rectangular: | |||
jack_info("Rectangular dithering at 16 bits"); | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_dither_rect_d16_sSs: | |||
sample_move_dither_rect_d16_sS; | |||
break; | |||
case Triangular: | |||
jack_info("Triangular dithering at 16 bits"); | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_dither_tri_d16_sSs: | |||
sample_move_dither_tri_d16_sS; | |||
break; | |||
case Triangular: | |||
jack_info("Triangular dithering at 16 bits"); | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_dither_tri_d16_sSs: | |||
sample_move_dither_tri_d16_sS; | |||
break; | |||
case Shaped: | |||
jack_info("Noise-shaped dithering at 16 bits"); | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_dither_shaped_d16_sSs: | |||
sample_move_dither_shaped_d16_sS; | |||
break; | |||
case Shaped: | |||
jack_info("Noise-shaped dithering at 16 bits"); | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_dither_shaped_d16_sSs: | |||
sample_move_dither_shaped_d16_sS; | |||
break; | |||
default: | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_d16_sSs : | |||
sample_move_d16_sS; | |||
default: | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_d16_sSs : | |||
sample_move_d16_sS; | |||
break; | |||
} | |||
break; | |||
} | |||
break; | |||
case 3: /* NO DITHER */ | |||
if (driver->playback_interleaved) { | |||
driver->channel_copy = memcpy_interleave_d24_s24; | |||
} else { | |||
driver->channel_copy = memcpy_fake; | |||
} | |||
case 3: /* NO DITHER */ | |||
if (driver->playback_interleaved) { | |||
driver->channel_copy = memcpy_interleave_d24_s24; | |||
} else { | |||
driver->channel_copy = memcpy_fake; | |||
} | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_d24_sSs: | |||
sample_move_d24_sS; | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_d24_sSs: | |||
sample_move_d24_sS; | |||
break; | |||
break; | |||
case 4: /* NO DITHER */ | |||
if (driver->playback_interleaved) { | |||
driver->channel_copy = memcpy_interleave_d32_s32; | |||
} else { | |||
driver->channel_copy = memcpy_fake; | |||
} | |||
case 4: /* NO DITHER */ | |||
if (driver->playback_interleaved) { | |||
driver->channel_copy = memcpy_interleave_d32_s32; | |||
} else { | |||
driver->channel_copy = memcpy_fake; | |||
} | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_d32u24_sSs: | |||
sample_move_d32u24_sS; | |||
break; | |||
driver->write_via_copy = driver->quirk_bswap? | |||
sample_move_d32u24_sSs: | |||
sample_move_d32u24_sS; | |||
break; | |||
default: | |||
jack_error ("impossible sample width (%d) discovered!", | |||
driver->playback_sample_bytes); | |||
exit (1); | |||
default: | |||
jack_error ("impossible sample width (%d) discovered!", | |||
driver->playback_sample_bytes); | |||
exit (1); | |||
} | |||
} | |||
} | |||
switch (driver->capture_sample_bytes) { | |||
case 2: | |||
driver->read_via_copy = driver->quirk_bswap? | |||
sample_move_dS_s16s: | |||
sample_move_dS_s16; | |||
break; | |||
case 3: | |||
driver->read_via_copy = driver->quirk_bswap? | |||
sample_move_dS_s24s: | |||
sample_move_dS_s24; | |||
break; | |||
case 4: | |||
driver->read_via_copy = driver->quirk_bswap? | |||
sample_move_dS_s32u24s: | |||
sample_move_dS_s32u24; | |||
break; | |||
if (driver->capture_handle) { | |||
switch (driver->capture_sample_bytes) { | |||
case 2: | |||
driver->read_via_copy = driver->quirk_bswap? | |||
sample_move_dS_s16s: | |||
sample_move_dS_s16; | |||
break; | |||
case 3: | |||
driver->read_via_copy = driver->quirk_bswap? | |||
sample_move_dS_s24s: | |||
sample_move_dS_s24; | |||
break; | |||
case 4: | |||
driver->read_via_copy = driver->quirk_bswap? | |||
sample_move_dS_s32u24s: | |||
sample_move_dS_s32u24; | |||
break; | |||
} | |||
} | |||
} | |||
@@ -207,16 +207,21 @@ JackFFADODriver::ffado_driver_wait (ffado_driver_t *driver, int extra_fd, int *s | |||
} else if (response == ffado_wait_error) { | |||
// an error happened (unhandled xrun) | |||
// this should be fatal | |||
jack_error("JackFFADODriver::ffado_driver_wait - unhandled xrun"); | |||
*status = -1; | |||
return 0; | |||
} else if (response == ffado_wait_shutdown) { | |||
// ffado requested shutdown (e.g. device unplugged) | |||
// this should be fatal | |||
jack_error("JackFFADODriver::ffado_driver_wait - shutdown requested " | |||
"(device unplugged?)"); | |||
*status = -1; | |||
return 0; | |||
} else { | |||
// unknown response code. should be fatal | |||
// this should be fatal | |||
jack_error("JackFFADODriver::ffado_driver_wait - unexpected error " | |||
"code '%d' returned from 'ffado_streaming_wait'", response); | |||
*status = -1; | |||
return 0; | |||
} | |||