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