diff --git a/ChangeLog b/ChangeLog index 00471db2..4c2d8e8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,10 +3,10 @@ --------------------------- Dmitry Baikov +Gabriel M. Beddingfield Steven Chamberlain Thom Johansen Thibault LeMeur -Pieter Palmers Tom Szilagyi Andrzej Szombierski Kjetil S.Matheussen @@ -19,12 +19,75 @@ Romain Moret Florian Faber Michael Voigt Torben Hohn -Paul Davis +Paul Davis +Peter L Jones +Devin Anderson +Josh Green +Mario Lang --------------------------- Jackdmp changes log --------------------------- +2010-01-29 Gabriel M. Beddingfield + + * Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. + +2009-12-15 Stephane Letz + + * Shared memory manager was calling abort in case of fatal error, now return an error in caller. + +2009-12-13 Stephane Letz + + * Mario Lang alsa_io time calculation overflow patch. + +2009-12-10 Stephane Letz + + * Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. + +2009-12-09 Stephane Letz + + * When threads are cancelled, the exception has to be rethrown. + +2009-12-08 Stephane Letz + + * Josh Green ALSA driver capture only patch. + +2009-12-03 Stephane Letz + + * Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). + +2009-12-02 Stephane Letz + + * Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. + * Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). + * Check dynamic port-max value. + +2009-12-01 Stephane Letz + + * Fix port_rename callback : now both old name and new name are given as parameters. + +2009-11-30 Stephane Letz + + * Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). + +2009-11-29 Stephane Letz + + * More robust sample rate change handling code in JackCoreAudioDriver. + +2009-11-24 Stephane Letz + + * Dynamic choice of maximum port number. + +2009-11-23 Stephane Letz + + * Peter L Jones patch for NetJack1 compilation on Windows. + +2009-11-20 Stephane Letz + + * Version 1.9.5 started. + * Client debugging code improved. + 2009-11-18 Stephane Letz * Sync JackCoreAudioAdapter code with JackCoreAudioDriver. diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 97e58833..06408833 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -251,7 +251,7 @@ extern "C" static inline bool CheckPort(jack_port_id_t port_index) { - return (port_index > 0 && port_index < PORT_NUM); + return (port_index > 0 && port_index < PORT_NUM_MAX); } static inline bool CheckBufferSize(jack_nframes_t buffer_size) @@ -290,6 +290,9 @@ EXPORT void jack_set_info_function (print_function func) EXPORT jack_client_t* jack_client_new(const char* client_name) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_new"); +#endif try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); @@ -312,7 +315,7 @@ EXPORT jack_client_t* jack_client_new(const char* client_name) EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_buffer"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -332,7 +335,7 @@ EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames) EXPORT const char* jack_port_name(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_name"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -352,7 +355,7 @@ EXPORT const char* jack_port_name(const jack_port_t* port) EXPORT const char* jack_port_short_name(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_short_name"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -372,7 +375,7 @@ EXPORT const char* jack_port_short_name(const jack_port_t* port) EXPORT int jack_port_flags(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_flags"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -392,7 +395,7 @@ EXPORT int jack_port_flags(const jack_port_t* port) EXPORT const char* jack_port_type(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_type"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -412,7 +415,7 @@ EXPORT const char* jack_port_type(const jack_port_t* port) EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_type_id"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -432,7 +435,7 @@ EXPORT jack_port_type_id_t jack_port_type_id(const jack_port_t *port) EXPORT int jack_port_connected(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_connected"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -453,7 +456,7 @@ EXPORT int jack_port_connected(const jack_port_t* port) EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_connected_to"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -483,7 +486,7 @@ EXPORT int jack_port_connected_to(const jack_port_t* port, const char* port_name EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_tie"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t src_aux = (uint64_t)src; @@ -517,7 +520,7 @@ EXPORT int jack_port_tie(jack_port_t* src, jack_port_t* dst) EXPORT int jack_port_untie(jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_untie"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -537,7 +540,7 @@ EXPORT int jack_port_untie(jack_port_t* port) EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_latency"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -558,7 +561,7 @@ EXPORT jack_nframes_t jack_port_get_latency(jack_port_t* port) EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_set_latency"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -578,7 +581,7 @@ EXPORT void jack_port_set_latency(jack_port_t* port, jack_nframes_t frames) EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_recompute_total_latency"); #endif JackClient* client = (JackClient*)ext_client; @@ -604,7 +607,7 @@ EXPORT int jack_recompute_total_latency(jack_client_t* ext_client, jack_port_t* EXPORT int jack_recompute_total_latencies(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_recompute_total_latencies"); #endif JackClient* client = (JackClient*)ext_client; @@ -625,7 +628,7 @@ This is unsafe if case of concurrent access, and should be "serialized" doing a EXPORT int jack_port_set_name(jack_port_t* port, const char* name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_set_name"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -655,7 +658,7 @@ EXPORT int jack_port_set_name(jack_port_t* port, const char* name) EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_set_alias"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -678,7 +681,7 @@ EXPORT int jack_port_set_alias(jack_port_t* port, const char* name) EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_unset_alias"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -701,7 +704,7 @@ EXPORT int jack_port_unset_alias(jack_port_t* port, const char* name) EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2]) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_aliases"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -721,7 +724,7 @@ EXPORT int jack_port_get_aliases(const jack_port_t* port, char* const aliases[2] EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_request_monitor"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -741,7 +744,7 @@ EXPORT int jack_port_request_monitor(jack_port_t* port, int onoff) EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const char* port_name, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_request_monitor_by_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -764,7 +767,7 @@ EXPORT int jack_port_request_monitor_by_name(jack_client_t* ext_client, const ch EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_ensure_monitor"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -784,7 +787,7 @@ EXPORT int jack_port_ensure_monitor(jack_port_t* port, int onoff) EXPORT int jack_port_monitoring_input(jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_monitoring_input"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -804,7 +807,7 @@ EXPORT int jack_port_monitoring_input(jack_port_t* port) EXPORT int jack_is_realtime(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_is_realtime"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -819,7 +822,7 @@ EXPORT int jack_is_realtime(jack_client_t* ext_client) EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_on_shutdown"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -832,7 +835,7 @@ EXPORT void jack_on_shutdown(jack_client_t* ext_client, JackShutdownCallback cal EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_on_info_shutdown"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -845,7 +848,7 @@ EXPORT void jack_on_info_shutdown(jack_client_t* ext_client, JackInfoShutdownCal EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallback callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_process_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -859,7 +862,7 @@ EXPORT int jack_set_process_callback(jack_client_t* ext_client, JackProcessCallb EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_thread_wait"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -874,7 +877,7 @@ EXPORT jack_nframes_t jack_thread_wait(jack_client_t* ext_client, int status) EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_cycle_wait"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -888,7 +891,7 @@ EXPORT jack_nframes_t jack_cycle_wait(jack_client_t* ext_client) EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_cycle_signal"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -901,7 +904,7 @@ EXPORT void jack_cycle_signal(jack_client_t* ext_client, int status) EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback fun, void *arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_process_thread"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -915,7 +918,7 @@ EXPORT int jack_set_process_thread(jack_client_t* ext_client, JackThreadCallback EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelCallback freewheel_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_freewheel_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -929,7 +932,7 @@ EXPORT int jack_set_freewheel_callback(jack_client_t* ext_client, JackFreewheelC EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_freewheel"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -943,7 +946,7 @@ EXPORT int jack_set_freewheel(jack_client_t* ext_client, int onoff) EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer_size) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_buffer_size"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -959,7 +962,7 @@ EXPORT int jack_set_buffer_size(jack_client_t* ext_client, jack_nframes_t buffer EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSizeCallback bufsize_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_buffer_size_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -973,7 +976,7 @@ EXPORT int jack_set_buffer_size_callback(jack_client_t* ext_client, JackBufferSi EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRateCallback srate_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_sample_rate_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -987,7 +990,7 @@ EXPORT int jack_set_sample_rate_callback(jack_client_t* ext_client, JackSampleRa EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, JackClientRegistrationCallback registration_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_client_registration_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1001,7 +1004,7 @@ EXPORT int jack_set_client_registration_callback(jack_client_t* ext_client, Jack EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPortRegistrationCallback registration_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_port_registration_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1015,7 +1018,7 @@ EXPORT int jack_set_port_registration_callback(jack_client_t* ext_client, JackPo EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortConnectCallback portconnect_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_port_connect_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1029,7 +1032,7 @@ EXPORT int jack_set_port_connect_callback(jack_client_t* ext_client, JackPortCon EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRenameCallback rename_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_port_rename_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1043,7 +1046,7 @@ EXPORT int jack_set_port_rename_callback(jack_client_t* ext_client, JackPortRena EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrderCallback graph_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_graph_order_callback"); #endif JackClient* client = (JackClient*)ext_client; jack_log("jack_set_graph_order_callback ext_client %x client %x ", ext_client, client); @@ -1058,7 +1061,7 @@ EXPORT int jack_set_graph_order_callback(jack_client_t* ext_client, JackGraphOrd EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xrun_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_xrun_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1072,7 +1075,7 @@ EXPORT int jack_set_xrun_callback(jack_client_t* ext_client, JackXRunCallback xr EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadInitCallback init_callback, void *arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_thread_init_callback"); #endif JackClient* client = (JackClient*)ext_client; jack_log("jack_set_thread_init_callback ext_client %x client %x ", ext_client, client); @@ -1087,7 +1090,7 @@ EXPORT int jack_set_thread_init_callback(jack_client_t* ext_client, JackThreadIn EXPORT int jack_activate(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_activate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1101,7 +1104,7 @@ EXPORT int jack_activate(jack_client_t* ext_client) EXPORT int jack_deactivate(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_deactivate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1115,7 +1118,7 @@ EXPORT int jack_deactivate(jack_client_t* ext_client) EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_register"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1136,7 +1139,7 @@ EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* po EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_unregister"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1159,7 +1162,7 @@ EXPORT int jack_port_unregister(jack_client_t* ext_client, jack_port_t* port) EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_is_mine"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1182,7 +1185,7 @@ EXPORT int jack_port_is_mine(const jack_client_t* ext_client, const jack_port_t* EXPORT const char** jack_port_get_connections(const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_connections"); #endif #if defined(__x86_64__) || defined(__ppc64__) uint64_t port_aux = (uint64_t)port; @@ -1204,7 +1207,7 @@ EXPORT const char** jack_port_get_connections(const jack_port_t* port) EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_client, const jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_all_connections"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1231,7 +1234,7 @@ EXPORT const char** jack_port_get_all_connections(const jack_client_t* ext_clien EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jack_port_t* port) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_get_total_latency"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1263,7 +1266,7 @@ EXPORT jack_nframes_t jack_port_get_total_latency(jack_client_t* ext_client, jac EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* dst) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_connect"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1280,7 +1283,7 @@ EXPORT int jack_connect(jack_client_t* ext_client, const char* src, const char* EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const char* dst) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_disconnect"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1297,7 +1300,7 @@ EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const cha EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_disconnect"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1320,7 +1323,7 @@ EXPORT int jack_port_disconnect(jack_client_t* ext_client, jack_port_t* src) EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_sample_rate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1335,7 +1338,7 @@ EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* ext_client) EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_buffer_size"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1350,7 +1353,7 @@ EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* ext_client) EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_ports"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1364,7 +1367,7 @@ EXPORT const char** jack_get_ports(jack_client_t* ext_client, const char* port_n EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* portname) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_by_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1391,7 +1394,7 @@ EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* por EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_port_by_id"); #endif /* jack_port_t* type is actually the port index */ #if defined(__x86_64__) || defined(__ppc64__) @@ -1404,7 +1407,7 @@ EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_engine_takeover_timebase"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1419,7 +1422,7 @@ EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client) EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_frames_since_cycle_start"); #endif JackTimer timer; JackEngineControl* control = GetEngineControl(); @@ -1433,13 +1436,16 @@ EXPORT jack_nframes_t jack_frames_since_cycle_start(const jack_client_t* ext_cli EXPORT jack_time_t jack_get_time() { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_get_time"); +#endif return GetMicroSeconds(); } EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nframes_t frames) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_frames_to_time"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1460,7 +1466,7 @@ EXPORT jack_time_t jack_frames_to_time(const jack_client_t* ext_client, jack_nfr EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_time_t time) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_time_to_frames"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1480,13 +1486,16 @@ EXPORT jack_nframes_t jack_time_to_frames(const jack_client_t* ext_client, jack_ EXPORT jack_nframes_t jack_frame_time(const jack_client_t* ext_client) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_frame_time"); +#endif return jack_time_to_frames(ext_client, GetMicroSeconds()); } EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_last_frame_time"); #endif JackEngineControl* control = GetEngineControl(); return (control) ? control->fFrameTimer.ReadCurrentState()->CurFrame() : 0; @@ -1495,7 +1504,7 @@ EXPORT jack_nframes_t jack_last_frame_time(const jack_client_t* ext_client) EXPORT float jack_cpu_load(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_cpu_load"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1510,7 +1519,7 @@ EXPORT float jack_cpu_load(jack_client_t* ext_client) EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_client_thread_id"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1524,7 +1533,7 @@ EXPORT pthread_t jack_client_thread_id(jack_client_t* ext_client) EXPORT char* jack_get_client_name(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_client_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1554,7 +1563,7 @@ EXPORT int jack_port_type_size(void) EXPORT int jack_release_timebase(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_release_timebase"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1568,7 +1577,7 @@ EXPORT int jack_release_timebase(jack_client_t* ext_client) EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sync_callback, void *arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_sync_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1582,7 +1591,7 @@ EXPORT int jack_set_sync_callback(jack_client_t* ext_client, JackSyncCallback sy EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_sync_timeout"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1596,7 +1605,7 @@ EXPORT int jack_set_sync_timeout(jack_client_t* ext_client, jack_time_t timeout) EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional, JackTimebaseCallback timebase_callback, void* arg) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_set_timebase_callback"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1610,7 +1619,7 @@ EXPORT int jack_set_timebase_callback(jack_client_t* ext_client, int conditional EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_locate"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1625,7 +1634,7 @@ EXPORT int jack_transport_locate(jack_client_t* ext_client, jack_nframes_t frame EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_client, jack_position_t* pos) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_query"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1639,7 +1648,7 @@ EXPORT jack_transport_state_t jack_transport_query(const jack_client_t* ext_clie EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_current_transport_frame"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1653,7 +1662,7 @@ EXPORT jack_nframes_t jack_get_current_transport_frame(const jack_client_t* ext_ EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* pos) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_reposition"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1668,7 +1677,7 @@ EXPORT int jack_transport_reposition(jack_client_t* ext_client, jack_position_t* EXPORT void jack_transport_start(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_start"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1681,7 +1690,7 @@ EXPORT void jack_transport_start(jack_client_t* ext_client) EXPORT void jack_transport_stop(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_transport_stop"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1694,6 +1703,9 @@ EXPORT void jack_transport_stop(jack_client_t* ext_client) // deprecated EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_get_transport_info"); +#endif jack_error("jack_get_transport_info: deprecated"); if (tinfo) memset(tinfo, 0, sizeof(jack_transport_info_t)); @@ -1701,6 +1713,9 @@ EXPORT void jack_get_transport_info(jack_client_t* ext_client, jack_transport_in EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_info_t* tinfo) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_set_transport_info"); +#endif jack_error("jack_set_transport_info: deprecated"); if (tinfo) memset(tinfo, 0, sizeof(jack_transport_info_t)); @@ -1710,7 +1725,7 @@ EXPORT void jack_set_transport_info(jack_client_t* ext_client, jack_transport_in EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_max_delayed_usecs"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1725,7 +1740,7 @@ EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client) EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_xrun_delayed_usecs"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1740,7 +1755,7 @@ EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client) EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_reset_max_delayed_usecs"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1755,7 +1770,7 @@ EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) EXPORT int jack_client_real_time_priority(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_client_real_time_priority"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1770,7 +1785,7 @@ EXPORT int jack_client_real_time_priority(jack_client_t* ext_client) EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_client_max_real_time_priority"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1795,6 +1810,9 @@ EXPORT int jack_client_create_thread(jack_client_t* client, thread_routine routine, void *arg) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_create_thread"); +#endif return JackThread::StartImp(thread, priority, realtime, routine, arg); } @@ -1805,11 +1823,17 @@ EXPORT int jack_drop_real_time_scheduling(pthread_t thread) EXPORT int jack_client_stop_thread(jack_client_t* client, pthread_t thread) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_stop_thread"); +#endif return JackThread::StopImp(thread); } EXPORT int jack_client_kill_thread(jack_client_t* client, pthread_t thread) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_kill_thread"); +#endif return JackThread::KillImp(thread); } @@ -1837,7 +1861,7 @@ EXPORT void jack_internal_client_close (const char *client_name) EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intclient_t intclient) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_get_internal_client_name"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1854,7 +1878,7 @@ EXPORT char* jack_get_internal_client_name(jack_client_t* ext_client, jack_intcl EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, const char* client_name, jack_status_t* status) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_internal_client_handle"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1872,7 +1896,7 @@ EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, c EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client, const char* client_name, jack_options_t options, jack_status_t* status, va_list ap) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_internal_client_load_aux"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { @@ -1911,7 +1935,7 @@ EXPORT jack_intclient_t jack_internal_client_load(jack_client_t *client, const c EXPORT jack_status_t jack_internal_client_unload(jack_client_t* ext_client, jack_intclient_t intclient) { #ifdef __CLIENTDEBUG__ - JackLibGlobals::CheckContext(); + JackGlobals::CheckContext("jack_internal_client_load"); #endif JackClient* client = (JackClient*)ext_client; if (client == NULL) { diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index a347ca12..f765d032 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -17,10 +17,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "JackAudioAdapter.h" #ifdef __APPLE__ #include #endif + +#include "JackAudioAdapter.h" #ifndef TARGET_OS_IPHONE #include "JackLibSampleRateResampler.h" #endif @@ -73,8 +74,8 @@ namespace Jack fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'AdapterTiming1.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fprintf(file, "set output 'AdapterTiming1.svg\n"); + fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); @@ -85,8 +86,10 @@ namespace Jack fprintf(file, "plot "); sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines\n"); fprintf(file, buffer); + fprintf(file, "unset multiplot\n"); + fprintf(file, "unset output\n"); fclose(file); @@ -105,8 +108,8 @@ namespace Jack fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'AdapterTiming2.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fprintf(file, "set output 'AdapterTiming2.svg\n"); + fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); @@ -117,8 +120,10 @@ namespace Jack fprintf(file, "plot "); sprintf(buffer, "\"JackAudioAdapter.log\" using 4 title \"Ratio 1\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 5 title \"Ratio 2\" with lines\n"); fprintf(file, buffer); + fprintf(file, "unset multiplot\n"); + fprintf(file, "unset output\n"); fclose(file); @@ -137,8 +142,8 @@ namespace Jack fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'AdapterTiming3.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fprintf(file, "set output 'AdapterTiming3.svg\n"); + fprintf(file, "set terminal svg\n"); fprintf(file, "set multiplot\n"); fprintf(file, "set grid\n"); @@ -149,8 +154,10 @@ namespace Jack fprintf(file, "plot "); sprintf(buffer, "\"JackAudioAdapter.log\" using 6 title \"Frames position in consumer ringbuffer\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 7 title \"Frames position in producer ringbuffer\" with lines\n"); fprintf(file, buffer); + fprintf(file, "unset multiplot\n"); + fprintf(file, "unset output\n"); fclose(file); } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index e6469267..d4359f83 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -254,7 +254,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, case kPortRenameCallback: jack_log("JackClient::kPortRenameCallback port = %ld"); if (fPortRename) { - fPortRename(value1, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); + fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg); } break; @@ -848,6 +848,8 @@ int JackClient::SetInitCallback(JackThreadInitCallback callback, void *arg) } else { fInitArg = arg; fInit = callback; + /* make sure that the message buffer thread is initialized too */ + JackMessageBuffer::fInstance->SetInitCallback(callback, arg); return 0; } } diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index 043b0c81..f6a74dca 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -33,7 +33,7 @@ JackConnectionManager::JackConnectionManager() int i; jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager)); - for (i = 0; i < PORT_NUM; i++) { + for (i = 0; i < PORT_NUM_MAX; i++) { fConnection[i].Init(); } diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index 47543038..5d5b8c62 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -353,11 +353,21 @@ struct JackClientTiming jack_time_t fFinishedAt; jack_client_state_t fStatus; - JackClientTiming(): fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered) - {} + JackClientTiming() + { + Init(); + } ~JackClientTiming() {} + void Init() + { + fSignaledAt = 0; + fAwakeAt = 0; + fFinishedAt = 0; + fStatus = NotTriggered; + } + } POST_PACKED_STRUCTURE; /*! @@ -379,7 +389,7 @@ class SERVER_EXPORT JackConnectionManager private: - JackFixedArray fConnection[PORT_NUM]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */ + JackFixedArray fConnection[PORT_NUM_MAX]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */ JackFixedArray1 fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */ JackFixedArray fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */ JackFixedMatrix fConnectionRef; /*! Table of port connections by (refnum , refnum) */ diff --git a/common/JackConstants.h b/common/JackConstants.h index aa6e0ce5..60a631c3 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -24,7 +24,7 @@ #include "config.h" #endif -#define VERSION "1.9.4" +#define VERSION "1.9.5" #define BUFFER_SIZE_MAX 8192 @@ -38,6 +38,8 @@ #define PORT_NUM 2048 #endif +#define PORT_NUM_MAX 4096 // The "max" value for ports used in connection manager, although port number in graph manager is dynamic + #define DRIVER_PORT_NUM 256 #ifndef PORT_NUM_FOR_CLIENT diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index 37eeb88a..f4850207 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -82,7 +82,11 @@ struct jackctl_server /* uint32_t, clock source type */ union jackctl_parameter_value clock_source; union jackctl_parameter_value default_clock_source; - + + /* uint32_t, max port number */ + union jackctl_parameter_value port_max; + union jackctl_parameter_value default_port_max; + /* bool */ union jackctl_parameter_value replace_registry; union jackctl_parameter_value default_replace_registry; @@ -741,6 +745,20 @@ EXPORT jackctl_server_t * jackctl_server_create( { goto fail_free_parameters; } + + value.ui = PORT_NUM; + if (jackctl_add_parameter( + &server_ptr->parameters, + "port-max", + "Maximum number of ports.", + "", + JackParamUInt, + &server_ptr->port_max, + &server_ptr->default_port_max, + value) == NULL) + { + goto fail_free_parameters; + } value.b = false; if (jackctl_add_parameter( @@ -864,15 +882,21 @@ jackctl_server_start( if (!server_ptr->realtime.b && server_ptr->client_timeout.i == 0) server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ + + /* check port max value before allocating server */ + if (server_ptr->port_max.ui > PORT_NUM_MAX) { + jack_error("JACK server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); + goto fail; + } /* get the engine/driver started */ - server_ptr->engine = new JackServer( server_ptr->sync.b, server_ptr->temporary.b, server_ptr->client_timeout.i, server_ptr->realtime.b, server_ptr->realtime_priority.i, + server_ptr->port_max.ui, server_ptr->verbose.b, (jack_timer_type_t)server_ptr->clock_source.ui, server_ptr->name.str); diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index a2a61d8d..6a90fcdc 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackDebugClient.h" #include "JackEngineControl.h" +#include "JackException.h" #include "JackError.h" #include "JackTime.h" #include @@ -55,9 +56,9 @@ JackDebugClient::~JackDebugClient() *fStream << setw(5) << "- Total number of instantiated port : " << fTotalPortNumber << endl; *fStream << setw(5) << "- Number of port remaining open when exiting client : " << fOpenPortNumber << endl; if (fOpenPortNumber != 0) - *fStream << "!!! WARNING !!! Some ports have not been unregistrated ! Incorrect exiting !" << endl; + *fStream << "!!! WARNING !!! Some ports have not been unregistered ! Incorrect exiting !" << endl; if (fIsDeactivated != fIsActivated) - *fStream << "!!! ERROR !!! Client seem do not perform symetric activation-deactivation ! (not the same number of activate and deactivate)" << endl; + *fStream << "!!! ERROR !!! Client seem to not perform symetric activation-deactivation ! (not the same number of activate and deactivate)" << endl; if (fIsClosed == 0) *fStream << "!!! ERROR !!! Client have not been closed with jack_client_close() !" << endl; @@ -68,9 +69,9 @@ JackDebugClient::~JackDebugClient() *fStream << setw(5) << "- Name : " << fPortList[i].name << endl; *fStream << setw(5) << "- idport : " << fPortList[i].idport << endl; *fStream << setw(5) << "- IsConnected : " << fPortList[i].IsConnected << endl; - *fStream << setw(5) << "- IsUnregistrated : " << fPortList[i].IsUnregistrated << endl; - if (fPortList[i].IsUnregistrated == 0) - *fStream << "!!! WARNING !!! Port have not been unregistrated ! Incorrect exiting !" << endl; + *fStream << setw(5) << "- IsUnregistered : " << fPortList[i].IsUnregistered << endl; + if (fPortList[i].IsUnregistered == 0) + *fStream << "!!! WARNING !!! Port have not been unregistered ! Incorrect exiting !" << endl; } *fStream << "delete object JackDebugClient : end of tracing" << endl; delete fStream; @@ -106,33 +107,39 @@ int JackDebugClient::Open(const char* server_name, const char* name, jack_option int JackDebugClient::Close() { - fIsClosed++; *fStream << "Client '" << fClientName << "' was closed" << endl; - return fClient->Close(); + int res = fClient->Close(); + fIsClosed++; + return res; } -void JackDebugClient::CheckClient() const +void JackDebugClient::CheckClient(const char* function_name) const { + *fStream << "CheckClient : " << function_name << ", calling thread : " << pthread_self() << endl; + if (fIsClosed > 0) { - *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed !" << endl; + *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl; *fStream << "This is likely to cause crash !'" << endl; + #ifdef __APPLE__ + // Debugger(); + #endif } } pthread_t JackDebugClient::GetThreadID() { - CheckClient(); + CheckClient("GetThreadID"); return fClient->GetThreadID(); } JackGraphManager* JackDebugClient::GetGraphManager() const { - CheckClient(); + CheckClient("GetGraphManager"); return fClient->GetGraphManager(); } JackEngineControl* JackDebugClient::GetEngineControl() const { - CheckClient(); + CheckClient("GetEngineControl"); return fClient->GetEngineControl(); } /*! @@ -141,13 +148,13 @@ JackEngineControl* JackDebugClient::GetEngineControl() const int JackDebugClient::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) { - CheckClient(); + CheckClient("ClientNotify"); return fClient->ClientNotify( refnum, name, notify, sync, message, value1, value2); } int JackDebugClient::Activate() { - CheckClient(); + CheckClient("Activate"); int res = fClient->Activate(); fIsActivated++; if (fIsDeactivated) @@ -160,7 +167,7 @@ int JackDebugClient::Activate() int JackDebugClient::Deactivate() { - CheckClient(); + CheckClient("Deactivate"); int res = fClient->Deactivate(); fIsDeactivated++; if (fIsActivated == 0) @@ -177,7 +184,7 @@ int JackDebugClient::Deactivate() int JackDebugClient::PortRegister(const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size) { - CheckClient(); + CheckClient("PortRegister"); int res = fClient->PortRegister(port_name, port_type, flags, buffer_size); if (res <= 0) { *fStream << "Client '" << fClientName << "' try port register ('" << port_name << "') and server return error " << res << " ." << endl; @@ -186,7 +193,7 @@ int JackDebugClient::PortRegister(const char* port_name, const char* port_type, fPortList[fTotalPortNumber].idport = res; strcpy(fPortList[fTotalPortNumber].name, port_name); fPortList[fTotalPortNumber].IsConnected = 0; - fPortList[fTotalPortNumber].IsUnregistrated = 0; + fPortList[fTotalPortNumber].IsUnregistered = 0; } else { *fStream << "!!! WARNING !!! History is full : no more port history will be recorded." << endl; } @@ -199,42 +206,42 @@ int JackDebugClient::PortRegister(const char* port_name, const char* port_type, int JackDebugClient::PortUnRegister(jack_port_id_t port_index) { - CheckClient(); + CheckClient("PortUnRegister"); int res = fClient->PortUnRegister(port_index); fOpenPortNumber--; int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (fPortList[i].idport == port_index) { // We found the last record - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : '" << fClientName << "' id deregistering port '" << fPortList[i].name << "' that have already been unregistered !" << endl; - fPortList[i].IsUnregistrated++; + fPortList[i].IsUnregistered++; break; } } if (i == 0) // Port is not found *fStream << "JackClientDebug : PortUnregister : port " << port_index << " was not previously registered !" << endl; if (res != 0) - *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << " )." << endl; + *fStream << "Client '" << fClientName << "' try to do PortUnregister and server return " << res << endl; *fStream << "Client '" << fClientName << "' unregister port '" << port_index << "'." << endl; return res; } int JackDebugClient::PortConnect(const char* src, const char* dst) { - CheckClient(); + CheckClient("PortConnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! Trying to connect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl; int i; int res = fClient->PortConnect( src, dst); for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (strcmp(fPortList[i].name, src) == 0) { // We found the last record in sources - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! Connecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected++; *fStream << "Connecting port " << src << " to " << dst << ". "; break; } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! Connecting port " << dst << " previoulsy unregistered !" << endl; fPortList[i].IsConnected++; *fStream << "Connecting port " << src << " to " << dst << ". "; @@ -251,20 +258,20 @@ int JackDebugClient::PortConnect(const char* src, const char* dst) int JackDebugClient::PortDisconnect(const char* src, const char* dst) { - CheckClient(); + CheckClient("PortDisconnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! Trying to disconnect a port ( " << src << " to " << dst << ") while the client has not been activated !" << endl; int res = fClient->PortDisconnect( src, dst); int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (strcmp(fPortList[i].name, src) == 0) { // We found the record in sources - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "disconnecting port " << src << ". "; break; } else if (strcmp(fPortList[i].name, dst) == 0 ) { // We found the record in dest - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disonnecting port " << dst << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "disconnecting port " << dst << ". "; @@ -281,14 +288,14 @@ int JackDebugClient::PortDisconnect(const char* src, const char* dst) int JackDebugClient::PortDisconnect(jack_port_id_t src) { - CheckClient(); + CheckClient("PortDisconnect"); if (!fIsActivated) *fStream << "!!! ERROR !!! : Trying to disconnect port " << src << " while that client has not been activated !" << endl; int res = fClient->PortDisconnect(src); int i; for (i = (fTotalPortNumber - 1); i >= 0; i--) { // We search the record into the history if (fPortList[i].idport == src) { // We found the record in sources - if (fPortList[i].IsUnregistrated != 0) + if (fPortList[i].IsUnregistered != 0) *fStream << "!!! ERROR !!! : Disconnecting port " << src << " previoulsy unregistered !" << endl; fPortList[i].IsConnected--; *fStream << "Disconnecting port " << src << ". " << endl; @@ -305,7 +312,7 @@ int JackDebugClient::PortDisconnect(jack_port_id_t src) int JackDebugClient::PortIsMine(jack_port_id_t port_index) { - CheckClient(); + CheckClient("PortIsMine"); return fClient->PortIsMine(port_index); } @@ -315,13 +322,13 @@ int JackDebugClient::PortIsMine(jack_port_id_t port_index) int JackDebugClient::SetBufferSize(jack_nframes_t buffer_size) { - CheckClient(); + CheckClient("SetBufferSize"); return fClient->SetBufferSize(buffer_size); } int JackDebugClient::SetFreeWheel(int onoff) { - CheckClient(); + CheckClient("SetFreeWheel"); if (onoff && fFreewheel) *fStream << "!!! ERROR !!! : Freewheel setup seems incorrect : set = ON while FW is already ON " << endl; if (!onoff && !fFreewheel) @@ -348,61 +355,61 @@ void JackDebugClient::ShutDown() int JackDebugClient::ReleaseTimebase() { - CheckClient(); + CheckClient("ReleaseTimebase"); return fClient->ReleaseTimebase(); } int JackDebugClient::SetSyncCallback(JackSyncCallback sync_callback, void* arg) { - CheckClient(); + CheckClient("SetSyncCallback"); return fClient->SetSyncCallback(sync_callback, arg); } int JackDebugClient::SetSyncTimeout(jack_time_t timeout) { - CheckClient(); + CheckClient("SetSyncTimeout"); return fClient->SetSyncTimeout(timeout); } int JackDebugClient::SetTimebaseCallback(int conditional, JackTimebaseCallback timebase_callback, void* arg) { - CheckClient(); + CheckClient("SetTimebaseCallback"); return fClient->SetTimebaseCallback( conditional, timebase_callback, arg); } void JackDebugClient::TransportLocate(jack_nframes_t frame) { - CheckClient(); + CheckClient("TransportLocate"); fClient->TransportLocate(frame); } jack_transport_state_t JackDebugClient::TransportQuery(jack_position_t* pos) { - CheckClient(); + CheckClient("TransportQuery"); return fClient->TransportQuery(pos); } jack_nframes_t JackDebugClient::GetCurrentTransportFrame() { - CheckClient(); + CheckClient("GetCurrentTransportFrame"); return fClient->GetCurrentTransportFrame(); } int JackDebugClient::TransportReposition(jack_position_t* pos) { - CheckClient(); + CheckClient("TransportReposition"); return fClient->TransportReposition(pos); } void JackDebugClient::TransportStart() { - CheckClient(); + CheckClient("TransportStart"); fClient->TransportStart(); } void JackDebugClient::TransportStop() { - CheckClient(); + CheckClient("TransportStop"); fClient->TransportStop(); } @@ -412,13 +419,13 @@ void JackDebugClient::TransportStop() void JackDebugClient::OnShutdown(JackShutdownCallback callback, void *arg) { - CheckClient(); + CheckClient("OnShutdown"); fClient->OnShutdown(callback, arg); } void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *arg) { - CheckClient(); + CheckClient("OnInfoShutdown"); fClient->OnInfoShutdown(callback, arg); } @@ -427,16 +434,18 @@ int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg) JackDebugClient* client = (JackDebugClient*)arg; jack_time_t t1 = GetMicroSeconds(); int res = client->fProcessTimeCallback(nframes, client->fProcessTimeCallbackArg); + if (res == 0) { jack_time_t t2 = GetMicroSeconds(); - long delta = long((t2 - t1) - client->GetEngineControl()->fPeriodUsecs); - if (delta > 0 && !client->fFreewheel) - *client->fStream << "!!! ERROR !!! : Process overload of " << delta << " us" << endl; + long delta = long((t2 - t1) - client->GetEngineControl()->fPeriodUsecs); + if (delta > 0 && !client->fFreewheel) + *client->fStream << "!!! ERROR !!! : Process overload of " << delta << " us" << endl; + } return res; } int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg) { - CheckClient(); + CheckClient("SetProcessCallback"); fProcessTimeCallback = callback; fProcessTimeCallbackArg = arg; return fClient->SetProcessCallback(TimeCallback, this); @@ -444,86 +453,86 @@ int JackDebugClient::SetProcessCallback(JackProcessCallback callback, void *arg) int JackDebugClient::SetXRunCallback(JackXRunCallback callback, void *arg) { - CheckClient(); + CheckClient("SetXRunCallback"); return fClient->SetXRunCallback(callback, arg); } int JackDebugClient::SetInitCallback(JackThreadInitCallback callback, void *arg) { - CheckClient(); + CheckClient("SetInitCallback"); return fClient->SetInitCallback(callback, arg); } int JackDebugClient::SetGraphOrderCallback(JackGraphOrderCallback callback, void *arg) { - CheckClient(); + CheckClient("SetGraphOrderCallback"); return fClient->SetGraphOrderCallback(callback, arg); } int JackDebugClient::SetBufferSizeCallback(JackBufferSizeCallback callback, void *arg) { - CheckClient(); + CheckClient("SetBufferSizeCallback"); return fClient->SetBufferSizeCallback(callback, arg); } int JackDebugClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback, void* arg) { - CheckClient(); + CheckClient("SetClientRegistrationCallback"); return fClient->SetClientRegistrationCallback(callback, arg); } int JackDebugClient::SetFreewheelCallback(JackFreewheelCallback callback, void *arg) { - CheckClient(); + CheckClient("SetFreewheelCallback"); return fClient->SetFreewheelCallback(callback, arg); } int JackDebugClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback, void *arg) { - CheckClient(); + CheckClient("SetPortRegistrationCallback"); return fClient->SetPortRegistrationCallback(callback, arg); } int JackDebugClient::SetPortConnectCallback(JackPortConnectCallback callback, void *arg) { - CheckClient(); + CheckClient("SetPortConnectCallback"); return fClient->SetPortConnectCallback(callback, arg); } int JackDebugClient::SetPortRenameCallback(JackPortRenameCallback callback, void *arg) { - CheckClient(); + CheckClient("SetPortRenameCallback"); return fClient->SetPortRenameCallback(callback, arg); } JackClientControl* JackDebugClient::GetClientControl() const { - CheckClient(); + CheckClient("GetClientControl"); return fClient->GetClientControl(); } // Internal clients char* JackDebugClient::GetInternalClientName(int ref) { - CheckClient(); + CheckClient("GetInternalClientName"); return fClient->GetInternalClientName(ref); } int JackDebugClient::InternalClientHandle(const char* client_name, jack_status_t* status) { - CheckClient(); + CheckClient("InternalClientHandle"); return fClient->InternalClientHandle(client_name, status); } int JackDebugClient::InternalClientLoad(const char* client_name, jack_options_t options, jack_status_t* status, jack_varargs_t* va) { - CheckClient(); + CheckClient("InternalClientLoad"); return fClient->InternalClientLoad(client_name, options, status, va); } void JackDebugClient::InternalClientUnload(int ref, jack_status_t* status) { - CheckClient(); + CheckClient("InternalClientUnload"); fClient->InternalClientUnload(ref, status); } diff --git a/common/JackDebugClient.h b/common/JackDebugClient.h index 0bb21b20..6a31f432 100644 --- a/common/JackDebugClient.h +++ b/common/JackDebugClient.h @@ -38,7 +38,7 @@ typedef struct jack_port_id_t idport; char name[JACK_PORT_NAME_SIZE]; //portname int IsConnected; - int IsUnregistrated; + int IsUnregistered; } PortFollower; @@ -129,7 +129,7 @@ class JackDebugClient : public JackClient void InternalClientUnload(int ref, jack_status_t* status); JackClientControl* GetClientControl() const; - void CheckClient() const; + void CheckClient(const char* function_name) const; static int TimeCallback(jack_nframes_t nframes, void *arg); }; diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index bab5db0f..a485d810 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -167,7 +167,7 @@ int JackDriver::Open(jack_nframes_t buffer_size, int JackDriver::Close() { - if (fClientControl.fRefNum > 0) { + if (fClientControl.fRefNum >= 0) { jack_log("JackDriver::Close"); fGraphManager->DirectDisconnect(fClientControl.fRefNum, fClientControl.fRefNum); // Disconnect driver from itself for sync fClientControl.fActive = false; diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 537c4160..fabebb01 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -89,6 +89,11 @@ int JackEngine::Close() return 0; } + +void JackEngine::NotifyQuit() +{ + fChannel.NotifyQuit(); +} //----------------------------- // Client ressource management @@ -322,9 +327,9 @@ void JackEngine::NotifyPortRegistation(jack_port_id_t port_index, bool onoff) NotifyClients((onoff ? kPortRegistrationOnCallback : kPortRegistrationOffCallback), false, "", port_index, 0); } -void JackEngine::NotifyPortRename(jack_port_id_t port) +void JackEngine::NotifyPortRename(jack_port_id_t port, const char* old_name) { - NotifyClients(kPortRenameCallback, false, "", port, 0); + NotifyClients(kPortRenameCallback, false, old_name, port, 0); } void JackEngine::NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) @@ -846,8 +851,10 @@ int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t ds int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) { AssertRefnum(refnum); + char old_name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; + strcpy(old_name, fGraphManager->GetPort(port)->GetName()); fGraphManager->GetPort(port)->SetName(name); - NotifyPortRename(port); + NotifyPortRename(port, old_name); return 0; } diff --git a/common/JackEngine.h b/common/JackEngine.h index 8212daf9..3a4a24a9 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -69,7 +69,7 @@ class SERVER_EXPORT JackEngine void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); - void NotifyPortRename(jack_port_id_t src); + void NotifyPortRename(jack_port_id_t src, const char* old_name); void NotifyActivate(int refnum); public: @@ -79,7 +79,7 @@ class SERVER_EXPORT JackEngine int Open(); int Close(); - + // Client management int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status); int ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); @@ -122,6 +122,7 @@ class SERVER_EXPORT JackEngine void NotifyBufferSize(jack_nframes_t buffer_size); void NotifySampleRate(jack_nframes_t sample_rate); void NotifyFreewheel(bool onoff); + void NotifyQuit(); }; diff --git a/common/JackEngineProfiling.cpp b/common/JackEngineProfiling.cpp index b0a1b441..4557fec9 100644 --- a/common/JackEngineProfiling.cpp +++ b/common/JackEngineProfiling.cpp @@ -25,6 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackGlobals.h" #include "JackTime.h" +#include +#include + namespace Jack { @@ -38,12 +41,10 @@ JackEngineProfiling::JackEngineProfiling():fAudioCycle(0),fMeasuredClient(0) JackEngineProfiling::~JackEngineProfiling() { - FILE* file = fopen("JackEngineProfiling.log", "w"); - char buffer[1024]; - + std::ofstream fStream("JackEngineProfiling.log", std::ios_base::ate); jack_info("Write server and clients timing data..."); - if (file == NULL) { + if (!fStream.is_open()) { jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file"); } else { @@ -58,7 +59,7 @@ JackEngineProfiling::~JackEngineProfiling() continue; // Skip non valid cycles // Print driver delta and end cycle - fprintf(file, "%ld \t %ld \t", d1, d2); + fStream << d1 << "\t" << d2 << "\t"; // For each measured client for (unsigned int j = 0; j < fMeasuredClient; j++) { @@ -71,222 +72,261 @@ JackEngineProfiling::~JackEngineProfiling() long d5 = long(fProfileTable[i].fClientTable[ref].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin); long d6 = long(fProfileTable[i].fClientTable[ref].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin); long d7 = long(fProfileTable[i].fClientTable[ref].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin); - - // Print ref, signal, start, end, scheduling, duration, status - fprintf(file, "%d \t %ld \t %ld \t %ld \t %ld \t %ld \t %d \t", - ref, - ((d5 > 0) ? d5 : 0), - ((d6 > 0) ? d6 : 0), - ((d7 > 0) ? d7 : 0), - ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0), - ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0), - fProfileTable[i].fClientTable[ref].fStatus); - } else { // Print tabs - fprintf(file, "\t \t \t \t \t \t \t"); + + fStream << ref << "\t" ; + fStream << ((d5 > 0) ? d5 : 0) << "\t"; + fStream << ((d6 > 0) ? d6 : 0) << "\t" ; + fStream << ((d7 > 0) ? d7 : 0) << "\t"; + fStream << ((d6 > 0 && d5 > 0) ? (d6 - d5) : 0) << "\t" ; + fStream << ((d7 > 0 && d6 > 0) ? (d7 - d6) : 0) << "\t" ; + fStream << fProfileTable[i].fClientTable[ref].fStatus << "\t" ;; + + } else { // Print tabs + fStream << "\t \t \t \t \t \t \t"; } } // Terminate line - fprintf(file, "\n"); + fStream << std::endl; } } // Driver period - file = fopen("Timing1.plot", "w"); - - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing1.log file"); + std::ofstream fStream1("Timing1.plot", std::ios_base::ate); + + if (!fStream1.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing1.plot file"); } else { - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Audio driver timing\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"); - - fprintf(file, "set output 'Timing1.pdf\n"); - fprintf(file, "set terminal pdf\n"); - - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Audio driver timing\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"); - - fclose(file); + fStream1 << "set grid\n"; + fStream1 << "set title \"Audio driver timing\"\n"; + fStream1 << "set xlabel \"audio cycles\"\n"; + fStream1 << "set ylabel \"usec\"\n"; + fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; + + fStream1 << "set output 'Timing1.svg\n"; + fStream1 << "set terminal svg\n"; + + fStream1 << "set grid\n"; + fStream1 << "set title \"Audio driver timing\"\n"; + fStream1 << "set xlabel \"audio cycles\"\n"; + fStream1 << "set ylabel \"usec\"\n"; + fStream1 << "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n"; + fStream1 << "unset output\n"; } // Driver end date - file = fopen("Timing2.plot", "w"); - - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing2.log file"); + std::ofstream fStream2("Timing2.plot", std::ios_base::ate); + + if (!fStream2.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing2.plot file"); } else { - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Driver end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"); + fStream2 << "set grid\n"; + fStream2 << "set title \"Driver end date\"\n"; + fStream2 << "set xlabel \"audio cycles\"\n"; + fStream2 << "set ylabel \"usec\"\n"; + fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; - fprintf(file, "set output 'Timing2.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream2 << "set output 'Timing2.svg\n"; + fStream2 << "set terminal svg\n"; - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Driver end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"); - - fclose(file); + fStream2 << "set grid\n"; + fStream2 << "set title \"Driver end date\"\n"; + fStream2 << "set xlabel \"audio cycles\"\n"; + fStream2 << "set ylabel \"usec\"\n"; + fStream2 << "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n"; + fStream2 << "unset output\n"; } // Clients end date if (fMeasuredClient > 0) { - file = fopen("Timing3.plot", "w"); - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing3.log file"); + std::ofstream fStream3("Timing3.plot", std::ios_base::ate); + + if (!fStream3.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing3.plot file"); } else { - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream3 << "set multiplot\n"; + fStream3 << "set grid\n"; + fStream3 << "set title \"Clients end date\"\n"; + fStream3 << "set xlabel \"audio cycles\"\n"; + fStream3 << "set ylabel \"usec\"\n"; + fStream3 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { if (i + 1 == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); - } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines"; + } else { + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines,"; } } else if (i + 1 == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } - fprintf(file, buffer); } - fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'Timing3.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream3 << "\n unset multiplot\n"; + fStream3 << "set output 'Timing3.svg\n"; + fStream3 << "set terminal svg\n"; - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients end date\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream3 << "set multiplot\n"; + fStream3 << "set grid\n"; + fStream3 << "set title \"Clients end date\"\n"; + fStream3 << "set xlabel \"audio cycles\"\n"; + fStream3 << "set ylabel \"usec\"\n"; + fStream3 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { if (i == 0) { if ((i + 1) == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines"; } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", - ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using "; + fStream3 << ((i + 1) * 7) - 1; + fStream3 << " title \"" << fIntervalTable[i].fName << "\"with lines,"; } } else if ((i + 1) == fMeasuredClient) { // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; } else { - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, fIntervalTable[i].fName); + fStream3 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) - 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; } - fprintf(file, buffer); } - - fclose(file); + fStream3 << "\nunset multiplot\n"; + fStream3 << "unset output\n"; } } // Clients scheduling if (fMeasuredClient > 0) { - file = fopen("Timing4.plot", "w"); - - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing4.log file"); + std::ofstream fStream4("Timing4.plot", std::ios_base::ate); + + if (!fStream4.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing4.plot file"); } else { - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients scheduling latency\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream4 << "set multiplot\n"; + fStream4 << "set grid\n"; + fStream4 << "set title \"Clients scheduling latency\"\n"; + fStream4 << "set xlabel \"audio cycles\"\n"; + fStream4 << "set ylabel \"usec\"\n"; + fStream4 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) { // Last client + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'Timing4.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream4 << "\n unset multiplot\n"; + fStream4 << "set output 'Timing4.svg\n"; + fStream4 << "set terminal svg\n"; - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients scheduling latency\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream4 << "set multiplot\n"; + fStream4 << "set grid\n"; + fStream4 << "set title \"Clients scheduling latency\"\n"; + fStream4 << "set xlabel \"audio cycles\"\n"; + fStream4 << "set ylabel \"usec\"\n"; + fStream4 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7), fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) { // Last client + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream4 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fclose(file); + fStream4 << "\nunset multiplot\n"; + fStream4 << "unset output\n"; } } // Clients duration if (fMeasuredClient > 0) { - file = fopen("Timing5.plot", "w"); + std::ofstream fStream5("Timing5.plot", std::ios_base::ate); - if (file == NULL) { - jack_error("JackEngineProfiling::Save cannot open Timing5.log file"); + if (!fStream5.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timing5.plot file"); } else { - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients duration\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream5 << "set multiplot\n"; + fStream5 << "set grid\n"; + fStream5 << "set title \"Clients duration\"\n"; + fStream5 << "set xlabel \"audio cycles\"\n"; + fStream5 << "set ylabel \"usec\"\n"; + fStream5 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) { // Last client + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fprintf(file, "\n unset multiplot\n"); - fprintf(file, "set output 'Timing5.pdf\n"); - fprintf(file, "set terminal pdf\n"); + fStream5 << "\n unset multiplot\n"; + fStream5 << "set output 'Timing5.svg\n"; + fStream5 << "set terminal svg\n"; - fprintf(file, "set multiplot\n"); - fprintf(file, "set grid\n"); - fprintf(file, "set title \"Clients duration\"\n"); - fprintf(file, "set xlabel \"audio cycles\"\n"); - fprintf(file, "set ylabel \"usec\"\n"); - fprintf(file, "plot "); + fStream5 << "set multiplot\n"; + fStream5 << "set grid\n"; + fStream5 << "set title \"Clients duration\"\n"; + fStream5 << "set xlabel \"audio cycles\"\n"; + fStream5 << "set ylabel \"usec\"\n"; + fStream5 << "plot "; for (unsigned int i = 0; i < fMeasuredClient; i++) { - if ((i + 1) == fMeasuredClient) // Last client - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - else - sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) + 1, fIntervalTable[i].fName); - fprintf(file, buffer); + if ((i + 1) == fMeasuredClient) {// Last client + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines"; + } else { + fStream5 << "\"JackEngineProfiling.log\" using " << ((i + 1) * 7) + 1 << " title \"" << fIntervalTable[i].fName << "\" with lines,"; + } } - fclose(file); + fStream5 << "\nunset multiplot\n"; + fStream5 << "unset output\n"; } } + + std::ofstream fStream6("Timings.html", std::ios_base::ate); + if (!fStream6.is_open()) { + jack_error("JackEngineProfiling::Save cannot open Timings.html file"); + } else { + fStream6 << "\n"; + fStream6 << "\n"; + fStream6 << "\n"; + fStream6 << " \n"; + fStream6 << " JACK engine profiling\n"; + fStream6 << " \n"; + fStream6 << " \n"; + fStream6 << " \n"; + fStream6 << " \n"; + fStream6 << "

JACK engine profiling

\n"; + fStream6 << "
Timing1
"; + fStream6 << "
Timing2
"; + fStream6 << "
Timing3
"; + fStream6 << "
Timing4
"; + fStream6 << "
Timing5
"; + fStream6 << " \n"; + fStream6 << "\n"; + } + + std::ofstream fStream7("generate_timings", std::ios_base::ate); + if (!fStream7.is_open()) { + jack_error("JackEngineProfiling::Save cannot open generate_timings file"); + } else { + fStream7 << "gnuplot -persist Timing1.plot \n"; + fStream7 << "gnuplot -persist Timing2.plot\n"; + fStream7 << "gnuplot -persist Timing3.plot\n"; + fStream7 << "gnuplot -persist Timing4.plot\n"; + fStream7 << "gnuplot -persist Timing5.plot\n"; + } } bool JackEngineProfiling::CheckClient(const char* name, int cur_point) diff --git a/common/JackException.h b/common/JackException.h index 3270f20a..58a9a23b 100644 --- a/common/JackException.h +++ b/common/JackException.h @@ -75,6 +75,24 @@ class SERVER_EXPORT JackTemporaryException : public JackException { {} }; +/*! + \brief + */ + +class SERVER_EXPORT JackQuitException : public JackException { + + public: + + JackQuitException(const std::string& msg) : JackException(msg) + {} + JackQuitException(char* msg) : JackException(msg) + {} + JackQuitException(const char* msg) : JackException(msg) + {} + JackQuitException() : JackException("") + {} +}; + /*! \brief Exception possibly thrown by Net slaves. */ diff --git a/common/JackFilters.h b/common/JackFilters.h index 76bf7ecd..ad2afecc 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -20,13 +20,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackFilters__ #define __JackFilters__ +#ifdef __APPLE__ +#include +#endif + #include "jack.h" +#ifndef TARGET_OS_IPHONE #include "JackAtomicState.h" +#endif #include #include namespace Jack { + +#ifndef TARGET_OS_IPHONE #define MAX_SIZE 64 @@ -204,6 +212,7 @@ namespace Jack } } POST_PACKED_STRUCTURE; +#endif /* Torben Hohn PI controler from JACK1 */ diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index c8c40545..2314c84d 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -37,5 +37,28 @@ JackClient* JackGlobals::fClientTable[CLIENT_NUM] = {}; #ifndef WIN32 jack_thread_creator_t JackGlobals::fJackThreadCreator = pthread_create; #endif + +#ifdef __CLIENTDEBUG__ +std::ofstream* JackGlobals::fStream = NULL; + +void JackGlobals::CheckContext(const char* name) +{ + if (JackGlobals::fStream == NULL) { + char provstr[256]; + char buffer[256]; + time_t curtime; + struct tm *loctime; + /* Get the current time. */ + curtime = time (NULL); + /* Convert it to local time representation. */ + loctime = localtime (&curtime); + strftime (buffer, 256, "%I-%M", loctime); + sprintf(provstr, "JackAPICall-%s.log", buffer); + JackGlobals::fStream = new std::ofstream(provstr, std::ios_base::ate); + JackGlobals::fStream->is_open(); + } + (*fStream) << "JACK API call : " << name << ", calling thread : " << pthread_self() << std::endl; +} +#endif } // end of namespace diff --git a/common/JackGlobals.h b/common/JackGlobals.h index 7586708e..3c581097 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -23,9 +23,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPlatformPlug.h" #include "JackConstants.h" +#ifdef __CLIENTDEBUG__ +#include +#include +#include +#include +#endif + namespace Jack { - + // Globals used for client management on server or library side. struct JackGlobals { @@ -38,6 +45,11 @@ struct JackGlobals { #ifndef WIN32 static jack_thread_creator_t fJackThreadCreator; #endif + +#ifdef __CLIENTDEBUG__ + static std::ofstream* fStream; + static void CheckContext(const char* name); +#endif }; // Each "side" server and client will implement this to get the shared graph manager, engine control and inter-process synchro table. diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index d16becd6..ce77f875 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -29,13 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -static void AssertPort(jack_port_id_t port_index) -{ - if (port_index >= PORT_NUM) { - jack_log("JackGraphManager::AssertPort port_index = %ld", port_index); - assert(port_index < PORT_NUM); - } -} static void AssertBufferSize(jack_nframes_t buffer_size) { @@ -44,7 +37,40 @@ static void AssertBufferSize(jack_nframes_t buffer_size) assert(buffer_size <= BUFFER_SIZE_MAX); } } + +void JackGraphManager::AssertPort(jack_port_id_t port_index) +{ + if (port_index >= fPortMax) { + jack_log("JackGraphManager::AssertPort port_index = %ld", port_index); + assert(port_index < fPortMax); + } +} + +JackGraphManager* JackGraphManager::Allocate(int port_max) +{ + // Using "Placement" new + void* shared_ptr = JackShmMem::operator new(sizeof(JackGraphManager) + port_max * sizeof(JackPort)); + return new(shared_ptr) JackGraphManager(port_max); +} +void JackGraphManager::Destroy(JackGraphManager* manager) +{ + // "Placement" new was used + manager->~JackGraphManager(); + JackShmMem::operator delete(manager); +} + +JackGraphManager::JackGraphManager(int port_max) +{ + assert(port_max <= PORT_NUM_MAX); + + for (int i = 0; i < port_max; i++) { + fPortArray[i].Release(); + } + + fPortMax = port_max; +} + JackPort* JackGraphManager::GetPort(jack_port_id_t port_index) { AssertPort(port_index); @@ -262,7 +288,7 @@ int JackGraphManager::ComputeTotalLatency(jack_port_id_t port_index) int JackGraphManager::ComputeTotalLatencies() { jack_port_id_t port_index; - for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { + for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (port->IsUsed()) ComputeTotalLatency(port_index); @@ -276,7 +302,7 @@ void JackGraphManager::SetBufferSize(jack_nframes_t buffer_size) jack_log("JackGraphManager::SetBufferSize size = %ld", buffer_size); jack_port_id_t port_index; - for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { + for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (port->IsUsed()) port->ClearBuffer(buffer_size); @@ -289,7 +315,7 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na jack_port_id_t port_index; // Available ports start at FIRST_AVAILABLE_PORT (= 1), otherwise a port_index of 0 is "seen" as a NULL port by the external API... - for (port_index = FIRST_AVAILABLE_PORT; port_index < PORT_NUM; port_index++) { + for (port_index = FIRST_AVAILABLE_PORT; port_index < fPortMax; port_index++) { JackPort* port = GetPort(port_index); if (!port->IsUsed()) { jack_log("JackGraphManager::AllocatePortAux port_index = %ld name = %s type = %s", port_index, port_name, port_type); @@ -299,7 +325,7 @@ jack_port_id_t JackGraphManager::AllocatePortAux(int refnum, const char* port_na } } - return (port_index < PORT_NUM) ? port_index : NO_PORT; + return (port_index < fPortMax) ? port_index : NO_PORT; } // Server @@ -424,7 +450,7 @@ void JackGraphManager::DisconnectAllInput(jack_port_id_t port_index) jack_log("JackGraphManager::DisconnectAllInput port_index = %ld", port_index); JackConnectionManager* manager = WriteNextStateStart(); - for (int i = 0; i < PORT_NUM; i++) { + for (unsigned int i = 0; i < fPortMax; i++) { if (manager->IsConnected(i, port_index)) { jack_log("JackGraphManager::Disconnect i = %ld port_index = %ld", i, port_index); Disconnect(i, port_index); @@ -661,7 +687,7 @@ int JackGraphManager::GetTwoPorts(const char* src_name, const char* dst_name, ja // Client : port array jack_port_id_t JackGraphManager::GetPort(const char* name) { - for (int i = 0; i < PORT_NUM; i++) { + for (unsigned int i = 0; i < fPortMax; i++) { JackPort* port = GetPort(i); if (port->IsUsed() && port->NameEquals(name)) return i; @@ -734,9 +760,9 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port } // Cleanup port array - memset(matching_ports, 0, sizeof(char*) * PORT_NUM); + memset(matching_ports, 0, sizeof(char*) * fPortMax); - for (int i = 0; i < PORT_NUM; i++) { + for (unsigned int i = 0; i < fPortMax; i++) { bool matching = true; JackPort* port = GetPort(i); @@ -783,7 +809,7 @@ void JackGraphManager::GetPortsAux(const char** matching_ports, const char* port */ const char** JackGraphManager::GetPorts(const char* port_name_pattern, const char* type_name_pattern, unsigned long flags) { - const char** res = (const char**)malloc(sizeof(char*) * PORT_NUM); + const char** res = (const char**)malloc(sizeof(char*) * fPortMax); UInt16 cur_index, next_index; if (!res) diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 0fdd3c82..c2d7e105 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -42,9 +42,11 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState private: - JackPort fPortArray[PORT_NUM]; + unsigned int fPortMax; JackClientTiming fClientTiming[CLIENT_NUM]; + JackPort fPortArray[0]; // The actual size depends of port_max, it will be dynamically computed and allocated using "placement" new + void AssertPort(jack_port_id_t port_index); jack_port_id_t AllocatePortAux(int refnum, const char* port_name, const char* port_type, JackPortFlags flags); void GetConnectionsAux(JackConnectionManager* manager, const char** res, jack_port_id_t port_index); void GetPortsAux(const char** matching_ports, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags); @@ -54,8 +56,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState public: - JackGraphManager() - {} + JackGraphManager(int port_max); ~JackGraphManager() {} @@ -127,6 +128,9 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState void Save(JackConnectionManager* dst); void Restore(JackConnectionManager* src); + + static JackGraphManager* Allocate(int port_max); + static void Destroy(JackGraphManager* manager); } POST_PACKED_STRUCTURE; diff --git a/common/JackLibAPI.cpp b/common/JackLibAPI.cpp index b2cce06f..45649c2d 100644 --- a/common/JackLibAPI.cpp +++ b/common/JackLibAPI.cpp @@ -112,6 +112,9 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { try { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_open"); +#endif assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); va_list ap; @@ -131,6 +134,9 @@ EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options EXPORT int jack_client_close(jack_client_t* ext_client) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_close"); +#endif assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); int res = -1; diff --git a/common/JackLibClient.cpp b/common/JackLibClient.cpp index 4c92e9e3..effdfc6f 100644 --- a/common/JackLibClient.cpp +++ b/common/JackLibClient.cpp @@ -103,6 +103,9 @@ int JackLibClient::Open(const char* server_name, const char* name, jack_options_ } catch (int n) { jack_error("Map shared memory segments exception %d", n); goto error; + } catch (...) { + jack_error("Unknown error..."); + goto error; } SetupDriverSync(false); diff --git a/common/JackLibGlobals.h b/common/JackLibGlobals.h index f109b665..5ef8b9e9 100644 --- a/common/JackLibGlobals.h +++ b/common/JackLibGlobals.h @@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackError.h" #include #include + namespace Jack { @@ -123,13 +124,6 @@ struct JackLibGlobals } } - static void CheckContext() - { - if (!(fClientCount > 0 && fGlobals)) { - jack_error("Error !!! : client accessing an already desallocated library context"); - } - } - }; } // end of namespace diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index c2de8512..a9f044a8 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -31,6 +31,16 @@ namespace Jack #define TRY_CALL \ try { \ +/* +See : http://groups.google.com/group/comp.programming.threads/browse_thread/thread/652bcf186fbbf697/f63757846514e5e5 + +catch (...) { + // Assuming thread cancellation, must rethrow + throw; + +} +*/ + #define CATCH_EXCEPTION_RETURN \ } catch(std::bad_alloc& e) { \ jack_error("Memory allocation error..."); \ @@ -41,14 +51,15 @@ namespace Jack return -1; \ } catch (...) { \ jack_error("Unknown error..."); \ - return -1; \ + throw; \ } \ -#define CATCH_ENGINE_EXCEPTION \ +#define CATCH_EXCEPTION \ } catch(std::bad_alloc& e) { \ jack_error("Memory allocation error..."); \ } catch (...) { \ jack_error("Unknown error..."); \ + throw; \ } \ /*! @@ -83,7 +94,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble return fEngine.Close(); CATCH_EXCEPTION_RETURN } - + // Client management int ClientCheck(const char* name, char* name_res, int protocol, int options, int* status) { @@ -233,35 +244,35 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble TRY_CALL JackLock lock(this); fEngine.NotifyXRun(refnum); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyGraphReorder() { TRY_CALL JackLock lock(this); fEngine.NotifyGraphReorder(); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyBufferSize(jack_nframes_t buffer_size) { TRY_CALL JackLock lock(this); fEngine.NotifyBufferSize(buffer_size); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifySampleRate(jack_nframes_t sample_rate) { TRY_CALL JackLock lock(this); fEngine.NotifySampleRate(sample_rate); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyFreewheel(bool onoff) { TRY_CALL JackLock lock(this); fEngine.NotifyFreewheel(onoff); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } void NotifyFailure(int code, const char* reason) @@ -269,7 +280,7 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble TRY_CALL JackLock lock(this); fEngine.NotifyFailure(code, reason); - CATCH_ENGINE_EXCEPTION + CATCH_EXCEPTION } int GetClientPID(const char* name) @@ -287,7 +298,15 @@ class SERVER_EXPORT JackLockedEngine : public JackLockAble return fEngine.GetClientRefNum(name); CATCH_EXCEPTION_RETURN } - + + void NotifyQuit() + { + TRY_CALL + JackLock lock(this); + return fEngine.NotifyQuit(); + CATCH_EXCEPTION + } + }; } // end of namespace diff --git a/common/JackMessageBuffer.cpp b/common/JackMessageBuffer.cpp index 8dacfe67..b9f28463 100644 --- a/common/JackMessageBuffer.cpp +++ b/common/JackMessageBuffer.cpp @@ -29,7 +29,7 @@ namespace Jack JackMessageBuffer* JackMessageBuffer::fInstance = NULL; JackMessageBuffer::JackMessageBuffer() - :fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0),fRunning(false) + :fInit(NULL),fInitArg(NULL),fThread(this),fInBuffer(0),fOutBuffer(0),fOverruns(0),fRunning(false) {} JackMessageBuffer::~JackMessageBuffer() @@ -82,6 +82,15 @@ bool JackMessageBuffer::Execute() while (fRunning) { fGuard.Lock(); fGuard.Wait(); + /* the client asked for all threads to run a thread + initialization callback, which includes us. + */ + if (fInit) { + fInit(fInitArg); + fInit = NULL; + /* and we're done */ + fGuard.Signal(); + } Flush(); fGuard.Unlock(); } @@ -115,5 +124,20 @@ void JackMessageBufferAdd(int level, const char *message) } } +void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *arg) +{ + fGuard.Lock(); + /* set up the callback */ + fInitArg = arg; + fInit = callback; + /* wake msg buffer thread */ + fGuard.Signal(); + /* wait for it to be done */ + fGuard.Wait(); + /* and we're done */ + fGuard.Unlock(); +} + + }; diff --git a/common/JackMessageBuffer.h b/common/JackMessageBuffer.h index 5e3472a5..ec13a5dc 100644 --- a/common/JackMessageBuffer.h +++ b/common/JackMessageBuffer.h @@ -57,6 +57,8 @@ class JackMessageBuffer : public JackRunnableInterface private: + JackThreadInitCallback fInit; + void* fInitArg; JackMessage fBuffers[MB_BUFFERS]; JackThread fThread; JackProcessSync fGuard; @@ -82,6 +84,7 @@ class JackMessageBuffer : public JackRunnableInterface void static Destroy(); void AddMessage(int level, const char *message); + void SetInitCallback(JackThreadInitCallback callback, void *arg); static JackMessageBuffer* fInstance; }; diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index dd19f904..46825d8d 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -878,21 +878,46 @@ SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** in // Empty code for now.. -//#ifdef TARGET_OS_IPHONE +#ifdef TARGET_OS_IPHONE -SERVER_EXPORT void jack_error(const char *fmt, ...) +static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) { - // TODO + char buffer[300]; + size_t len; + + if (prefix != NULL) { + len = strlen(prefix); + memcpy(buffer, prefix, len); + } else { + len = 0; + } + + vsnprintf(buffer + len, sizeof(buffer) - len, fmt, ap); + printf(buffer); + printf("\n"); } +SERVER_EXPORT void jack_error(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + va_end(ap);} + SERVER_EXPORT void jack_info(const char *fmt, ...) { - // TODO + va_list ap; + va_start(ap, fmt); + jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + va_end(ap); } SERVER_EXPORT void jack_log(const char *fmt, ...) { - // TODO + va_list ap; + va_start(ap, fmt); + jack_format_and_log(LOG_LEVEL_INFO, "Jack: ", fmt, ap); + va_end(ap); } -//#endif +#endif diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 5131c98c..1ecc04ca 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -227,6 +227,7 @@ namespace Jack do { session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, SLAVE_SETUP ); SessionParamsHToN(&fParams, &net_params); @@ -316,6 +317,7 @@ namespace Jack JackNetSocket mcast_socket ( fMulticastIP, fSocket.GetPort() ); session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SessionParamsHToN(&fParams, &net_params); if ( mcast_socket.NewSocket() == SOCKET_ERROR ) @@ -679,6 +681,8 @@ namespace Jack //utility session_params_t host_params; int rx_bytes = 0; + + jack_log ( "sizeof (session_params_t) %d", sizeof (session_params_t) ); //socket if ( fSocket.NewSocket() == SOCKET_ERROR ) { @@ -706,6 +710,7 @@ namespace Jack { //send 'available' session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SessionParamsHToN(&fParams, &net_params); if ( fSocket.SendTo ( &net_params, sizeof ( session_params_t ), 0, fMulticastIP ) == SOCKET_ERROR ) jack_error ( "Error in data send : %s", StrError ( NET_ERROR_CODE ) ); @@ -713,15 +718,28 @@ namespace Jack //filter incoming packets : don't exit while no error is detected memset(&net_params, 0, sizeof ( session_params_t )); rx_bytes = fSocket.CatchHost ( &net_params, sizeof ( session_params_t ), 0 ); + + SessionParamsDisplay(&net_params); + jack_error ( "rx_bytes %d %d", rx_bytes, errno ); + + SessionParamsNToH(&net_params, &host_params); if ( ( rx_bytes == SOCKET_ERROR ) && ( fSocket.GetError() != NET_NO_DATA ) ) { jack_error ( "Can't receive : %s", StrError ( NET_ERROR_CODE ) ); return NET_RECV_ERROR; } + for (int i = 0; i < 7; i++) { + jack_info ( " fPacketType %d", host_params.fPacketType[i]); + } + jack_info ( " received... host_params param %s %s %d %d", net_params.fPacketType, fParams.fPacketType, net_params.fPacketID, GetPacketType ( &host_params )); + + SessionParamsDisplay(&host_params); } while ( strcmp ( host_params.fPacketType, fParams.fPacketType ) && ( GetPacketType ( &host_params ) != SLAVE_SETUP ) ); + jack_info ( "SLAVE_SETUP received..." ); + //everything is OK, copy parameters fParams = host_params; @@ -746,6 +764,7 @@ namespace Jack //tell the master to start session_params_t net_params; + memset(&net_params, 0, sizeof ( session_params_t )); SetPacketType ( &fParams, START_MASTER ); SessionParamsHToN(&fParams, &net_params); if ( fSocket.Send ( &net_params, sizeof ( session_params_t ), 0 ) == SOCKET_ERROR ) diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index bc0160bc..4a75cc23 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -17,8 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -//#define HAVE_CELT 1 - #ifdef WIN32 #include #endif diff --git a/common/JackNotification.h b/common/JackNotification.h index 43611a4f..be0c89fd 100644 --- a/common/JackNotification.h +++ b/common/JackNotification.h @@ -44,6 +44,7 @@ enum NotificationType { kPortRenameCallback = 13, kRealTimeCallback = 14, kShutDownCallback = 15, + kQUIT = 16, kMaxNotification }; diff --git a/common/JackPhysicalMidiInput.cpp b/common/JackPhysicalMidiInput.cpp new file mode 100644 index 00000000..311dad0b --- /dev/null +++ b/common/JackPhysicalMidiInput.cpp @@ -0,0 +1,287 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include +#include +#include + +#include "JackError.h" +#include "JackPhysicalMidiInput.h" + +namespace Jack { + +JackPhysicalMidiInput::JackPhysicalMidiInput(size_t buffer_size) +{ + size_t datum_size = sizeof(jack_midi_data_t); + assert(buffer_size > 0); + input_ring = jack_ringbuffer_create((buffer_size + 1) * datum_size); + if (! input_ring) { + throw std::bad_alloc(); + } + jack_ringbuffer_mlock(input_ring); + Clear(); + expected_data_bytes = 0; + status_byte = 0; +} + +JackPhysicalMidiInput::~JackPhysicalMidiInput() +{ + jack_ringbuffer_free(input_ring); +} + +void +JackPhysicalMidiInput::Clear() +{ + jack_ringbuffer_reset(input_ring); + buffered_bytes = 0; + unbuffered_bytes = 0; +} + +void +JackPhysicalMidiInput::HandleBufferFailure(size_t unbuffered_bytes, + size_t total_bytes) +{ + jack_error("%d MIDI byte(s) of a %d byte message could not be buffered - " + "message dropped", unbuffered_bytes, total_bytes); +} + +void +JackPhysicalMidiInput::HandleIncompleteMessage(size_t bytes) +{ + jack_error("Discarding %d MIDI byte(s) - incomplete message (cable " + "unplugged?)", bytes); +} + +void +JackPhysicalMidiInput::HandleInvalidStatusByte(jack_midi_data_t status) +{ + jack_error("Dropping invalid MIDI status byte '%x'", + (unsigned int) status); +} + +void +JackPhysicalMidiInput::HandleUnexpectedSysexEnd(size_t bytes) +{ + jack_error("Discarding %d MIDI byte(s) - received sysex end without sysex " + "start (cable unplugged?)", bytes); +} + +void +JackPhysicalMidiInput::HandleWriteFailure(size_t bytes) +{ + jack_error("Failed to write a %d byte MIDI message to the port buffer", + bytes); +} + +void +JackPhysicalMidiInput::Process(jack_nframes_t frames) +{ + assert(port_buffer); + port_buffer->Reset(frames); + jack_nframes_t current_frame = 0; + size_t datum_size = sizeof(jack_midi_data_t); + for (;;) { + jack_midi_data_t datum; + current_frame = Receive(&datum, current_frame, frames); + if (current_frame >= frames) { + break; + } + + jack_log("JackPhysicalMidiInput::Process (%d) - Received '%x' byte", + current_frame, (unsigned int) datum); + + if (datum >= 0xf8) { + // Realtime + if (datum == 0xfd) { + HandleInvalidStatusByte(datum); + } else { + + jack_log("JackPhysicalMidiInput::Process - Writing realtime " + "event."); + + WriteByteEvent(current_frame, datum); + } + continue; + } + if (datum == 0xf7) { + // Sysex end + if (status_byte != 0xf0) { + HandleUnexpectedSysexEnd(buffered_bytes + unbuffered_bytes); + Clear(); + expected_data_bytes = 0; + status_byte = 0; + } else { + + jack_log("JackPhysicalMidiInput::Process - Writing sysex " + "event."); + + WriteBufferedSysexEvent(current_frame); + } + continue; + } + if (datum >= 0x80) { + + // We're handling a non-realtime status byte + + jack_log("JackPhysicalMidiInput::Process - Handling non-realtime " + "status byte."); + + if (buffered_bytes || unbuffered_bytes) { + HandleIncompleteMessage(buffered_bytes + unbuffered_bytes + 1); + Clear(); + } + status_byte = datum; + switch (datum & 0xf0) { + case 0x80: + case 0x90: + case 0xa0: + case 0xb0: + case 0xe0: + // Note On, Note Off, Aftertouch, Control Change, Pitch Wheel + expected_data_bytes = 2; + break; + case 0xc0: + case 0xd0: + // Program Change, Channel Pressure + expected_data_bytes = 1; + break; + case 0xf0: + switch (datum) { + case 0xf0: + // Sysex message + expected_data_bytes = 0; + break; + case 0xf1: + case 0xf3: + // MTC Quarter frame, Song Select + expected_data_bytes = 1; + break; + case 0xf2: + // Song Position + expected_data_bytes = 2; + break; + case 0xf4: + case 0xf5: + // Undefined + HandleInvalidStatusByte(datum); + expected_data_bytes = 0; + status_byte = 0; + break; + case 0xf6: + // Tune Request + WriteByteEvent(current_frame, datum); + expected_data_bytes = 0; + status_byte = 0; + } + break; + } + continue; + } + + // We're handling a data byte + + jack_log("JackPhysicalMidiInput::Process - Buffering data byte."); + + if (jack_ringbuffer_write(input_ring, (const char *) &datum, + datum_size) == datum_size) { + buffered_bytes++; + } else { + unbuffered_bytes++; + } + unsigned long total_bytes = buffered_bytes + unbuffered_bytes; + assert((! expected_data_bytes) || + (total_bytes <= expected_data_bytes)); + if (total_bytes == expected_data_bytes) { + if (! unbuffered_bytes) { + + jack_log("JackPhysicalMidiInput::Process - Writing buffered " + "event."); + + WriteBufferedEvent(current_frame); + } else { + HandleBufferFailure(unbuffered_bytes, total_bytes); + Clear(); + } + if (status_byte >= 0xf0) { + expected_data_bytes = 0; + status_byte = 0; + } + } + } +} + +void +JackPhysicalMidiInput::WriteBufferedEvent(jack_nframes_t frame) +{ + assert(port_buffer && port_buffer->IsValid()); + size_t space = jack_ringbuffer_read_space(input_ring); + jack_midi_data_t *event = port_buffer->ReserveEvent(frame, space + 1); + if (event) { + jack_ringbuffer_data_t vector[2]; + jack_ringbuffer_get_read_vector(input_ring, vector); + event[0] = status_byte; + size_t data_length_1 = vector[0].len; + memcpy(event + 1, vector[0].buf, data_length_1); + size_t data_length_2 = vector[1].len; + if (data_length_2) { + memcpy(event + data_length_1 + 1, vector[1].buf, data_length_2); + } + } else { + HandleWriteFailure(space + 1); + } + Clear(); +} + +void +JackPhysicalMidiInput::WriteBufferedSysexEvent(jack_nframes_t frame) +{ + assert(port_buffer && port_buffer->IsValid()); + size_t space = jack_ringbuffer_read_space(input_ring); + jack_midi_data_t *event = port_buffer->ReserveEvent(frame, space + 2); + if (event) { + jack_ringbuffer_data_t vector[2]; + jack_ringbuffer_get_read_vector(input_ring, vector); + event[0] = status_byte; + size_t data_length_1 = vector[0].len; + memcpy(event + 1, vector[0].buf, data_length_1); + size_t data_length_2 = vector[1].len; + if (data_length_2) { + memcpy(event + data_length_1 + 1, vector[1].buf, data_length_2); + } + event[data_length_1 + data_length_2 + 1] = 0xf7; + } else { + HandleWriteFailure(space + 2); + } + Clear(); +} + +void +JackPhysicalMidiInput::WriteByteEvent(jack_nframes_t frame, + jack_midi_data_t datum) +{ + assert(port_buffer && port_buffer->IsValid()); + jack_midi_data_t *event = port_buffer->ReserveEvent(frame, 1); + if (event) { + event[0] = datum; + } else { + HandleWriteFailure(1); + } +} + +} diff --git a/common/JackPhysicalMidiInput.h b/common/JackPhysicalMidiInput.h new file mode 100644 index 00000000..6ba3b471 --- /dev/null +++ b/common/JackPhysicalMidiInput.h @@ -0,0 +1,146 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackPhysicalMidiInput__ +#define __JackPhysicalMidiInput__ + +#include "JackMidiPort.h" +#include "ringbuffer.h" + +namespace Jack { + + class JackPhysicalMidiInput { + + private: + + size_t buffered_bytes; + size_t expected_data_bytes; + jack_ringbuffer_t *input_ring; + JackMidiBuffer *port_buffer; + jack_midi_data_t status_byte; + size_t unbuffered_bytes; + + void + Clear(); + + void + WriteBufferedEvent(jack_nframes_t); + + void + WriteBufferedSysexEvent(jack_nframes_t); + + void + WriteByteEvent(jack_nframes_t, jack_midi_data_t); + + protected: + + /** + * Override to specify how to react when 1 or more bytes of a MIDI + * message are lost because there wasn't enough room in the input + * buffer. The first argument is the amount of bytes that couldn't be + * buffered, and the second argument is the total amount of bytes in + * the MIDI message. The default implementation calls 'jack_error' + * with a basic error message. + */ + + virtual void + HandleBufferFailure(size_t, size_t); + + /** + * Override to specify how to react when a new status byte is received + * before all of the data bytes in a message are received. The + * argument is the number of bytes being discarded. The default + * implementation calls 'jack_error' with a basic error message. + */ + + virtual void + HandleIncompleteMessage(size_t); + + /** + * Override to specify how to react when an invalid status byte (0xf4, + * 0xf5, 0xfd) is received. The argument contains the invalid status + * byte. The default implementation calls 'jack_error' with a basic + * error message. + */ + + virtual void + HandleInvalidStatusByte(jack_midi_data_t); + + /** + * Override to specify how to react when a sysex end byte (0xf7) is + * received without first receiving a sysex start byte (0xf0). The + * argument contains the amount of bytes that will be discarded. The + * default implementation calls 'jack_error' with a basic error + * message. + */ + + virtual void + HandleUnexpectedSysexEnd(size_t); + + /** + * Override to specify how to react when a MIDI message can not be + * written to the port buffer. The argument specifies the length of + * the MIDI message. The default implementation calls 'jack_error' + * with a basic error message. + */ + + virtual void + HandleWriteFailure(size_t); + + /** + * This method *must* be overridden to handle receiving MIDI bytes. + * The first argument is a pointer to the memory location at which the + * MIDI byte should be stored. The second argument is the last frame + * at which a MIDI byte was received, except at the beginning of the + * period when the value is 0. The third argument is the total number + * of frames in the period. The return value is the frame at which the + * MIDI byte is received at, or the value of the third argument is no + * more MIDI bytes can be received in this period. + */ + + virtual jack_nframes_t + Receive(jack_midi_data_t *, jack_nframes_t, jack_nframes_t) = 0; + + public: + + JackPhysicalMidiInput(size_t buffer_size=1024); + ~JackPhysicalMidiInput(); + + /** + * Called to process MIDI data during a period. + */ + + void + Process(jack_nframes_t); + + /** + * Set the MIDI buffer that will receive incoming messages. + */ + + inline void + SetPortBuffer(JackMidiBuffer *port_buffer) + { + this->port_buffer = port_buffer; + } + + }; + +} + +#endif diff --git a/common/JackPhysicalMidiOutput.cpp b/common/JackPhysicalMidiOutput.cpp new file mode 100644 index 00000000..8f41d443 --- /dev/null +++ b/common/JackPhysicalMidiOutput.cpp @@ -0,0 +1,320 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackError.h" +#include "JackPhysicalMidiOutput.h" + +namespace Jack { + +JackPhysicalMidiOutput::JackPhysicalMidiOutput(size_t non_rt_buffer_size, + size_t rt_buffer_size) +{ + size_t datum_size = sizeof(jack_midi_data_t); + assert(non_rt_buffer_size > 0); + assert(rt_buffer_size > 0); + output_ring = jack_ringbuffer_create((non_rt_buffer_size + 1) * + datum_size); + if (! output_ring) { + throw std::bad_alloc(); + } + rt_output_ring = jack_ringbuffer_create((rt_buffer_size + 1) * + datum_size); + if (! rt_output_ring) { + jack_ringbuffer_free(output_ring); + throw std::bad_alloc(); + } + jack_ringbuffer_mlock(output_ring); + jack_ringbuffer_mlock(rt_output_ring); + running_status = 0; +} + +JackPhysicalMidiOutput::~JackPhysicalMidiOutput() +{ + jack_ringbuffer_free(output_ring); + jack_ringbuffer_free(rt_output_ring); +} + +jack_nframes_t +JackPhysicalMidiOutput::Advance(jack_nframes_t frame) +{ + return frame; +} + +inline jack_midi_data_t +JackPhysicalMidiOutput::ApplyRunningStatus(jack_midi_data_t **buffer, + size_t *size) +{ + + // Stolen and modified from alsa/midi_pack.h + + jack_midi_data_t status = (*buffer)[0]; + if ((status >= 0x80) && (status < 0xf0)) { + if (status == running_status) { + (*buffer)++; + (*size)--; + } else { + running_status = status; + } + } else if (status < 0xf8) { + running_status = 0; + } + return status; +} + +void +JackPhysicalMidiOutput::HandleEventLoss(JackMidiEvent *event) +{ + jack_error("%d byte MIDI event lost", event->size); +} + +void +JackPhysicalMidiOutput::Process(jack_nframes_t frames) +{ + assert(port_buffer); + jack_nframes_t current_frame = Advance(0); + jack_nframes_t current_midi_event = 0; + jack_midi_data_t datum; + size_t datum_size = sizeof(jack_midi_data_t); + JackMidiEvent *midi_event; + jack_midi_data_t *midi_event_buffer; + size_t midi_event_size; + jack_nframes_t midi_events = port_buffer->event_count; + + // First, send any realtime MIDI data that's left from last cycle. + + if ((current_frame < frames) && + jack_ringbuffer_read_space(rt_output_ring)) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sending buffered " + "realtime data from last period.", current_frame); + + current_frame = SendBufferedData(rt_output_ring, current_frame, + frames); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent", current_frame); + + } + + // Iterate through the events in this cycle. + + for (; (current_midi_event < midi_events) && (current_frame < frames); + current_midi_event++) { + + // Once we're inside this loop, we know that the realtime buffer + // is empty. As long as we don't find a realtime message, we can + // concentrate on sending non-realtime data. + + midi_event = &(port_buffer->events[current_midi_event]); + jack_nframes_t midi_event_time = midi_event->time; + midi_event_buffer = midi_event->GetData(port_buffer); + midi_event_size = midi_event->size; + datum = ApplyRunningStatus(&midi_event_buffer, &midi_event_size); + if (current_frame < midi_event_time) { + + // We have time before this event is scheduled to be sent. + // Send data in the non-realtime buffer. + + if (jack_ringbuffer_read_space(output_ring)) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sending " + "buffered non-realtime data from last period.", + current_frame); + + current_frame = SendBufferedData(output_ring, current_frame, + midi_event_time); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent", + current_frame); + + } + if (current_frame < midi_event_time) { + + // We _still_ have time before this event is scheduled to + // be sent. Let's send as much of this event as we can + // (save for one byte, which will need to be sent at or + // after its scheduled time). First though, we need to + // make sure that we can buffer this data if we need to. + // Otherwise, we might start sending a message that we + // can't finish. + + if (midi_event_size > 1) { + if (jack_ringbuffer_write_space(output_ring) < + ((midi_event_size - 1) * datum_size)) { + HandleEventLoss(midi_event); + continue; + } + + // Send as much of the event as possible (save for one + // byte). + + do { + + jack_log("JackPhysicalMidiOutput::Process (%d) - " + "Sending unbuffered event byte early.", + current_frame); + + current_frame = Send(current_frame, + *midi_event_buffer); + + jack_log("JackPhysicalMidiOutput::Process (%d) - " + "Sent.", current_frame); + + midi_event_buffer++; + midi_event_size--; + if (current_frame >= midi_event_time) { + + // The event we're processing must be a + // non-realtime event. It has more than one + // byte. + + goto buffer_non_realtime_data; + } + } while (midi_event_size > 1); + } + + jack_log("JackPhysicalMidiOutput::Process (%d) - Advancing to " + ">= %d", current_frame, midi_event_time); + + current_frame = Advance(midi_event_time); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Advanced.", + current_frame); + + } + } + + // If the event is realtime, then we'll send the event now. + // Otherwise, we attempt to put the rest of the event bytes in the + // non-realtime buffer. + + if (datum >= 0xf8) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sending " + "unbuffered realtime event.", current_frame); + + current_frame = Send(current_frame, datum); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent.", + current_frame); + + } else if (jack_ringbuffer_write_space(output_ring) >= + (midi_event_size * datum_size)) { + buffer_non_realtime_data: + + jack_log("JackPhysicalMidiOutput::Process (%d) - Buffering %d " + "byte(s) of non-realtime data.", current_frame, + midi_event_size); + + jack_ringbuffer_write(output_ring, + (const char *) midi_event_buffer, + midi_event_size); + } else { + HandleEventLoss(midi_event); + } + } + + if (current_frame < frames) { + + // If we have time left to send data, then we know that all of the + // data in the realtime buffer has been sent, and that all of the + // non-realtime messages have either been sent, or buffered. We + // use whatever time is left to send data in the non-realtime + // buffer. + + if (jack_ringbuffer_read_space(output_ring)) { + + jack_log("JackPhysicalMidiOutput::Process (%d) - All events " + "processed. Sending buffered non-realtime data.", + current_frame); + + current_frame = SendBufferedData(output_ring, current_frame, + frames); + + jack_log("JackPhysicalMidiOutput::Process (%d) - Sent.", + current_frame); + + } + } else { + + // Since we have no time left, we need to put all remaining midi + // events in their appropriate buffers, and send them next period. + + for (; current_midi_event < midi_events; current_midi_event++) { + midi_event = &(port_buffer->events[current_midi_event]); + midi_event_buffer = midi_event->GetData(port_buffer); + midi_event_size = midi_event->size; + datum = ApplyRunningStatus(&midi_event_buffer, &midi_event_size); + if (datum >= 0xf8) { + + // Realtime. + + if (jack_ringbuffer_write_space(rt_output_ring) >= + datum_size) { + + jack_log("JackPhysicalMidiOutput::Process - Buffering " + "realtime event for next period."); + + jack_ringbuffer_write(rt_output_ring, + (const char *) &datum, datum_size); + continue; + } + } else { + + // Non-realtime. + + if (jack_ringbuffer_write_space(output_ring) >= + (midi_event_size * datum_size)) { + + jack_log("JackPhysicalMidiOutput::Process - Buffering " + "non-realtime event for next period."); + + jack_ringbuffer_write(output_ring, + (const char *) midi_event_buffer, + midi_event_size * datum_size); + continue; + } + } + HandleEventLoss(midi_event); + } + } +} + +jack_nframes_t +JackPhysicalMidiOutput::SendBufferedData(jack_ringbuffer_t *buffer, + jack_nframes_t current_frame, + jack_nframes_t boundary) +{ + assert(buffer); + assert(current_frame < boundary); + size_t datum_size = sizeof(jack_midi_data_t); + size_t data_length = jack_ringbuffer_read_space(buffer) / datum_size; + for (size_t i = 0; i < data_length; i++) { + jack_midi_data_t datum; + jack_ringbuffer_read(buffer, (char *) &datum, datum_size); + current_frame = Send(current_frame, datum); + if (current_frame >= boundary) { + break; + } + } + return current_frame; +} + +} diff --git a/common/JackPhysicalMidiOutput.h b/common/JackPhysicalMidiOutput.h new file mode 100644 index 00000000..f76a233a --- /dev/null +++ b/common/JackPhysicalMidiOutput.h @@ -0,0 +1,118 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackPhysicalMidiOutput__ +#define __JackPhysicalMidiOutput__ + +#include "JackMidiPort.h" +#include "ringbuffer.h" + +namespace Jack { + + class JackPhysicalMidiOutput { + + private: + + jack_midi_data_t + ApplyRunningStatus(jack_midi_data_t **, size_t *); + + jack_ringbuffer_t *output_ring; + JackMidiBuffer *port_buffer; + jack_ringbuffer_t *rt_output_ring; + jack_midi_data_t running_status; + + protected: + + /** + * Override to specify the next frame at which a midi byte can be sent. + * The returned frame must be greater than or equal to the frame + * argument. The default returns the frame passed to it. + */ + + virtual jack_nframes_t + Advance(jack_nframes_t); + + /** + * Override to customize how to react when a MIDI event can't be + * buffered and can't be sent immediately. The default calls + * 'jack_error' and specifies the number of bytes lost. + */ + + virtual void + HandleEventLoss(JackMidiEvent *); + + /** + * This method *must* be overridden to specify what happens when a MIDI + * byte is sent at the specfied frame. The frame argument specifies + * the frame at which the MIDI byte should be sent, and the second + * argument specifies the byte itself. The return value is the next + * frame at which a MIDI byte can be sent, and must be greater than or + * equal to the frame argument. + */ + + virtual jack_nframes_t + Send(jack_nframes_t, jack_midi_data_t) = 0; + + /** + * Override to optimize behavior when sending MIDI data that's in the + * ringbuffer. The first frame argument is the current frame, and the + * second frame argument is the boundary frame. The function returns + * the next frame at which MIDI data can be sent, regardless of whether + * or not the boundary is reached. The default implementation calls + * 'Send' with each byte in the ringbuffer until either the ringbuffer + * is empty, or a frame beyond the boundary frame is returned by + * 'Send'. + */ + + virtual jack_nframes_t + SendBufferedData(jack_ringbuffer_t *, jack_nframes_t, jack_nframes_t); + + public: + + /** + * The non-realtime buffer size and the realtime buffer size are both + * optional arguments. + */ + + JackPhysicalMidiOutput(size_t non_rt_buffer_size=1024, + size_t rt_buffer_size=64); + ~JackPhysicalMidiOutput(); + + /** + * Called to process MIDI data during a period. + */ + + void + Process(jack_nframes_t); + + /** + * Set the MIDI buffer that will contain the outgoing MIDI messages. + */ + + inline void + SetPortBuffer(JackMidiBuffer *port_buffer) + { + this->port_buffer = port_buffer; + } + + }; + +} + +#endif diff --git a/common/JackPort.cpp b/common/JackPort.cpp index 42b5fb2e..f8c62d67 100644 --- a/common/JackPort.cpp +++ b/common/JackPort.cpp @@ -28,15 +28,9 @@ namespace Jack { JackPort::JackPort() - : fTypeId(0), - fFlags(JackPortIsInput), - fRefNum( -1), - fLatency(0), - fTotalLatency(0), - fMonitorRequests(0), - fInUse(false), - fTied(NO_PORT) -{} +{ + Release(); +} bool JackPort::Allocate(int refnum, const char* port_name, const char* port_type, JackPortFlags flags) { @@ -68,6 +62,7 @@ void JackPort::Release() fInUse = false; fLatency = 0; fTotalLatency = 0; + fMonitorRequests = 0; fTied = NO_PORT; fAlias1[0] = '\0'; fAlias2[0] = '\0'; diff --git a/common/JackServer.cpp b/common/JackServer.cpp index a260b47a..e2676500 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -38,15 +38,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) +JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name) { if (rt) { jack_info("JACK server starting in realtime mode with priority %ld", priority); } else { jack_info("JACK server starting in non-realtime mode"); } - - fGraphManager = new JackGraphManager(); + + fGraphManager = JackGraphManager::Allocate(port_max); fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver(fEngine, GetSynchroTable())); @@ -60,7 +60,7 @@ JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long pr JackServer::~JackServer() { - delete fGraphManager; + JackGraphManager::Destroy(fGraphManager); delete fAudioDriver; delete fDriverInfo; delete fFreewheelDriver; @@ -125,6 +125,7 @@ fail_close1: int JackServer::Close() { jack_log("JackServer::Close"); + fEngine->NotifyQuit(); fChannel.Close(); fAudioDriver->Detach(); fAudioDriver->Close(); diff --git a/common/JackServer.h b/common/JackServer.h index 325237de..f99d7c20 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -62,7 +62,7 @@ class SERVER_EXPORT JackServer public: - JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name); + JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name); ~JackServer(); int Open(jack_driver_desc_t* driver_desc, JSList* driver_params); diff --git a/common/JackServerAPI.cpp b/common/JackServerAPI.cpp index e8e6c021..a9755fe8 100644 --- a/common/JackServerAPI.cpp +++ b/common/JackServerAPI.cpp @@ -105,6 +105,9 @@ EXPORT jack_client_t* jack_client_open_aux(const char* client_name, jack_options EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_open"); +#endif try { assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); @@ -125,6 +128,9 @@ EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options EXPORT int jack_client_close(jack_client_t* ext_client) { +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_client_close"); +#endif assert(JackGlobals::fOpenMutex); JackGlobals::fOpenMutex->Lock(); int res = -1; diff --git a/common/JackServerGlobals.cpp b/common/JackServerGlobals.cpp index 7698c640..fcad0a71 100644 --- a/common/JackServerGlobals.cpp +++ b/common/JackServerGlobals.cpp @@ -41,11 +41,12 @@ int JackServerGlobals::Start(const char* server_name, int time_out_ms, int rt, int priority, + int port_max, int verbose, jack_timer_type_t clock) { jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); - new JackServer(sync, temporary, time_out_ms, rt, priority, verbose, clock, server_name); // Will setup fInstance and fUserCount globals + new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, server_name); // Will setup fInstance and fUserCount globals int res = fInstance->Open(driver_desc, driver_params); return (res < 0) ? res : fInstance->Start(); } @@ -291,7 +292,7 @@ bool JackServerGlobals::Init() free(argv[i]); } - int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, verbose_aux, clock_source); + int res = Start(server_name, driver_desc, driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source); if (res < 0) { jack_error("Cannot start server... exit"); Delete(); diff --git a/common/JackServerGlobals.h b/common/JackServerGlobals.h index 00d8b0ff..b4b688c1 100644 --- a/common/JackServerGlobals.h +++ b/common/JackServerGlobals.h @@ -54,6 +54,7 @@ struct SERVER_EXPORT JackServerGlobals int time_out_ms, int rt, int priority, + int port_max, int verbose, jack_timer_type_t clock); static void Stop(); diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 9045827c..89ed0845 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -100,6 +100,7 @@ static void usage(FILE* file) " [ --name OR -n server-name ]\n" " [ --timeout OR -t client-timeout-in-msecs ]\n" " [ --loopback OR -L loopback-port-number ]\n" + " [ --port-max OR -p maximum-number-of-ports]\n" " [ --midi OR -X midi-driver ]\n" " [ --verbose OR -v ]\n" #ifdef __linux__ @@ -118,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" @@ -178,11 +179,11 @@ int main(int argc, char* argv[]) jackctl_driver_t * loopback_driver_ctl; int replace_registry = 0; + const char *options = "-d:X:P:uvshVrRL:STFl:t:mn:p:" #ifdef __linux__ - const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:c:L:"; -#else - const char *options = "-ad:X:P:uvshVrRL:STFl:t:mn:p:L:"; + "c:" #endif + ; struct option long_options[] = { #ifdef __linux__ @@ -220,7 +221,6 @@ int main(int argc, char* argv[]) char *midi_driver_name = NULL; char **midi_driver_args = NULL; int midi_driver_nargs = 1; - int port_max = 512; int do_mlock = 1; int do_unlock = 0; int loopback = 0; @@ -291,7 +291,11 @@ int main(int argc, char* argv[]) break; case 'p': - port_max = (unsigned int)atol(optarg); + param = jackctl_get_parameter(server_parameters, "port-max"); + if (param != NULL) { + value.ui = atoi(optarg); + jackctl_parameter_set_value(param, &value); + } break; case 'm': @@ -408,7 +412,7 @@ int main(int argc, char* argv[]) // Audio driver audio_driver_ctl = jackctl_server_get_driver(server_ctl, audio_driver_name); if (audio_driver_ctl == NULL) { - fprintf(stderr, "Unkown driver \"%s\"\n", audio_driver_name); + fprintf(stderr, "Unknown driver \"%s\"\n", audio_driver_name); goto fail_free1; } @@ -446,7 +450,7 @@ int main(int argc, char* argv[]) midi_driver_ctl = jackctl_server_get_driver(server_ctl, midi_driver_name); if (midi_driver_ctl == NULL) { - fprintf(stderr, "Unkown driver \"%s\"\n", midi_driver_name); + fprintf(stderr, "Unknown driver \"%s\"\n", midi_driver_name); goto fail_free2; } diff --git a/common/jack/jack.h b/common/jack/jack.h index a5dc3aec..96800dcd 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -34,30 +34,20 @@ extern "C" * Note: More documentation can be found in jack/types.h. */ -/************************************************************* - * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function - * added to the JACK API after the 0.116.2 release. - *************************************************************/ - -#ifndef JACK_WEAK_EXPORT -#ifdef __GNUC__ -/* JACK_WEAK_EXPORT needs to be a macro which - expands into a compiler directive. If non-null, the directive - must tell the compiler to arrange for weak linkage of - the symbol it used with. For this to work full may - require linker arguments in the client as well. -*/ -#define JACK_WEAK_EXPORT __attribute__((weak)) -#else -/* Add other things here for non-gcc platforms */ -#endif -#endif - -/** -* @defgroup ClientFunctions Creating & manipulating clients -* @{ -*/ - + /************************************************************* + * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function + * added to the JACK API after the 0.116.2 release. + * + * Functions that predate this release are marked with + * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile + * time in a variety of ways. The default definition is empty, + * so that these symbols get normal linkage. If you wish to + * use all JACK symbols with weak linkage, include + * before jack.h. + *************************************************************/ + +#include + /** * Call this function to get version of the JACK, in form of several numbers * @@ -75,7 +65,7 @@ jack_get_version( int *major_ptr, int *minor_ptr, int *micro_ptr, - int *proto_ptr); + int *proto_ptr) JACK_OPTIONAL_WEAK_EXPORT; /** * Call this function to get version of the JACK, in form of a string @@ -84,7 +74,7 @@ jack_get_version( * */ const char * -jack_get_version_string(); +jack_get_version_string() JACK_OPTIONAL_WEAK_EXPORT; /** * Open an external client session with a JACK server. This interface @@ -121,7 +111,7 @@ jack_get_version_string(); */ jack_client_t * jack_client_open (const char *client_name, jack_options_t options, - jack_status_t *status, ...); + jack_status_t *status, ...) JACK_OPTIONAL_WEAK_EXPORT; /** * \bold THIS FUNCTION IS DEPRECATED AND SHOULD NOT BE USED IN @@ -129,20 +119,20 @@ jack_client_t * jack_client_open (const char *client_name, * * @deprecated Please use jack_client_open(). */ -jack_client_t * jack_client_new (const char *client_name); +jack_client_t * jack_client_new (const char *client_name) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Disconnects an external client from a JACK server. * * @return 0 on success, otherwise a non-zero error code */ -int jack_client_close (jack_client_t *client); +int jack_client_close (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a JACK client name * including the final NULL character. This value is a constant. */ -int jack_client_name_size (void); +int jack_client_name_size (void) JACK_OPTIONAL_WEAK_EXPORT; /** * @return pointer to actual client name. This is useful when @ref @@ -150,7 +140,7 @@ int jack_client_name_size (void); * JackNameNotUnique status was returned. In that case, the actual * name will differ from the @a client_name requested. */ -char * jack_get_client_name (jack_client_t *client); +char * jack_get_client_name (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Load an internal client into the Jack server. @@ -175,14 +165,14 @@ char * jack_get_client_name (jack_client_t *client); */ int jack_internal_client_new (const char *client_name, const char *load_name, - const char *load_init); + const char *load_init) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Remove an internal client from a JACK server. * * @deprecated Please use jack_internal_client_load(). */ -void jack_internal_client_close (const char *client_name); +void jack_internal_client_close (const char *client_name) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * Tell the Jack server that the program is ready to start processing @@ -190,7 +180,7 @@ void jack_internal_client_close (const char *client_name); * * @return 0 on success, otherwise a non-zero error code */ -int jack_activate (jack_client_t *client); +int jack_activate (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to remove this @a client from the process @@ -199,18 +189,18 @@ int jack_activate (jack_client_t *client); * * @return 0 on success, otherwise a non-zero error code */ -int jack_deactivate (jack_client_t *client); +int jack_deactivate (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return pid of client. If not available, 0 will be returned. */ -int jack_get_client_pid (const char *name); +int jack_get_client_pid (const char *name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the pthread ID of the thread running the JACK client side * code. */ -pthread_t jack_client_thread_id (jack_client_t *); +pthread_t jack_client_thread_id (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -221,7 +211,7 @@ pthread_t jack_client_thread_id (jack_client_t *); * * @return 1 if JACK is running realtime, 0 otherwise */ -int jack_is_realtime (jack_client_t *client); +int jack_is_realtime (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @defgroup NonCallbackAPI The non-callback API @@ -234,7 +224,7 @@ int jack_is_realtime (jack_client_t *client); * * @deprecated Please use jack_cycle_wait() and jack_cycle_signal() functions. */ -jack_nframes_t jack_thread_wait (jack_client_t*, int status); +jack_nframes_t jack_thread_wait (jack_client_t*, int status) JACK_OPTIONAL_WEAK_EXPORT; /** * Wait until this JACK client should process data. @@ -243,7 +233,7 @@ jack_nframes_t jack_thread_wait (jack_client_t*, int status); * * @return the number of frames of data to process */ -jack_nframes_t jack_cycle_wait (jack_client_t* client); + jack_nframes_t jack_cycle_wait (jack_client_t* client) JACK_OPTIONAL_WEAK_EXPORT; /** * Signal next clients in the graph. @@ -251,7 +241,7 @@ jack_nframes_t jack_cycle_wait (jack_client_t* client); * @param client - pointer to a JACK client structure * @param status - if non-zero, calling thread should exit */ -void jack_cycle_signal (jack_client_t* client, int status); +void jack_cycle_signal (jack_client_t* client, int status) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a thread_callback in the RT thread. @@ -269,7 +259,7 @@ void jack_cycle_signal (jack_client_t* client, int status); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_callback, void *arg); +int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -294,7 +284,7 @@ int jack_set_process_thread(jack_client_t* client, JackThreadCallback thread_cal */ int jack_set_thread_init_callback (jack_client_t *client, JackThreadInitCallback thread_init_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * @param client pointer to JACK client structure. @@ -346,7 +336,7 @@ void jack_on_shutdown (jack_client_t *client, * jack_on_info_shutdown() will. */ void jack_on_info_shutdown (jack_client_t *client, - JackInfoShutdownCallback shutdown_callback, void *arg); + JackInfoShutdownCallback shutdown_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a process_callback whenever there is @@ -367,7 +357,7 @@ void jack_on_info_shutdown (jack_client_t *client, */ int jack_set_process_callback (jack_client_t *client, JackProcessCallback process_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a freewheel_callback @@ -387,7 +377,7 @@ int jack_set_process_callback (jack_client_t *client, */ int jack_set_freewheel_callback (jack_client_t *client, JackFreewheelCallback freewheel_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell JACK to call @a bufsize_callback whenever the size of the the @@ -410,7 +400,7 @@ int jack_set_freewheel_callback (jack_client_t *client, */ int jack_set_buffer_size_callback (jack_client_t *client, JackBufferSizeCallback bufsize_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the Jack server to call @a srate_callback whenever the system @@ -427,11 +417,11 @@ int jack_set_buffer_size_callback (jack_client_t *client, */ int jack_set_sample_rate_callback (jack_client_t *client, JackSampleRateCallback srate_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** - * Tell the JACK server to call @a registration_callback whenever a - * port is registered or unregistered, passing @a arg as a parameter. + * Tell the JACK server to call @a client_registration_callback whenever a + * client is registered or unregistered, passing @a arg as a parameter. * * All "notification events" are received in a seperated non RT thread, * the code in the supplied function does not need to be @@ -444,7 +434,7 @@ int jack_set_sample_rate_callback (jack_client_t *client, */ int jack_set_client_registration_callback (jack_client_t *, JackClientRegistrationCallback - registration_callback, void *arg); + registration_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a registration_callback whenever a @@ -460,8 +450,8 @@ int jack_set_client_registration_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_registration_callback (jack_client_t *, - JackPortRegistrationCallback - registration_callback, void *arg); + JackPortRegistrationCallback + registration_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a connect_callback whenever a @@ -477,8 +467,8 @@ int jack_set_client_registration_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_connect_callback (jack_client_t *, - JackPortConnectCallback - connect_callback, void *arg); + JackPortConnectCallback + connect_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a rename_callback whenever a @@ -494,8 +484,8 @@ int jack_set_port_connect_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_port_rename_callback (jack_client_t *, - JackPortRenameCallback - rename_callback, void *arg); + JackPortRenameCallback + rename_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a graph_callback whenever the @@ -512,7 +502,7 @@ int jack_set_port_rename_callback (jack_client_t *, */ int jack_set_graph_order_callback (jack_client_t *, JackGraphOrderCallback graph_callback, - void *); + void *) JACK_OPTIONAL_WEAK_EXPORT; /** * Tell the JACK server to call @a xrun_callback whenever there is a @@ -528,7 +518,7 @@ int jack_set_graph_order_callback (jack_client_t *, * @return 0 on success, otherwise a non-zero error code */ int jack_set_xrun_callback (jack_client_t *, - JackXRunCallback xrun_callback, void *arg); + JackXRunCallback xrun_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -561,7 +551,7 @@ int jack_set_xrun_callback (jack_client_t *, * * @return 0 on success, otherwise a non-zero error code. */ -int jack_set_freewheel(jack_client_t* client, int onoff); +int jack_set_freewheel(jack_client_t* client, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * Change the buffer size passed to the @a process_callback. @@ -578,13 +568,13 @@ int jack_set_freewheel(jack_client_t* client, int onoff); * * @return 0 on success, otherwise a non-zero error code */ -int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes); +int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the sample rate of the jack system, as set by the user when * jackd was started. */ -jack_nframes_t jack_get_sample_rate (jack_client_t *); +jack_nframes_t jack_get_sample_rate (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the current maximum size that will ever be passed to the @a @@ -595,7 +585,7 @@ jack_nframes_t jack_get_sample_rate (jack_client_t *); * * @see jack_set_buffer_size_callback() */ -jack_nframes_t jack_get_buffer_size (jack_client_t *); +jack_nframes_t jack_get_buffer_size (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * Old-style interface to become the timebase for the entire JACK @@ -607,7 +597,7 @@ jack_nframes_t jack_get_buffer_size (jack_client_t *); * * @return ENOSYS, function not implemented. */ -int jack_engine_takeover_timebase (jack_client_t *); +int jack_engine_takeover_timebase (jack_client_t *) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * @return the current CPU load estimated by JACK. This is a running @@ -615,7 +605,7 @@ int jack_engine_takeover_timebase (jack_client_t *); * all clients as a percentage of the real time available per cycle * determined by the buffer size and sample rate. */ -float jack_cpu_load (jack_client_t *client); +float jack_cpu_load (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -654,7 +644,7 @@ jack_port_t * jack_port_register (jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, - unsigned long buffer_size); + unsigned long buffer_size) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove the port from the client, disconnecting any existing @@ -662,7 +652,7 @@ jack_port_t * jack_port_register (jack_client_t *client, * * @return 0 on success, otherwise a non-zero error code */ -int jack_port_unregister (jack_client_t *, jack_port_t *); +int jack_port_unregister (jack_client_t *, jack_port_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * This returns a pointer to the memory area associated with the @@ -683,7 +673,7 @@ int jack_port_unregister (jack_client_t *, jack_port_t *); * Caching output ports is DEPRECATED in Jack 2.0, due to some new optimization (like "pipelining"). * Port buffers have to be retrieved in each callback for proper functionning. */ -void * jack_port_get_buffer (jack_port_t *, jack_nframes_t); +void * jack_port_get_buffer (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the full name of the jack_port_t (including the @a @@ -691,7 +681,7 @@ void * jack_port_get_buffer (jack_port_t *, jack_nframes_t); * * @see jack_port_name_size(). */ -const char * jack_port_name (const jack_port_t *port); +const char * jack_port_name (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the short name of the jack_port_t (not including the @a @@ -699,35 +689,35 @@ const char * jack_port_name (const jack_port_t *port); * * @see jack_port_name_size(). */ -const char * jack_port_short_name (const jack_port_t *port); +const char * jack_port_short_name (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @ref JackPortFlags of the jack_port_t. */ -int jack_port_flags (const jack_port_t *port); +int jack_port_flags (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @a port type, at most jack_port_type_size() characters * including a final NULL. */ -const char * jack_port_type (const jack_port_t *port); +const char * jack_port_type (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the @a port type id. */ -jack_port_type_id_t jack_port_type_id (const jack_port_t *port); +jack_port_type_id_t jack_port_type_id (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if the jack_port_t belongs to the jack_client_t. */ -int jack_port_is_mine (const jack_client_t *, const jack_port_t *port); +int jack_port_is_mine (const jack_client_t *, const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return number of connections to or from @a port. * * @pre The calling client must own @a port. */ -int jack_port_connected (const jack_port_t *port); +int jack_port_connected (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if the locally-owned @a port is @b directly connected @@ -736,7 +726,7 @@ int jack_port_connected (const jack_port_t *port); * @see jack_port_name_size() */ int jack_port_connected_to (const jack_port_t *port, - const char *port_name); + const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return a null-terminated array of full port names to which the @a @@ -749,7 +739,7 @@ int jack_port_connected_to (const jack_port_t *port, * * @see jack_port_name_size(), jack_port_get_all_connections() */ -const char ** jack_port_get_connections (const jack_port_t *port); +const char ** jack_port_get_connections (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @return a null-terminated array of full port names to which the @a @@ -771,7 +761,7 @@ const char ** jack_port_get_connections (const jack_port_t *port); * @see jack_port_name_size() */ const char ** jack_port_get_all_connections (const jack_client_t *client, - const jack_port_t *port); + const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * @@ -780,7 +770,7 @@ const char ** jack_port_get_all_connections (const jack_client_t *client, * turned out to serve essentially no purpose in real-life * JACK clients. */ -int jack_port_tie (jack_port_t *src, jack_port_t *dst); +int jack_port_tie (jack_port_t *src, jack_port_t *dst) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * @@ -789,7 +779,7 @@ int jack_port_tie (jack_port_t *src, jack_port_t *dst); * turned out to serve essentially no purpose in real-life * JACK clients. */ -int jack_port_untie (jack_port_t *port); +int jack_port_untie (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; /** * @return the time (in frames) between data being available or @@ -801,7 +791,7 @@ int jack_port_untie (jack_port_t *port); * connector and the corresponding frames being readable from the * port. */ -jack_nframes_t jack_port_get_latency (jack_port_t *port); +jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * The maximum of the sum of the latencies in every @@ -809,7 +799,7 @@ jack_nframes_t jack_port_get_latency (jack_port_t *port); * ports with the @ref JackPortIsTerminal flag set. */ jack_nframes_t jack_port_get_total_latency (jack_client_t *, - jack_port_t *port); + jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * The port latency is zero by default. Clients that control @@ -821,7 +811,7 @@ jack_nframes_t jack_port_get_total_latency (jack_client_t *, * to an external digital converter, the latency setting should * include both buffering by the audio interface *and* the converter. */ -void jack_port_set_latency (jack_port_t *, jack_nframes_t); +void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * Request a complete recomputation of a port's total latency. This @@ -834,7 +824,7 @@ void jack_port_set_latency (jack_port_t *, jack_nframes_t); * @return zero for successful execution of the request. non-zero * otherwise. */ -int jack_recompute_total_latency (jack_client_t*, jack_port_t* port); +int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_EXPORT; /** * Request a complete recomputation of all port latencies. This @@ -849,7 +839,7 @@ int jack_recompute_total_latency (jack_client_t*, jack_port_t* port); * @return zero for successful execution of the request. non-zero * otherwise. */ -int jack_recompute_total_latencies (jack_client_t*); + int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * Modify a port's short name. May be called at any time. If the @@ -858,7 +848,7 @@ int jack_recompute_total_latencies (jack_client_t*); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_port_set_name (jack_port_t *port, const char *port_name); +int jack_port_set_name (jack_port_t *port, const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * Set @a alias as an alias for @a port. May be called at any time. @@ -873,7 +863,7 @@ int jack_port_set_name (jack_port_t *port, const char *port_name); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_port_set_alias (jack_port_t *port, const char *alias); +int jack_port_set_alias (jack_port_t *port, const char *alias) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove @a alias as an alias for @a port. May be called at any time. @@ -883,20 +873,20 @@ int jack_port_set_alias (jack_port_t *port, const char *alias); * * @return 0 on success, otherwise a non-zero error code. */ -int jack_port_unset_alias (jack_port_t *port, const char *alias); +int jack_port_unset_alias (jack_port_t *port, const char *alias) JACK_OPTIONAL_WEAK_EXPORT; /** * Get any aliases known for @port. * * @return the number of aliases discovered for the port */ -int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]); +int jack_port_get_aliases (const jack_port_t *port, char* const aliases[2]) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for this @a port, turn input * monitoring on or off. Otherwise, do nothing. */ -int jack_port_request_monitor (jack_port_t *port, int onoff); +int jack_port_request_monitor (jack_port_t *port, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for this @a port_name, turn input @@ -907,7 +897,7 @@ int jack_port_request_monitor (jack_port_t *port, int onoff); * @see jack_port_name_size() */ int jack_port_request_monitor_by_name (jack_client_t *client, - const char *port_name, int onoff); + const char *port_name, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * If @ref JackPortCanMonitor is set for a port, this function turns @@ -916,12 +906,12 @@ int jack_port_request_monitor_by_name (jack_client_t *client, * * @return 0 on success, otherwise a non-zero error code */ -int jack_port_ensure_monitor (jack_port_t *port, int onoff); +int jack_port_ensure_monitor (jack_port_t *port, int onoff) JACK_OPTIONAL_WEAK_EXPORT; /** * @return TRUE if input monitoring has been requested for @a port. */ -int jack_port_monitoring_input (jack_port_t *port); +int jack_port_monitoring_input (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; /** * Establish a connection between two ports. @@ -942,7 +932,7 @@ int jack_port_monitoring_input (jack_port_t *port); */ int jack_connect (jack_client_t *, const char *source_port, - const char *destination_port); + const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT; /** * Remove a connection between two ports. @@ -959,7 +949,7 @@ int jack_connect (jack_client_t *, */ int jack_disconnect (jack_client_t *, const char *source_port, - const char *destination_port); + const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT; /** * Perform the same function as jack_disconnect() using port handles @@ -970,7 +960,7 @@ int jack_disconnect (jack_client_t *, * while generic connection clients (e.g. patchbays) would use * jack_disconnect(). */ -int jack_port_disconnect (jack_client_t *, jack_port_t *); +int jack_port_disconnect (jack_client_t *, jack_port_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a full JACK port name @@ -980,13 +970,13 @@ int jack_port_disconnect (jack_client_t *, jack_port_t *); * with a colon (:) followed by its short name and a NULL * character. */ -int jack_port_name_size(void); +int jack_port_name_size(void) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the maximum number of characters in a JACK port type name * including the final NULL character. This value is a constant. */ -int jack_port_type_size(void); +int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1014,20 +1004,20 @@ int jack_port_type_size(void); const char ** jack_get_ports (jack_client_t *, const char *port_name_pattern, const char *type_name_pattern, - unsigned long flags); + unsigned long flags) JACK_OPTIONAL_WEAK_EXPORT; /** * @return address of the jack_port_t named @a port_name. * * @see jack_port_name_size() */ -jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name); +jack_port_t * jack_port_by_name (jack_client_t *, const char *port_name) JACK_OPTIONAL_WEAK_EXPORT; /** * @return address of the jack_port_t of a @a port_id. */ jack_port_t * jack_port_by_id (jack_client_t *client, - jack_port_id_t port_id); + jack_port_id_t port_id) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1044,7 +1034,7 @@ jack_port_t * jack_port_by_id (jack_client_t *client, * @return the estimated time in frames that has passed since the JACK * server began the current process cycle. */ -jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *); +jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated current time in frames. @@ -1052,7 +1042,7 @@ jack_nframes_t jack_frames_since_cycle_start (const jack_client_t *); * callback). The return value can be compared with the value of * jack_last_frame_time to relate time in other threads to JACK time. */ -jack_nframes_t jack_frame_time (const jack_client_t *); +jack_nframes_t jack_frame_time (const jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the precise time at the start of the current process cycle. @@ -1068,17 +1058,17 @@ jack_nframes_t jack_frame_time (const jack_client_t *); * If an xrun occurs, clients must check this value again, as time * may have advanced in a non-linear way (e.g. cycles may have been skipped). */ -jack_nframes_t jack_last_frame_time (const jack_client_t *client); +jack_nframes_t jack_last_frame_time (const jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated time in microseconds of the specified frame time */ -jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t); +jack_time_t jack_frames_to_time(const jack_client_t *client, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return the estimated time in frames for the specified system time. */ -jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t); +jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t) JACK_OPTIONAL_WEAK_EXPORT; /** * @return return JACK's current system time in microseconds, @@ -1086,7 +1076,7 @@ jack_nframes_t jack_time_to_frames(const jack_client_t *client, jack_time_t); * * The value returned is guaranteed to be monotonic, but not linear. */ -jack_time_t jack_get_time(); +jack_time_t jack_get_time() JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1103,7 +1093,7 @@ jack_time_t jack_get_time(); * * @param msg error message text (no newline at end). */ -extern void (*jack_error_callback)(const char *msg); +extern void (*jack_error_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the @ref jack_error_callback for error message display. @@ -1112,7 +1102,7 @@ extern void (*jack_error_callback)(const char *msg); * The JACK library provides two built-in callbacks for this purpose: * default_jack_error_callback() and silent_jack_error_callback(). */ -void jack_set_error_function (void (*func)(const char *)); +void jack_set_error_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPORT; /** * Display JACK info message. @@ -1122,7 +1112,7 @@ void jack_set_error_function (void (*func)(const char *)); * * @param msg info message text (no newline at end). */ -extern void (*jack_info_callback)(const char *msg); +extern void (*jack_info_callback)(const char *msg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the @ref jack_info_callback for info message display. @@ -1131,7 +1121,7 @@ extern void (*jack_info_callback)(const char *msg); * The JACK library provides two built-in callbacks for this purpose: * default_jack_info_callback() and silent_jack_info_callback(). */ -void jack_set_info_function (void (*func)(const char *)); +void jack_set_info_function (void (*func)(const char *)) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ @@ -1142,7 +1132,7 @@ void jack_set_info_function (void (*func)(const char *)); * Developers are strongly encouraged to use this function instead of the standard "free" function in new code. * */ -void jack_free(void* ptr); +void jack_free(void* ptr) JACK_OPTIONAL_WEAK_EXPORT; #ifdef __cplusplus diff --git a/common/jack/midiport.h b/common/jack/midiport.h index da0b940d..fd620b8d 100644 --- a/common/jack/midiport.h +++ b/common/jack/midiport.h @@ -27,7 +27,7 @@ extern "C" { #include #include - +#include /** Type for raw event data contained in @ref jack_midi_event_t. */ typedef unsigned char jack_midi_data_t; @@ -53,7 +53,7 @@ typedef struct _jack_midi_event * @return number of events inside @a port_buffer */ jack_nframes_t -jack_midi_get_event_count(void* port_buffer); +jack_midi_get_event_count(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Get a MIDI event from an event port buffer. @@ -70,7 +70,7 @@ jack_midi_get_event_count(void* port_buffer); int jack_midi_event_get(jack_midi_event_t *event, void *port_buffer, - jack_nframes_t event_index); + jack_nframes_t event_index) JACK_OPTIONAL_WEAK_EXPORT; /** Clear an event buffer. @@ -82,7 +82,7 @@ jack_midi_event_get(jack_midi_event_t *event, * @param port_buffer Port buffer to clear (must be an output port buffer). */ void -jack_midi_clear_buffer(void *port_buffer); +jack_midi_clear_buffer(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Get the size of the largest event that can be stored by the port. @@ -93,7 +93,7 @@ jack_midi_clear_buffer(void *port_buffer); * @param port_buffer Port buffer to check size of. */ size_t -jack_midi_max_event_size(void* port_buffer); +jack_midi_max_event_size(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /** Allocate space for an event to be written to an event port buffer. @@ -112,9 +112,9 @@ jack_midi_max_event_size(void* port_buffer); * NULL on error (ie not enough space). */ jack_midi_data_t* -jack_midi_event_reserve(void *port_buffer, +jack_midi_event_reserve(void *port_buffer, jack_nframes_t time, - size_t data_size); + size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; /** Write an event into an event port buffer. @@ -130,10 +130,10 @@ jack_midi_event_reserve(void *port_buffer, * @return 0 on success, ENOBUFS if there's not enough space in buffer for event. */ int -jack_midi_event_write(void *port_buffer, - jack_nframes_t time, +jack_midi_event_write(void *port_buffer, + jack_nframes_t time, const jack_midi_data_t *data, - size_t data_size); + size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; /** Get the number of events that could not be written to @a port_buffer. @@ -145,7 +145,7 @@ jack_midi_event_write(void *port_buffer, * @returns Number of events that could not be written to @a port_buffer. */ jack_nframes_t -jack_midi_get_lost_event_count(void *port_buffer); +jack_midi_get_lost_event_count(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ diff --git a/common/jack/thread.h b/common/jack/thread.h index 48adf084..5d002afa 100644 --- a/common/jack/thread.h +++ b/common/jack/thread.h @@ -26,6 +26,7 @@ extern "C" #endif #include +#include /** @file thread.h * @@ -45,7 +46,7 @@ extern "C" * Otherwise returns -1. */ -int jack_client_real_time_priority (jack_client_t*); +int jack_client_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * @returns if JACK is running with realtime scheduling, this returns @@ -53,7 +54,7 @@ int jack_client_real_time_priority (jack_client_t*); * is subject to realtime scheduling. Otherwise returns -1. */ -int jack_client_max_real_time_priority (jack_client_t*); +int jack_client_max_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; /** * Attempt to enable realtime scheduling for a thread. On some @@ -65,7 +66,7 @@ int jack_client_max_real_time_priority (jack_client_t*); * @returns 0, if successful; EPERM, if the calling process lacks * required realtime privileges; otherwise some other error number. */ -int jack_acquire_real_time_scheduling (pthread_t thread, int priority); +int jack_acquire_real_time_scheduling (pthread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; /** * Create a thread for JACK or one of its clients. The thread is @@ -88,7 +89,7 @@ int jack_client_create_thread (jack_client_t* client, int priority, int realtime, /* boolean */ void *(*start_routine)(void*), - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Drop realtime scheduling for a thread. @@ -97,7 +98,7 @@ int jack_client_create_thread (jack_client_t* client, * * @returns 0, if successful; otherwise an error number. */ -int jack_drop_real_time_scheduling (pthread_t thread); +int jack_drop_real_time_scheduling (pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Stop the thread, waiting for the thread handler to terminate. @@ -106,7 +107,7 @@ int jack_drop_real_time_scheduling (pthread_t thread); * * @returns 0, if successful; otherwise an error number. */ -int jack_client_stop_thread(jack_client_t* client, pthread_t thread); +int jack_client_stop_thread(jack_client_t* client, pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** * Cancel the thread then waits for the thread handler to terminate. @@ -115,7 +116,7 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * * @returns 0, if successful; otherwise an error number. */ - int jack_client_kill_thread(jack_client_t* client, pthread_t thread); + int jack_client_kill_thread(jack_client_t* client, pthread_t thread) JACK_OPTIONAL_WEAK_EXPORT; #ifndef WIN32 @@ -142,7 +143,7 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * @param creator a function that creates a new thread * */ -void jack_set_thread_creator (jack_thread_creator_t creator); +void jack_set_thread_creator (jack_thread_creator_t creator) JACK_OPTIONAL_WEAK_EXPORT; #endif diff --git a/common/jack/transport.h b/common/jack/transport.h index 67bcaa2a..e8ba8cbb 100644 --- a/common/jack/transport.h +++ b/common/jack/transport.h @@ -26,6 +26,7 @@ extern "C" { #endif #include +#include /** * @defgroup TransportControl Transport and Timebase control @@ -48,7 +49,7 @@ extern "C" { * * @return 0 on success, otherwise a non-zero error code. */ -int jack_release_timebase (jack_client_t *client); +int jack_release_timebase (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Register (or unregister) as a slow-sync client, one that cannot @@ -72,7 +73,7 @@ int jack_release_timebase (jack_client_t *client); */ int jack_set_sync_callback (jack_client_t *client, JackSyncCallback sync_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the timeout value for slow-sync clients. @@ -92,7 +93,7 @@ int jack_set_sync_callback (jack_client_t *client, * @return 0 on success, otherwise a non-zero error code. */ int jack_set_sync_timeout (jack_client_t *client, - jack_time_t timeout); + jack_time_t timeout) JACK_OPTIONAL_WEAK_EXPORT; /** * Register as timebase master for the JACK subsystem. @@ -122,7 +123,7 @@ int jack_set_sync_timeout (jack_client_t *client, int jack_set_timebase_callback (jack_client_t *client, int conditional, JackTimebaseCallback timebase_callback, - void *arg); + void *arg) JACK_OPTIONAL_WEAK_EXPORT; /** * Reposition the transport to a new frame number. @@ -141,7 +142,7 @@ int jack_set_timebase_callback (jack_client_t *client, * @return 0 if valid request, non-zero otherwise. */ int jack_transport_locate (jack_client_t *client, - jack_nframes_t frame); + jack_nframes_t frame) JACK_OPTIONAL_WEAK_EXPORT; /** * Query the current transport state and position. @@ -159,7 +160,7 @@ int jack_transport_locate (jack_client_t *client, * @return Current transport state. */ jack_transport_state_t jack_transport_query (const jack_client_t *client, - jack_position_t *pos); + jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; /** * Return an estimate of the current transport frame, @@ -168,7 +169,7 @@ jack_transport_state_t jack_transport_query (const jack_client_t *client, * * @param client the JACK client structure */ -jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client); +jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Request a new transport position. @@ -187,7 +188,7 @@ jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client); * @return 0 if valid request, EINVAL if position structure rejected. */ int jack_transport_reposition (jack_client_t *client, - jack_position_t *pos); + jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; /** * Start the JACK transport rolling. @@ -200,7 +201,7 @@ int jack_transport_reposition (jack_client_t *client, * * @param client the JACK client structure. */ -void jack_transport_start (jack_client_t *client); +void jack_transport_start (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Stop the JACK transport. @@ -210,7 +211,7 @@ void jack_transport_start (jack_client_t *client); * * @param client the JACK client structure. */ -void jack_transport_stop (jack_client_t *client); +void jack_transport_stop (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; /** * Gets the current transport info structure (deprecated). @@ -225,7 +226,7 @@ void jack_transport_stop (jack_client_t *client); * @pre Must be called from the process thread. */ void jack_get_transport_info (jack_client_t *client, - jack_transport_info_t *tinfo); + jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_EXPORT; /** * Set the transport info structure (deprecated). @@ -235,7 +236,7 @@ void jack_get_transport_info (jack_client_t *client, * a ::JackTimebaseCallback. */ void jack_set_transport_info (jack_client_t *client, - jack_transport_info_t *tinfo); + jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_EXPORT; /*@}*/ diff --git a/common/jack/types.h b/common/jack/types.h index fd71ceac..6c1b0f95 100644 --- a/common/jack/types.h +++ b/common/jack/types.h @@ -202,7 +202,7 @@ typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int * * @return zero on success, non-zero on error */ -typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* new_name, void *arg); +typedef int (*JackPortRenameCallback)(jack_port_id_t port, const char* old_name, const char* new_name, void *arg); /** * Prototype for the client supplied function that is called diff --git a/common/jack/weakjack.h b/common/jack/weakjack.h new file mode 100644 index 00000000..11d2acaa --- /dev/null +++ b/common/jack/weakjack.h @@ -0,0 +1,52 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __weakjack_h__ +#define __weakjack_h__ + +#ifndef JACK_OPTIONAL_WEAK_EXPORT +/* JACK_OPTIONAL_WEAK_EXPORT needs to be a macro which + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of + the symbol it used with. For this to work fully may + require linker arguments for the client as well. +*/ +#ifdef __GNUC__ +#define JACK_OPTIONAL_WEAK_EXPORT __attribute__((__weak__)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + +#ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT +/* JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT needs to be a macro + which expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of the + symbol it is used with AND optionally to mark the symbol + as deprecated. For this to work fully may require + linker arguments for the client as well. +*/ +#ifdef __GNUC__ +#define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__weak__,__deprecated__)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + +#endif /* weakjack */ diff --git a/common/jack/weakmacros.h b/common/jack/weakmacros.h new file mode 100644 index 00000000..3db19d3f --- /dev/null +++ b/common/jack/weakmacros.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2010 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __weakmacros_h__ +#define __weakmacros_h__ + +/************************************************************* + * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function + * added to the JACK API after the 0.116.2 release. + * + * Functions that predate this release are marked with + * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile + * time in a variety of ways. The default definition is empty, + * so that these symbols get normal linkage. If you wish to + * use all JACK symbols with weak linkage, include + * before jack.h. + *************************************************************/ + +#ifndef JACK_WEAK_EXPORT +#ifdef __GNUC__ +/* JACK_WEAK_EXPORT needs to be a macro which + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of + the symbol it used with. For this to work full may + require linker arguments in the client as well. +*/ +#define JACK_WEAK_EXPORT __attribute__((weak)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + +#ifndef JACK_OPTIONAL_WEAK_EXPORT +#define JACK_OPTIONAL_WEAK_EXPORT +#endif + +#ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT +#ifdef __GNUC__ +#define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__deprecated__)) +#else +/* Add other things here for non-gcc platforms */ +#endif /* __GNUC__ */ +#endif + +#endif /* __weakmacros_h__ */ diff --git a/common/netjack.c b/common/netjack.c index eb5f36b7..a073c2cf 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -42,6 +42,7 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #ifdef WIN32 #include #include +#define socklen_t int #else #include #include @@ -49,7 +50,9 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ #include "netjack.h" -//#include "config.h" +#ifdef __linux__ +#include "config.h" +#endif #if HAVE_SAMPLERATE #include @@ -92,7 +95,7 @@ int netjack_wait( netjack_driver_state_t *netj ) jacknet_packet_header *pkthdr; if( !netj->next_deadline_valid ) { - netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline = jack_get_time() + netj->period_usecs; netj->next_deadline_valid = 1; } @@ -165,7 +168,7 @@ int netjack_wait( netjack_driver_state_t *netj ) netj->packet_data_valid = 1; int want_deadline; - if( netj->jitter_val != 0 ) + if( netj->jitter_val != 0 ) want_deadline = netj->jitter_val; else if( netj->latency < 4 ) want_deadline = -netj->period_usecs/2; @@ -174,23 +177,23 @@ int netjack_wait( netjack_driver_state_t *netj ) if( netj->deadline_goodness != MASTER_FREEWHEELS ) { if( netj->deadline_goodness < want_deadline ) { - netj->deadline_offset -= netj->period_usecs/100; + netj->next_deadline -= netj->period_usecs/100; //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); } if( netj->deadline_goodness > want_deadline ) { - netj->deadline_offset += netj->period_usecs/100; + netj->next_deadline += netj->period_usecs/100; //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); } } - if( netj->deadline_offset < (netj->period_usecs*70/100) ) { - jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); - netj->deadline_offset = (netj->period_usecs*90/100); - } +// if( netj->next_deadline < (netj->period_usecs*70/100) ) { +// jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); +// netj->deadline_offset = (netj->period_usecs*90/100); +// } - netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline += netj->period_usecs; } else { netj->time_to_deadline = 0; - netj->next_deadline = jack_get_time() + netj->deadline_offset; + netj->next_deadline += netj->period_usecs; // bah... the packet is not there. // either // - it got lost. @@ -581,7 +584,13 @@ netjack_startup( netjack_driver_state_t *netj ) struct sockaddr_in address; // Now open the socket, and wait for the first packet to arrive... netj->sockfd = socket (AF_INET, SOCK_DGRAM, 0); + #ifdef WIN32 + u_long parm = 1; + DWORD bufsize = 262144; + //ioctlsocket( netj->sockfd, FIONBIO, &parm ); + setsockopt( netj->sockfd, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, sizeof(bufsize) ); + setsockopt( netj->sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, sizeof(bufsize) ); if (netj->sockfd == INVALID_SOCKET) #else if (netj->sockfd == -1) @@ -705,7 +714,7 @@ netjack_startup( netjack_driver_state_t *netj ) netj->period_usecs = (jack_time_t) floor ((((float) netj->period_size) / (float)netj->sample_rate) * 1000000.0f); - + if( netj->latency == 0 ) netj->deadline_offset = 50*netj->period_usecs; else @@ -716,7 +725,7 @@ netjack_startup( netjack_driver_state_t *netj ) // TODO: this is a hack. But i dont want to change the packet header. netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); - + netj->net_period_down = netj->resample_factor; netj->net_period_up = netj->resample_factor_up; } else { diff --git a/common/netjack_packet.c b/common/netjack_packet.c index 4edbb2a3..dfe3b9e2 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -26,7 +26,9 @@ * */ -//#include "config.h" +#ifdef __linux__ +#include "config.h" +#endif #ifdef __APPLE__ #define _DARWIN_C_SOURCE @@ -50,7 +52,9 @@ #ifdef WIN32 #include +#define socklen_t int #include +#define socklen_t int #else #include #include @@ -126,7 +130,7 @@ int get_sample_size (int bitdepth) if (bitdepth == 16) return sizeof (int16_t); //JN: why? is this for buffer sizes before or after encoding? - //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? + //JN: if the former, why not int16_t, if the latter, shouldn't it depend on -c N? if( bitdepth == CELT_MODE ) return sizeof( unsigned char ); return sizeof (int32_t); diff --git a/common/ringbuffer.c b/common/ringbuffer.c index f2096630..45ee27b3 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -70,7 +70,7 @@ jack_ringbuffer_create (size_t sz) int power_of_two; jack_ringbuffer_t *rb; - if ((rb = malloc (sizeof (jack_ringbuffer_t))) == NULL) { + if ((rb = (jack_ringbuffer_t *) malloc (sizeof (jack_ringbuffer_t))) == NULL) { return NULL; } @@ -81,7 +81,7 @@ jack_ringbuffer_create (size_t sz) rb->size_mask -= 1; rb->write_ptr = 0; rb->read_ptr = 0; - if ((rb->buf = malloc (rb->size)) == NULL) { + if ((rb->buf = (char *) malloc (rb->size)) == NULL) { free (rb); return NULL; } @@ -400,4 +400,5 @@ jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb, vec[0].len = free_cnt; vec[1].len = 0; } -} \ No newline at end of file +} + diff --git a/common/shm.c b/common/shm.c index fdd3b151..e74a2134 100644 --- a/common/shm.c +++ b/common/shm.c @@ -18,23 +18,23 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - -/* This module provides a set of abstract shared memory interfaces - * with support using both System V and POSIX shared memory - * implementations. The code is divided into three sections: - * - * - common (interface-independent) code - * - POSIX implementation - * - System V implementation - * - * The implementation used is determined by whether USE_POSIX_SHM was - * set in the ./configure step. - */ + +/* This module provides a set of abstract shared memory interfaces + * with support using both System V and POSIX shared memory + * implementations. The code is divided into three sections: + * + * - common (interface-independent) code + * - POSIX implementation + * - System V implementation + * + * The implementation used is determined by whether USE_POSIX_SHM was + * set in the ./configure step. + */ #include "JackConstants.h" #ifdef WIN32 -#include +#include #include #else @@ -145,23 +145,22 @@ static int semid = -1; #ifdef WIN32 -static void -semaphore_init () {} +static int +semaphore_init () {return 0;} -static void -semaphore_add (int value) {} +static int +semaphore_add (int value) {return 0;} #else /* all semaphore errors are fatal -- issue message, but do not return */ static void semaphore_error (char *msg) { - jack_error ("Fatal JACK semaphore error: %s (%s)", + jack_error ("JACK semaphore error: %s (%s)", msg, strerror (errno)); - abort (); } -static void +static int semaphore_init () { key_t semkey = JACK_SEMAPHORE_KEY; @@ -180,21 +179,26 @@ semaphore_init () sbuf.sem_op = 1; sbuf.sem_flg = 0; if (semop(semid, &sbuf, 1) == -1) { - semaphore_error ("semop"); + semaphore_error ("semop"); + return -1; } } else if (errno == EEXIST) { if ((semid = semget(semkey, 0, 0)) == -1) { - semaphore_error ("semget"); + semaphore_error ("semget"); + return -1; } } else { - semaphore_error ("semget creation"); + semaphore_error ("semget creation"); + return -1; } } + + return 0; } -static inline void +static inline int semaphore_add (int value) { struct sembuf sbuf; @@ -202,20 +206,26 @@ semaphore_add (int value) sbuf.sem_num = 0; sbuf.sem_op = value; sbuf.sem_flg = SEM_UNDO; + if (semop(semid, &sbuf, 1) == -1) { semaphore_error ("semop"); + return -1; } + + return 0; } #endif -static void +static int jack_shm_lock_registry (void) { - if (semid == -1) - semaphore_init (); + if (semid == -1) { + if (semaphore_init () < 0) + return -1; + } - semaphore_add (-1); + return semaphore_add (-1); } static void @@ -297,7 +307,10 @@ jack_server_initialize_shm (int new_registry) if (jack_shm_header) return 0; /* already initialized */ - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } rc = jack_access_registry (®istry_info); @@ -353,7 +366,11 @@ jack_initialize_shm (const char *server_name) jack_set_server_prefix (server_name); - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } + if ((rc = jack_access_registry (®istry_info)) == 0) { if ((rc = jack_shm_validate_registry ()) != 0) { jack_error ("Incompatible shm registry, " @@ -412,15 +429,20 @@ jack_release_shm_entry (jack_shm_registry_index_t index) sizeof (jack_shm_registry[index].id)); } -void +int jack_release_shm_info (jack_shm_registry_index_t index) { /* must NOT have the registry locked */ if (jack_shm_registry[index].allocator == GetPID()) { - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } jack_release_shm_entry (index); jack_shm_unlock_registry (); } + + return 0; } /* Claim server_name for this process. @@ -440,7 +462,10 @@ jack_register_server (const char *server_name, int new_registry) if (jack_server_initialize_shm (new_registry)) return ENOMEM; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } /* See if server_name already registered. Since server names * are per-user, we register the unique server prefix string. @@ -493,11 +518,14 @@ jack_register_server (const char *server_name, int new_registry) } /* release server_name registration */ -void +int jack_unregister_server (const char *server_name /* unused */) { int i; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } for (i = 0; i < MAX_SERVERS; i++) { if (jack_shm_header->server[i].pid == GetPID()) { @@ -506,7 +534,8 @@ jack_unregister_server (const char *server_name /* unused */) } } - jack_shm_unlock_registry (); + jack_shm_unlock_registry (); + return 0; } /* called for server startup and termination */ @@ -517,7 +546,10 @@ jack_cleanup_shm () int destroy; jack_shm_info_t copy; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } for (i = 0; i < MAX_SHM_ID; i++) { jack_shm_registry_t* r; @@ -741,7 +773,10 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) int rc = -1; char name[SHM_NAME_MAX+1]; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } if ((registry = jack_get_free_shm_info ()) == NULL) { jack_error ("shm registry full"); @@ -780,7 +815,7 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) close (shm_fd); registry->size = size; strncpy (registry->id, name, sizeof (registry->id)); - registry->allocator = getpid(); + registry->allocator = GetPID(); si->index = registry->index; si->ptr.attached_at = MAP_FAILED; /* not attached */ rc = 0; /* success */ @@ -936,7 +971,10 @@ jack_shmalloc (const char *shm_name, jack_shmsize_t size, jack_shm_info_t* si) int rc = -1; char name[SHM_NAME_MAX+1]; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } if ((registry = jack_get_free_shm_info ()) == NULL) { jack_error ("shm registry full"); @@ -1133,7 +1171,10 @@ jack_shmalloc (const char* name_not_used, jack_shmsize_t size, int rc = -1; jack_shm_registry_t* registry; - jack_shm_lock_registry (); + if (jack_shm_lock_registry () < 0) { + jack_error ("jack_shm_lock_registry fails..."); + return -1; + } if ((registry = jack_get_free_shm_info ())) { diff --git a/common/shm.h b/common/shm.h index 4a7d15c6..ed5a953f 100644 --- a/common/shm.h +++ b/common/shm.h @@ -115,33 +115,33 @@ extern "C" * indicating where the shared memory has been * attached to the address space. */ - + typedef struct _jack_shm_info { jack_shm_registry_index_t index; /* offset into the registry */ uint32_t size; union { void *attached_at; /* address where attached */ - char ptr_size[8]; - } ptr; /* a "pointer" that has the same 8 bytes size when compling in 32 or 64 bits */ + char ptr_size[8]; + } ptr; /* a "pointer" that has the same 8 bytes size when compling in 32 or 64 bits */ } POST_PACKED_STRUCTURE jack_shm_info_t; /* utility functions used only within JACK */ - + void jack_shm_copy_from_registry (jack_shm_info_t*, jack_shm_registry_index_t); void jack_shm_copy_to_registry (jack_shm_info_t*, jack_shm_registry_index_t*); - void jack_release_shm_info (jack_shm_registry_index_t); - char* jack_shm_addr (jack_shm_info_t* si); + int jack_release_shm_info (jack_shm_registry_index_t); + char* jack_shm_addr (jack_shm_info_t* si); - // here begin the API + // here begin the API int jack_register_server (const char *server_name, int new_registry); - void jack_unregister_server (const char *server_name); + int jack_unregister_server (const char *server_name); int jack_initialize_shm (const char *server_name); - int jack_initialize_shm_server (void); - int jack_initialize_shm_client (void); + int jack_initialize_shm_server (void); + int jack_initialize_shm_client (void); int jack_cleanup_shm (void); int jack_shmalloc (const char *shm_name, jack_shmsize_t size, @@ -149,7 +149,7 @@ extern "C" void jack_release_shm (jack_shm_info_t*); void jack_destroy_shm (jack_shm_info_t*); int jack_attach_shm (jack_shm_info_t*); - int jack_attach_shm_read (jack_shm_info_t*); + int jack_attach_shm_read (jack_shm_info_t*); int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size); #ifdef __cplusplus diff --git a/common/wscript b/common/wscript index 951ab68b..4af4f268 100644 --- a/common/wscript +++ b/common/wscript @@ -130,7 +130,8 @@ def build(bld): 'JackNetTool.cpp', 'JackNetInterface.cpp', 'JackArgParser.cpp', - 'JackDummyDriver.cpp', + 'JackPhysicalMidiInput.cpp', + 'JackPhysicalMidiOutput.cpp', ] if bld.env['IS_LINUX']: diff --git a/dbus/controller_iface_control.c b/dbus/controller_iface_control.c index 768c192f..ca3ab038 100644 --- a/dbus/controller_iface_control.c +++ b/dbus/controller_iface_control.c @@ -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; diff --git a/dbus/controller_iface_patchbay.c b/dbus/controller_iface_patchbay.c index 9adb7cfa..ed477d7d 100644 --- a/dbus/controller_iface_patchbay.c +++ b/dbus/controller_iface_patchbay.c @@ -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) diff --git a/dbus/jackdbus.c b/dbus/jackdbus.c index ef03680f..eb86308b 100644 --- a/dbus/jackdbus.c +++ b/dbus/jackdbus.c @@ -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) { diff --git a/dbus/jackdbus.h b/dbus/jackdbus.h index d94bc334..d920cf06 100644 --- a/dbus/jackdbus.h +++ b/dbus/jackdbus.h @@ -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, diff --git a/dbus/wscript b/dbus/wscript index e23e67b0..a4066b57 100644 --- a/dbus/wscript +++ b/dbus/wscript @@ -10,11 +10,15 @@ def set_options(opt): opt.add_option('--enable-pkg-config-dbus-service-dir', action='store_true', default=False, help='force D-Bus service install dir to be one returned by pkg-config') def configure(conf): - if not conf.check_cfg(package='dbus-1', atleast_version='1.0.0', args='--cflags --libs'): + conf.env['BUILD_JACKDBUS'] = False + + if not conf.check_cfg(package='dbus-1', atleast_version='1.0.0', args='--cflags --libs') or not conf.is_defined('HAVE_DBUS_1'): + print Logs.colors.RED + 'WARNING !! jackdbus will not be built because libdbus-dev is missing' + Logs.colors.NORMAL return dbus_dir = conf.check_cfg(package='dbus-1', args='--variable=session_bus_services_dir') if not dbus_dir: + print Logs.colors.RED + 'WARNING !! jackdbus will not be built because service dir is unknown' + Logs.colors.NORMAL return dbus_dir = dbus_dir.strip() @@ -31,15 +35,13 @@ def configure(conf): if conf.is_defined('HAVE_EXPAT'): conf.env['LIB_EXPAT'] = ['expat'] + else: + print Logs.colors.RED + 'WARNING !! jackdbus will not be built because of expat is missing' + Logs.colors.NORMAL + return - conf.env['BUILD_JACKDBUS1'] = conf.is_defined('HAVE_EXPAT') and conf.is_defined('HAVE_DBUS_1') - + conf.env['BUILD_JACKDBUS'] = True def build(bld): - - if bld.env['BUILD_JACKDBUS1'] != True: - return - obj = bld.new_task_gen('cc', 'program') if bld.env['IS_LINUX']: sysdeps_dbus_include = ['../linux', '../posix'] diff --git a/doxyfile b/doxyfile index 0ba53fc0..bc5116a0 100644 --- a/doxyfile +++ b/doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = "Jack2" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.9.4 +PROJECT_NUMBER = 1.9.5 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/example-clients/alsa_in.c b/example-clients/alsa_in.c index 2a8b78c3..a04271eb 100644 --- a/example-clients/alsa_in.c +++ b/example-clients/alsa_in.c @@ -184,7 +184,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ } /* set the buffer time */ - buffer_time = 1000000*period*nperiods/rate; + buffer_time = 1000000*(uint64_t)period*nperiods/rate; err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir); if (err < 0) { printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err)); @@ -199,7 +199,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size ); } /* set the period time */ - period_time = 1000000*period/rate; + period_time = 1000000*(uint64_t)period/rate; err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir); if (err < 0) { printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err)); diff --git a/example-clients/alsa_out.c b/example-clients/alsa_out.c index 2d34cd13..852e978c 100644 --- a/example-clients/alsa_out.c +++ b/example-clients/alsa_out.c @@ -183,7 +183,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ } /* set the buffer time */ - buffer_time = 1000000*period*nperiods/rate; + buffer_time = 1000000*(uint64_t)period*nperiods/rate; err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, &dir); if (err < 0) { printf("Unable to set buffer time %i for playback: %s\n", 1000000*period*nperiods/rate, snd_strerror(err)); @@ -198,7 +198,7 @@ static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_ printf( "WARNING: buffer size does not match: (requested %d, got %d)\n", nperiods * period, (int) real_buffer_size ); } /* set the period time */ - period_time = 1000000*period/rate; + period_time = 1000000*(uint64_t)period/rate; err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, &dir); if (err < 0) { printf("Unable to set period time %i for playback: %s\n", 1000000*period/rate, snd_strerror(err)); diff --git a/example-clients/jack_control b/example-clients/jack_control index c7b2dab5..1d06436b 100755 --- a/example-clients/jack_control +++ b/example-clients/jack_control @@ -106,9 +106,9 @@ def main(): print "Usage: %s [command] [command] ..." % os.path.basename(sys.argv[0]) print "Commands:" print " exit - exit jack dbus service (stops jack server if currently running)" - print " status - check whether jack server is started, return value is 0 if runing and 1 otherwise" + print " status - check whether jack server is started, return value is 0 if running and 1 otherwise" print " start - start jack server if not currently started" - print " stop - stop jack server if currenly started" + print " stop - stop jack server if currently started" print " sm - switch master to currently selected driver" print " dl - get list of available drivers" print " dg - get currently selected driver" diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index c9d5be48..3ca00900 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -136,8 +136,14 @@ main (int argc, char *argv[]) for (i = 0; i < result.audio_output; i++) { audio_output_buffer[i] = calloc(buffer_size, sizeof(float)); } - - // Run until interrupted + + /* + Run until interrupted. + + WARNING !! : this code is given for demonstration purpose. For proper timing bevahiour + it has to be called in a real-time context (which is *not* the case here...) + */ + while (1) { // Copy input to output diff --git a/example-clients/netsource.c b/example-clients/netsource.c index ed4c1af0..d6d252c2 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -34,8 +34,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include +#ifdef __linux__ +#include "config.h" +#endif + #ifdef WIN32 #include +#define socklen_t int #include #else #include @@ -753,7 +758,7 @@ main (int argc, char *argv[]) if (statecopy_netxruns != state_netxruns) { statecopy_netxruns = state_netxruns; printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", - client_name, + client_name, state_currentframe, statecopy_netxruns, 100*statecopy_netxruns/state_currentframe, diff --git a/example-clients/wscript b/example-clients/wscript index 152c737d..215be593 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -51,10 +51,11 @@ def configure(conf): e = conf.check_cc(lib='readline', define_name="HAVE_READLINE") - if conf.is_defined('HAVE_READLINE'): - conf.env['LIB_READLINE'] = ['readline'] + # define_name="HAVE_READLINE" has no effect, LIB_READLINE is defined if readline is available + #if conf.is_defined('HAVE_READLINE'): + # conf.env['LIB_READLINE'] = ['readline'] - conf.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] = conf.is_defined('HAVE_READLINE') and conf.is_defined('HAVE_NCURSES') + conf.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] = bool(conf.env['LIB_READLINE']) and bool(conf.env['LIB_NCURSES']) conf.env['BUILD_EXAMPLE_CLIENT_REC'] = conf.is_defined('HAVE_SNDFILE') diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 45486f53..8c0168e5 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -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; + } } } diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index b6080d69..be2f3359 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -2,6 +2,7 @@ Copyright (C) 2001 Paul Davis Copyright (C) 2004 Grame Copyright (C) 2007 Pieter Palmers +Copyright (C) 2009 Devin Anderson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,6 +36,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include "JackFFADODriver.h" +#include "JackFFADOMidiInput.h" +#include "JackFFADOMidiOutput.h" #include "JackEngineControl.h" #include "JackClientControl.h" #include "JackPort.h" @@ -91,29 +94,14 @@ JackFFADODriver::ffado_driver_read (ffado_driver_t * driver, jack_nframes_t nfra /* process the midi data */ for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].stream_type == ffado_stream_type_midi) { - jack_nframes_t i; - int done; - uint32_t *midi_buffer = driver->capture_channels[chn].midi_buffer; - midi_unpack_t *midi_unpack = &driver->capture_channels[chn].midi_unpack; - buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[chn], nframes); - jack_midi_clear_buffer(buf); - - /* if the returned buffer is invalid, discard the midi data */ - if (!buf) continue; - /* else unpack - note that libffado guarantees that midi bytes are on 8-byte aligned indexes - */ - for (i = 0; i < nframes; i += 8) { - if (midi_buffer[i] & 0xFF000000) { - done = midi_unpack_buf(midi_unpack, (unsigned char *)(midi_buffer + i), 1, buf, i); - if (done != 1) { - printError("buffer overflow in channel %d\n", chn); - break; - } - - printMessage("MIDI IN: %08X (i=%d)", midi_buffer[i], i); - } + JackFFADOMidiInput *midi_input = (JackFFADOMidiInput *) driver->capture_channels[chn].midi_input; + JackMidiBuffer *buffer = (JackMidiBuffer *) fGraphManager->GetBuffer(fCapturePortList[chn], nframes); + if (! buffer) { + continue; } + midi_input->SetInputBuffer(driver->capture_channels[chn].midi_buffer); + midi_input->SetPortBuffer(buffer); + midi_input->Process(nframes); } } @@ -146,80 +134,20 @@ JackFFADODriver::ffado_driver_write (ffado_driver_t * driver, jack_nframes_t nfr ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(buf)); ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); } else if (driver->playback_channels[chn].stream_type == ffado_stream_type_midi) { - jack_nframes_t nevents; - jack_nframes_t i; - midi_pack_t *midi_pack = &driver->playback_channels[chn].midi_pack; uint32_t *midi_buffer = driver->playback_channels[chn].midi_buffer; - buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); - jack_nframes_t min_next_pos = 0; - memset(midi_buffer, 0, nframes * sizeof(uint32_t)); + buf = (jack_default_audio_sample_t *) fGraphManager->GetBuffer(fPlaybackPortList[chn], nframes); ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(midi_buffer)); - /* if the returned buffer is invalid, continue */ if (!buf) { ffado_streaming_playback_stream_onoff(driver->dev, chn, 0); continue; } ffado_streaming_playback_stream_onoff(driver->dev, chn, 1); - - // check if we still have to process bytes from the previous period - if (driver->playback_channels[chn].nb_overflow_bytes) { - printMessage("have to process %d bytes from previous period", driver->playback_channels[chn].nb_overflow_bytes); - } - for (i = 0; i < driver->playback_channels[chn].nb_overflow_bytes; ++i) { - midi_buffer[min_next_pos] = 0x01000000 | (driver->playback_channels[chn].overflow_buffer[i] & 0xFF); - min_next_pos += 8; - } - driver->playback_channels[chn].nb_overflow_bytes = 0; - - // process the events in this period - nevents = jack_midi_get_event_count(buf); - //if (nevents) - // printMessage("MIDI: %d events in ch %d", nevents, chn); - - for (i = 0; i < nevents; ++i) { - size_t j; - jack_midi_event_t event; - jack_midi_event_get(&event, buf, i); - - midi_pack_event(midi_pack, &event); - - // floor the initial position to be a multiple of 8 - jack_nframes_t pos = event.time & 0xFFFFFFF8; - for (j = 0; j < event.size; j++) { - // make sure we don't overwrite a previous byte - while (pos < min_next_pos && pos < nframes) { - pos += 8; - printMessage("have to correct pos to %d", pos); - } - - if (pos >= nframes) { - unsigned int f; - printMessage("midi message crosses period boundary"); - driver->playback_channels[chn].nb_overflow_bytes = event.size - j; - if (driver->playback_channels[chn].nb_overflow_bytes > MIDI_OVERFLOW_BUFFER_SIZE) { - printError("too much midi bytes cross period boundary"); - driver->playback_channels[chn].nb_overflow_bytes = MIDI_OVERFLOW_BUFFER_SIZE; - } - // save the bytes that still have to be transmitted in the next period - for (f = 0; f < driver->playback_channels[chn].nb_overflow_bytes; f++) { - driver->playback_channels[chn].overflow_buffer[f] = event.buffer[j+f]; - } - // exit since we can't transmit anything anymore. - // the rate should be controlled - if (i < nevents - 1) { - printError("%d midi events lost due to period crossing", nevents - i - 1); - } - break; - } else { - midi_buffer[pos] = 0x01000000 | (event.buffer[j] & 0xFF); - pos += 8; - min_next_pos = pos; - } - } - //printMessage("MIDI: sent %d-byte event at %ld", (int)event.size, (long)event.time); - } + JackFFADOMidiOutput *midi_output = (JackFFADOMidiOutput *) driver->playback_channels[chn].midi_output; + midi_output->SetPortBuffer((JackMidiBuffer *) buf); + midi_output->SetOutputBuffer(midi_buffer); + midi_output->Process(nframes); } else { // always have a valid buffer ffado_streaming_set_playback_stream_buffer(driver->dev, chn, (char *)(driver->nullbuffer)); @@ -279,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; } @@ -541,9 +474,7 @@ int JackFFADODriver::Attach() printError(" cannot enable port %s", buf); } - // setup midi unpacker - midi_unpack_init(&driver->capture_channels[chn].midi_unpack); - midi_unpack_reset(&driver->capture_channels[chn].midi_unpack); + driver->capture_channels[chn].midi_input = new JackFFADOMidiInput(); // setup the midi buffer driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); @@ -616,9 +547,13 @@ int JackFFADODriver::Attach() if (ffado_streaming_playback_stream_onoff(driver->dev, chn, 0)) { printError(" cannot enable port %s", buf); } - // setup midi packer - midi_pack_reset(&driver->playback_channels[chn].midi_pack); // setup the midi buffer + + // This constructor optionally accepts arguments for the + // non-realtime buffer size and the realtime buffer size. Ideally, + // these would become command-line options for the FFADO driver. + driver->playback_channels[chn].midi_output = new JackFFADOMidiOutput(); + driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t)); port = fGraphManager->GetPort(port_index); @@ -658,12 +593,16 @@ int JackFFADODriver::Detach() for (chn = 0; chn < driver->capture_nchannels; chn++) { if (driver->capture_channels[chn].midi_buffer) free(driver->capture_channels[chn].midi_buffer); + if (driver->capture_channels[chn].midi_input) + delete ((JackFFADOMidiInput *) (driver->capture_channels[chn].midi_input)); } free(driver->capture_channels); for (chn = 0; chn < driver->playback_nchannels; chn++) { if (driver->playback_channels[chn].midi_buffer) free(driver->playback_channels[chn].midi_buffer); + if (driver->playback_channels[chn].midi_output) + delete ((JackFFADOMidiOutput *) (driver->playback_channels[chn].midi_output)); } free(driver->playback_channels); diff --git a/linux/firewire/JackFFADOMidiInput.cpp b/linux/firewire/JackFFADOMidiInput.cpp new file mode 100644 index 00000000..38ed539b --- /dev/null +++ b/linux/firewire/JackFFADOMidiInput.cpp @@ -0,0 +1,59 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackFFADOMidiInput.h" + +namespace Jack { + +JackFFADOMidiInput::JackFFADOMidiInput(size_t buffer_size): + JackPhysicalMidiInput(buffer_size) +{ + new_period = true; +} + +JackFFADOMidiInput::~JackFFADOMidiInput() +{ + // Empty +} + +jack_nframes_t +JackFFADOMidiInput::Receive(jack_midi_data_t *datum, + jack_nframes_t current_frame, + jack_nframes_t total_frames) +{ + assert(input_buffer); + if (! new_period) { + current_frame += 8; + } else { + new_period = false; + } + for (; current_frame < total_frames; current_frame += 8) { + uint32_t data = input_buffer[current_frame]; + if (data & 0xff000000) { + *datum = (jack_midi_data_t) (data & 0xff); + return current_frame; + } + } + new_period = true; + return total_frames; +} + +} diff --git a/linux/firewire/JackFFADOMidiInput.h b/linux/firewire/JackFFADOMidiInput.h new file mode 100644 index 00000000..12dc043c --- /dev/null +++ b/linux/firewire/JackFFADOMidiInput.h @@ -0,0 +1,54 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiInput__ +#define __JackFFADOMidiInput__ + +#include "JackPhysicalMidiInput.h" + +namespace Jack { + + class JackFFADOMidiInput: public JackPhysicalMidiInput { + + private: + + uint32_t *input_buffer; + bool new_period; + + protected: + + jack_nframes_t + Receive(jack_midi_data_t *, jack_nframes_t, jack_nframes_t); + + public: + + JackFFADOMidiInput(size_t buffer_size=1024); + ~JackFFADOMidiInput(); + + inline void + SetInputBuffer(uint32_t *input_buffer) + { + this->input_buffer = input_buffer; + } + + }; + +} + +#endif diff --git a/linux/firewire/JackFFADOMidiOutput.cpp b/linux/firewire/JackFFADOMidiOutput.cpp new file mode 100644 index 00000000..995f2d28 --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutput.cpp @@ -0,0 +1,60 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include + +#include "JackError.h" +#include "JackFFADOMidiOutput.h" + +namespace Jack { + +JackFFADOMidiOutput::JackFFADOMidiOutput(size_t non_rt_buffer_size, + size_t rt_buffer_size): + JackPhysicalMidiOutput(non_rt_buffer_size, rt_buffer_size) +{ + // Empty +} + +JackFFADOMidiOutput::~JackFFADOMidiOutput() +{ + // Empty +} + +jack_nframes_t +JackFFADOMidiOutput::Advance(jack_nframes_t current_frame) +{ + if (current_frame % 8) { + current_frame = (current_frame & (~ ((jack_nframes_t) 7))) + 8; + } + return current_frame; +} + +jack_nframes_t +JackFFADOMidiOutput::Send(jack_nframes_t current_frame, jack_midi_data_t datum) +{ + assert(output_buffer); + + jack_log("JackFFADOMidiOutput::Send (%d) - Sending '%x' byte.", + current_frame, (unsigned int) datum); + + output_buffer[current_frame] = 0x01000000 | ((uint32_t) datum); + return current_frame + 8; +} + +} diff --git a/linux/firewire/JackFFADOMidiOutput.h b/linux/firewire/JackFFADOMidiOutput.h new file mode 100644 index 00000000..309e7f61 --- /dev/null +++ b/linux/firewire/JackFFADOMidiOutput.h @@ -0,0 +1,57 @@ +/* +Copyright (C) 2009 Devin Anderson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifndef __JackFFADOMidiOutput__ +#define __JackFFADOMidiOutput__ + +#include "JackPhysicalMidiOutput.h" + +namespace Jack { + + class JackFFADOMidiOutput: public JackPhysicalMidiOutput { + + private: + + uint32_t *output_buffer; + + protected: + + jack_nframes_t + Advance(jack_nframes_t); + + jack_nframes_t + Send(jack_nframes_t, jack_midi_data_t); + + public: + + JackFFADOMidiOutput(size_t non_rt_buffer_size=1024, + size_t rt_buffer_size=64); + ~JackFFADOMidiOutput(); + + inline void + SetOutputBuffer(uint32_t *output_buffer) + { + this->output_buffer = output_buffer; + } + + }; + +} + +#endif diff --git a/linux/firewire/ffado_driver.h b/linux/firewire/ffado_driver.h index a851d845..a06c1361 100644 --- a/linux/firewire/ffado_driver.h +++ b/linux/firewire/ffado_driver.h @@ -7,6 +7,7 @@ * http://www.jackaudio.org * * Copyright (C) 2005-2007 Pieter Palmers + * Copyright (C) 2009 Devin Anderson * * adapted for JackMP by Pieter Palmers * @@ -51,9 +52,7 @@ #include #include -#include -#include "../alsa/midi_pack.h" -#include "../alsa/midi_unpack.h" +//#include // debug print control flags #define DEBUG_LEVEL_BUFFERS (1<<0) @@ -143,21 +142,16 @@ struct _ffado_jack_settings typedef struct _ffado_capture_channel { ffado_streaming_stream_type stream_type; - midi_unpack_t midi_unpack; uint32_t *midi_buffer; + void *midi_input; } ffado_capture_channel_t; -#define MIDI_OVERFLOW_BUFFER_SIZE 4 typedef struct _ffado_playback_channel { ffado_streaming_stream_type stream_type; - midi_pack_t midi_pack; uint32_t *midi_buffer; - // to hold the midi bytes that couldn't be transferred - // during the previous period - char overflow_buffer[MIDI_OVERFLOW_BUFFER_SIZE]; - unsigned int nb_overflow_bytes; + void *midi_output; } ffado_playback_channel_t; diff --git a/linux/wscript b/linux/wscript index 56a77330..869985d4 100644 --- a/linux/wscript +++ b/linux/wscript @@ -2,7 +2,7 @@ # encoding: utf-8 def configure(conf): - conf.check_cfg(package='alsa', atleast_version='1.0.0', args='--cflags --libs') + conf.check_cfg(package='alsa', atleast_version='1.0.18', args='--cflags --libs') conf.env['BUILD_DRIVER_ALSA'] = conf.is_defined('HAVE_ALSA') conf. check_cfg(package='libfreebob', atleast_version='1.0.0', args='--cflags --libs') @@ -55,6 +55,13 @@ def build(bld): 'alsa/ice1712.c' ] + ffado_driver_src = ['firewire/JackFFADODriver.cpp', + 'firewire/JackFFADOMidiInput.cpp', + 'firewire/JackFFADOMidiOutput.cpp', + '../common/JackPhysicalMidiInput.cpp', + '../common/JackPhysicalMidiOutput.cpp' + ] + if bld.env['BUILD_DRIVER_ALSA'] == True: create_jack_driver_obj(bld, 'alsa', alsa_driver_src, "ALSA") @@ -62,7 +69,7 @@ def build(bld): create_jack_driver_obj(bld, 'freebob', 'freebob/JackFreebobDriver.cpp', "LIBFREEBOB") if bld.env['BUILD_DRIVER_FFADO'] == True: - create_jack_driver_obj(bld, 'firewire', 'firewire/JackFFADODriver.cpp', "LIBFFADO") + create_jack_driver_obj(bld, 'firewire', ffado_driver_src, "LIBFFADO") create_jack_driver_obj(bld, 'net', '../common/JackNetDriver.cpp') diff --git a/macosx/Jack-Info.plist b/macosx/Jack-Info.plist index 1e5eb07e..8b6a61de 100644 --- a/macosx/Jack-Info.plist +++ b/macosx/Jack-Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable Jackservermp CFBundleGetInfoString - Jackdmp 1.9.4, @03-09 Paul Davis, Grame + Jackdmp 1.9.5, @03-09 Paul Davis, Grame CFBundleIdentifier com.grame.Jackmp CFBundleInfoDictionaryVersion @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.9.4 + 1.9.5 diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp index 4ddb0b1c..fb95621d 100644 --- a/macosx/JackMacEngineRPC.cpp +++ b/macosx/JackMacEngineRPC.cpp @@ -18,9 +18,11 @@ This program is free software; you can redistribute it and/or modify */ #include "JackServer.h" +#include "JackNotification.h" #include "JackLockedEngine.h" #include "JackRPCEngine.h" #include "JackMachServerChannel.h" +#include "JackException.h" #include using namespace Jack; @@ -238,6 +240,11 @@ rpc_type server_rpc_jack_client_rt_notify(mach_port_t server_port, int refnum, i JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; assert(channel); assert(channel->GetServer()); - channel->GetServer()->Notify(refnum, notify, value); - return KERN_SUCCESS; + + if (notify == kQUIT) { + throw JackQuitException(); + } else { + channel->GetServer()->Notify(refnum, notify, value); + return KERN_SUCCESS; + } } diff --git a/macosx/JackMachClientChannel.cpp b/macosx/JackMachClientChannel.cpp index c666bbb3..f5f88504 100644 --- a/macosx/JackMachClientChannel.cpp +++ b/macosx/JackMachClientChannel.cpp @@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackRPCClientServer.c" #include "JackError.h" #include "JackLibClient.h" -#include "JackLibGlobals.h" #include "JackMachThread.h" #include "JackConstants.h" diff --git a/macosx/JackMachServerChannel.cpp b/macosx/JackMachServerChannel.cpp index 19295f79..fcf4fe8c 100644 --- a/macosx/JackMachServerChannel.cpp +++ b/macosx/JackMachServerChannel.cpp @@ -58,7 +58,12 @@ int JackMachServerChannel::Open(const char* server_name, JackServer* server) void JackMachServerChannel::Close() { jack_log("JackMachServerChannel::Close"); + #ifdef MAC_OS_X_VERSION_10_5 + // Exception does not work in this case on pre Snow Loopard systems, see JackMachServerNotifyChannel::NotifyQuit() fThread.Kill(); + #else + fThread.Stop(); + #endif fServerPort.DestroyPort(); } @@ -149,12 +154,19 @@ boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach bool JackMachServerChannel::Execute() { - kern_return_t res; - if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) { - jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res)); + try { + + kern_return_t res; + if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) { + jack_log("JackMachServerChannel::Execute: err = %s", mach_error_string(res)); + return false; + } + return true; + + } catch (JackQuitException& e) { + jack_log("JackMachServerChannel::Execute JackQuitException"); + return false; } - //return (res == KERN_SUCCESS); mach_msg_server can fail if the client reply port is not valid anymore (crashed client) - return true; } } // end of namespace diff --git a/macosx/JackMachServerNotifyChannel.cpp b/macosx/JackMachServerNotifyChannel.cpp index 2e1c9abe..f55ce09e 100644 --- a/macosx/JackMachServerNotifyChannel.cpp +++ b/macosx/JackMachServerNotifyChannel.cpp @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackMachServerNotifyChannel.h" #include "JackRPCEngineUser.c" +#include "JackNotification.h" #include "JackTools.h" #include "JackConstants.h" #include "JackError.h" @@ -42,9 +43,7 @@ int JackMachServerNotifyChannel::Open(const char* server_name) } void JackMachServerNotifyChannel::Close() -{ - //fClientPort.DisconnectPort(); pas nŽcessaire car le JackMachServerChannel a dŽja disparu? -} +{} void JackMachServerNotifyChannel::Notify(int refnum, int notify, int value) { @@ -53,6 +52,18 @@ void JackMachServerNotifyChannel::Notify(int refnum, int notify, int value) jack_error("Could not write request ref = %d notify = %d err = %s", refnum, notify, mach_error_string(res)); } } + +void JackMachServerNotifyChannel::NotifyQuit() +{ + #ifdef MAC_OS_X_VERSION_10_5 + // Nothing : since exception does not work in this case on pre Snow Loopard systems, see JackMachServerChannel::Close() + #else + kern_return_t res = rpc_jack_client_rt_notify(fClientPort.GetPort(), -1, kQUIT, 0, 0); + if (res != KERN_SUCCESS) { + jack_error("Could not write request ref = %d notify = %d err = %s", -1, kQUIT, mach_error_string(res)); + } +#endif +} } // end of namespace diff --git a/macosx/JackMachServerNotifyChannel.h b/macosx/JackMachServerNotifyChannel.h index 98523a84..8eb7b72f 100644 --- a/macosx/JackMachServerNotifyChannel.h +++ b/macosx/JackMachServerNotifyChannel.h @@ -46,7 +46,8 @@ class JackMachServerNotifyChannel void Close(); // Close the Server/Client connection void Notify(int refnum, int notify, int value); -}; + void NotifyQuit(); +}; } // end of namespace diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index f7c038c0..ac96f4a0 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -61,8 +61,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackMachThread__ #define __JackMachThread__ +#include + +#ifdef TARGET_OS_IPHONE +typedef unsigned char Boolean; +#endif + + #include "JackPosixThread.h" +#ifndef TARGET_OS_IPHONE #import +#endif #include #include diff --git a/macosx/JackPlatformPlug_os.h b/macosx/JackPlatformPlug_os.h index c52a259f..df7f0175 100644 --- a/macosx/JackPlatformPlug_os.h +++ b/macosx/JackPlatformPlug_os.h @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackPlatformPlug_APPLE__ #define __JackPlatformPlug_APPLE__ +#include + namespace Jack { class JackPosixMutex; @@ -42,13 +44,16 @@ namespace Jack { typedef JackPosixMutex JackMutex; } namespace Jack { typedef JackMachThread JackThread; } /* __JackPlatformSynchro__ client activation */ +#ifndef TARGET_OS_IPHONE #include "JackMachSemaphore.h" namespace Jack { typedef JackMachSemaphore JackSynchro; } +#endif /* __JackPlatformProcessSync__ */ #include "JackProcessSync.h" /* Only on windows a special JackProcessSync is used. It is directly defined by including JackProcessSync.h here */ +#ifndef TARGET_OS_IPHONE /* __JackPlatformServerChannel__ */ #include "JackMachServerChannel.h" namespace Jack { typedef JackMachServerChannel JackServerChannel; } @@ -64,6 +69,7 @@ namespace Jack { typedef JackMachServerNotifyChannel JackServerNotifyChannel; } /* __JackPlatformNotifyChannel__ */ #include "JackMachNotifyChannel.h" namespace Jack { typedef JackMachNotifyChannel JackNotifyChannel; } +#endif /* __JackPlatformNetSocket__ */ #include "JackNetUnixSocket.h" diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index c8aae4f5..461f827b 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -323,6 +323,83 @@ 4B43A8CB1014605000E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8DF1014615800E52943 /* JackLoopbackDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */; }; 4B43A8E11014615800E52943 /* JackLoopbackDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B43A8C81014605000E52943 /* JackLoopbackDriver.cpp */; }; + 4B47AC8210B5890100469C67 /* JackMachPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B799AD707899652003F3F15 /* JackMachPort.h */; }; + 4B47AC8310B5890100469C67 /* JackError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1770834EE4800C94B91 /* JackError.h */; }; + 4B47AC8410B5890100469C67 /* JackTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1830834EE5800C94B91 /* JackTime.h */; }; + 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1870834EE7900C94B91 /* JackShmMem.h */; }; + 4B47AC8610B5890100469C67 /* shm.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D18F0834EE8400C94B91 /* shm.h */; }; + 4B47AC8710B5890100469C67 /* JackThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D19F0834EE9E00C94B91 /* JackThread.h */; }; + 4B47AC8810B5890100469C67 /* JackActivationCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1A70834EEB400C94B91 /* JackActivationCount.h */; }; + 4B47AC8910B5890100469C67 /* JackChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */; }; + 4B47AC8A10B5890100469C67 /* JackGraphManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C70834EF2200C94B91 /* JackGraphManager.h */; }; + 4B47AC8B10B5890100469C67 /* JackPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1CF0834EF2F00C94B91 /* JackPort.h */; }; + 4B47AC8C10B5890100469C67 /* JackClientInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1D90834EF4500C94B91 /* JackClientInterface.h */; }; + 4B47AC8D10B5890100469C67 /* JackClientControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1DD0834EF4D00C94B91 /* JackClientControl.h */; }; + 4B47AC8E10B5890100469C67 /* JackClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1E10834EF5500C94B91 /* JackClient.h */; }; + 4B47AC8F10B5890100469C67 /* JackInternalClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1EE0834EF9200C94B91 /* JackInternalClient.h */; }; + 4B47AC9010B5890100469C67 /* JackLibGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FB0834EFD100C94B91 /* JackLibGlobals.h */; }; + 4B47AC9110B5890100469C67 /* JackLibClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1FC0834EFD100C94B91 /* JackLibClient.h */; }; + 4B47AC9210B5890100469C67 /* JackConnectionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8D1C30834EF1400C94B91 /* JackConnectionManager.h */; }; + 4B47AC9310B5890100469C67 /* JackFrameTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */; }; + 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF6C1D608ACE64C001E2013 /* JackMachSemaphore.h */; }; + 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB73F608AD291A00DB99B8 /* JackGlobals.h */; }; + 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB741F08AD2B9900DB99B8 /* JackMachThread.h */; }; + 4B47AC9710B5890100469C67 /* JackMachClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BFB298708AF450200D450D4 /* JackMachClientChannel.h */; }; + 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD561C708EEB910006BBC2A /* JackSynchro.h */; }; + 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B98AE010931D30C0091932A /* JackDebugClient.h */; }; + 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B66A8580934964500A89560 /* JackConstants.h */; }; + 4B47AC9B10B5890100469C67 /* JackTransportEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */; }; + 4B47AC9C10B5890100469C67 /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47AC9D10B5890100469C67 /* intclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C73790CC60A6D001AFFD4 /* intclient.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47AC9E10B5890100469C67 /* jack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737A0CC60A6D001AFFD4 /* jack.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47AC9F10B5890100469C67 /* ringbuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737B0CC60A6D001AFFD4 /* ringbuffer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA010B5890100469C67 /* statistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737C0CC60A6D001AFFD4 /* statistics.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA110B5890100469C67 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737D0CC60A6D001AFFD4 /* thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA210B5890100469C67 /* transport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737E0CC60A6D001AFFD4 /* transport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA310B5890100469C67 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6C737F0CC60A6D001AFFD4 /* types.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA410B5890100469C67 /* JackPortType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAB95B70B9E20B800A0C723 /* JackPortType.h */; }; + 4B47ACA510B5890100469C67 /* JackMidiPort.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */; }; + 4B47ACA610B5890100469C67 /* midiport.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B6B9EF50CD0958B0051EE5A /* midiport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA710B5890100469C67 /* JackTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4CC000CDA153400CCF5BB /* JackTools.h */; }; + 4B47ACA810B5890100469C67 /* jslist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B9A26000DBF8584006E9FBC /* jslist.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4F9C8B0DC20C0400706CB0 /* JackMessageBuffer.h */; }; + 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; + 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BECB2F40F4451C10091B70A /* JackProcessSync.h */; }; + 4B47ACAE10B5890100469C67 /* JackMacLibClientRPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF3937C0626BF3600CC67FA /* JackMacLibClientRPC.cpp */; }; + 4B47ACAF10B5890100469C67 /* JackRPCEngineUser.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B89B769076B74D200D170DE /* JackRPCEngineUser.c */; }; + 4B47ACB010B5890100469C67 /* JackMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B799AD607899652003F3F15 /* JackMachPort.cpp */; }; + 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1880834EE7900C94B91 /* JackShmMem.cpp */; }; + 4B47ACB210B5890100469C67 /* shm.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1900834EE8400C94B91 /* shm.c */; }; + 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1A80834EEB400C94B91 /* JackActivationCount.cpp */; }; + 4B47ACB410B5890100469C67 /* JackGraphManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C80834EF2200C94B91 /* JackGraphManager.cpp */; }; + 4B47ACB510B5890100469C67 /* JackPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1D00834EF2F00C94B91 /* JackPort.cpp */; }; + 4B47ACB610B5890100469C67 /* JackClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E50834EF6700C94B91 /* JackClient.cpp */; }; + 4B47ACB710B5890100469C67 /* JackAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1E90834EF7500C94B91 /* JackAPI.cpp */; }; + 4B47ACB810B5890100469C67 /* JackLibClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FD0834EFD100C94B91 /* JackLibClient.cpp */; }; + 4B47ACB910B5890100469C67 /* JackLibAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1FE0834EFD100C94B91 /* JackLibAPI.cpp */; }; + 4B47ACBA10B5890100469C67 /* JackConnectionManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D1C40834EF1400C94B91 /* JackConnectionManager.cpp */; }; + 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */; }; + 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6C1D508ACE64C001E2013 /* JackMachSemaphore.cpp */; }; + 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB741E08AD2B9900DB99B8 /* JackMachThread.cpp */; }; + 4B47ACBE10B5890100469C67 /* JackMachClientChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFB29AE08AF45FD00D450D4 /* JackMachClientChannel.cpp */; }; + 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C28F908DAD01E00249230 /* JackGlobals.cpp */; }; + 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B003AB008E2B2BA0060EFDC /* ringbuffer.c */; }; + 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B98AE000931D30C0091932A /* JackDebugClient.cpp */; }; + 4B47ACC210B5890100469C67 /* JackTransportEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */; }; + 4B47ACC310B5890100469C67 /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; + 4B47ACC410B5890100469C67 /* JackPortType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95B60B9E20B800A0C723 /* JackPortType.cpp */; }; + 4B47ACC510B5890100469C67 /* JackAudioPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */; }; + 4B47ACC610B5890100469C67 /* JackMidiPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */; }; + 4B47ACC710B5890100469C67 /* JackMidiAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80D7E70BA0D17400F035BB /* JackMidiAPI.cpp */; }; + 4B47ACC810B5890100469C67 /* JackEngineControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6F7AEC0CD0CDBD00F48A9D /* JackEngineControl.cpp */; }; + 4B47ACC910B5890100469C67 /* JackTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4CBFF0CDA153400CCF5BB /* JackTools.cpp */; }; + 4B47ACCA10B5890100469C67 /* JackError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B9A25B30DBF8330006E9FBC /* JackError.cpp */; }; + 4B47ACCB10B5890100469C67 /* JackMessageBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F9C8A0DC20C0400706CB0 /* JackMessageBuffer.cpp */; }; + 4B47ACCC10B5890100469C67 /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; + 4B47ACCD10B5890100469C67 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; + 4B47ACCE10B5890100469C67 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBC80E878D24003D2374 /* JackMachTime.c */; }; + 4B47ACCF10B5890100469C67 /* JackProcessSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BECB2F30F4451C10091B70A /* JackProcessSync.cpp */; }; + 4B47ACD210B5890100469C67 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4B4CA9750E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; 4B4CA9760E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */; }; 4B4CA9770E02CF9600F4BFDA /* JackRestartThreadedDriver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */; }; @@ -676,6 +753,18 @@ 4BC3B6BE0E703BCC0066E42F /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; 4BC3B6BF0E703BCC0066E42F /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */; }; 4BC3B6C00E703BCC0066E42F /* JackNetUnixSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */; }; + 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; + 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; + 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; + 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; + 4BCBCE6110C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; + 4BCBCE6210C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; + 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; + 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; + 4BCBCE6510C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */; }; + 4BCBCE6610C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */; }; + 4BCBCE6710C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */; }; + 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */; }; 4BCC87960D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87970D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; 4BCC87980D57168300A7FEB1 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BCC87950D57168300A7FEB1 /* Accelerate.framework */; }; @@ -1424,6 +1513,7 @@ 4B43A8C91014605000E52943 /* JackLoopbackDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackLoopbackDriver.h; path = ../common/JackLoopbackDriver.h; sourceTree = SOURCE_ROOT; }; 4B43A8E71014615800E52943 /* jack_loopback.so */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = jack_loopback.so; sourceTree = BUILT_PRODUCTS_DIR; }; 4B464301076CAC7700E5077C /* Jack-Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = SOURCE_ROOT; }; + 4B47ACD710B5890100469C67 /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4B4CA9730E02CF9600F4BFDA /* JackRestartThreadedDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRestartThreadedDriver.h; path = ../common/JackRestartThreadedDriver.h; sourceTree = SOURCE_ROOT; }; 4B4CA9740E02CF9600F4BFDA /* JackRestartThreadedDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRestartThreadedDriver.cpp; path = ../common/JackRestartThreadedDriver.cpp; sourceTree = SOURCE_ROOT; }; 4B4E9AF80E5F1090000A3278 /* JackControlAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackControlAPI.cpp; path = ../common/JackControlAPI.cpp; sourceTree = SOURCE_ROOT; }; @@ -1488,7 +1578,6 @@ 4B9A25B30DBF8330006E9FBC /* JackError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackError.cpp; path = ../common/JackError.cpp; sourceTree = SOURCE_ROOT; }; 4B9A26000DBF8584006E9FBC /* jslist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jslist.h; path = ../common/jack/jslist.h; sourceTree = SOURCE_ROOT; }; 4BA339AC10B2E36800190E3B /* Jackservermp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackservermp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4BA339AD10B2E36800190E3B /* Jack-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Jack-Info.plist"; sourceTree = ""; }; 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroClient.cpp; path = ../tests/testSynchroClient.cpp; sourceTree = SOURCE_ROOT; }; 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSynchroServer.cpp; path = ../tests/testSynchroServer.cpp; sourceTree = SOURCE_ROOT; }; 4BA692B00CBE4BC700EAD520 /* jack_load */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_load; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1531,6 +1620,10 @@ 4BC3B6B90E703BCC0066E42F /* JackNetUnixSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackNetUnixSocket.cpp; path = ../posix/JackNetUnixSocket.cpp; sourceTree = SOURCE_ROOT; }; 4BC3B6BA0E703BCC0066E42F /* JackNetUnixSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackNetUnixSocket.h; path = ../posix/JackNetUnixSocket.h; sourceTree = SOURCE_ROOT; }; 4BC8326D0DF42C7D00DD1C93 /* JackMutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackMutex.h; path = ../common/JackMutex.h; sourceTree = SOURCE_ROOT; }; + 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPhysicalMidiInput.cpp; path = ../common/JackPhysicalMidiInput.cpp; sourceTree = SOURCE_ROOT; }; + 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPhysicalMidiInput.h; path = ../common/JackPhysicalMidiInput.h; sourceTree = SOURCE_ROOT; }; + 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackPhysicalMidiOutput.cpp; path = ../common/JackPhysicalMidiOutput.cpp; sourceTree = SOURCE_ROOT; }; + 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackPhysicalMidiOutput.h; path = ../common/JackPhysicalMidiOutput.h; sourceTree = SOURCE_ROOT; }; 4BCC87950D57168300A7FEB1 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = /System/Library/Frameworks/Accelerate.framework; sourceTree = ""; }; 4BD4B4D409BACD9600750C0F /* JackTransportEngine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackTransportEngine.h; path = ../common/JackTransportEngine.h; sourceTree = SOURCE_ROOT; }; 4BD4B4D509BACD9600750C0F /* JackTransportEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackTransportEngine.cpp; path = ../common/JackTransportEngine.cpp; sourceTree = SOURCE_ROOT; }; @@ -1958,6 +2051,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACD110B5890100469C67 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B47ACD210B5890100469C67 /* Accelerate.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB50CD1CB9E0005BF74 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2288,7 +2389,6 @@ 0249A662FF388D9811CA2CEA /* External Frameworks and Libraries */, 1AB674ADFE9D54B511CA2CBB /* Products */, 4B464301076CAC7700E5077C /* Jack-Info.plist */, - 4BA339AD10B2E36800190E3B /* Jack-Info.plist */, ); name = JackServer; sourceTree = ""; @@ -2406,6 +2506,7 @@ 4B32256110A3187800838A8E /* jack_netsource */, 4B32257B10A3190C00838A8E /* jack_netsource */, 4BA339AC10B2E36800190E3B /* Jackservermp.framework */, + 4B47ACD710B5890100469C67 /* Jackmp.framework */, ); name = Products; sourceTree = ""; @@ -2856,6 +2957,10 @@ 4BF3390D0F8B86AF0080FB5B /* MIDI */ = { isa = PBXGroup; children = ( + 4BCBCE5910C4FE3F00450FFE /* JackPhysicalMidiInput.cpp */, + 4BCBCE5A10C4FE3F00450FFE /* JackPhysicalMidiInput.h */, + 4BCBCE5B10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp */, + 4BCBCE5C10C4FE3F00450FFE /* JackPhysicalMidiOutput.h */, 4BF3391F0F8B873E0080FB5B /* JackMidiDriver.cpp */, 4BF339200F8B873E0080FB5B /* JackMidiDriver.h */, 4BF339140F8B86DC0080FB5B /* JackCoreMidiDriver.h */, @@ -3120,6 +3225,8 @@ 4BF339220F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4BDCDBD21001FD0200B15929 /* JackWaitThreadedDriver.h in Headers */, 4BDCDC0A1001FDA800B15929 /* JackArgParser.h in Headers */, + 4BCBCE6210C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, + 4BCBCE6410C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3354,6 +3461,55 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47AC8110B5890100469C67 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B47AC8210B5890100469C67 /* JackMachPort.h in Headers */, + 4B47AC8310B5890100469C67 /* JackError.h in Headers */, + 4B47AC8410B5890100469C67 /* JackTime.h in Headers */, + 4B47AC8510B5890100469C67 /* JackShmMem.h in Headers */, + 4B47AC8610B5890100469C67 /* shm.h in Headers */, + 4B47AC8710B5890100469C67 /* JackThread.h in Headers */, + 4B47AC8810B5890100469C67 /* JackActivationCount.h in Headers */, + 4B47AC8910B5890100469C67 /* JackChannel.h in Headers */, + 4B47AC8A10B5890100469C67 /* JackGraphManager.h in Headers */, + 4B47AC8B10B5890100469C67 /* JackPort.h in Headers */, + 4B47AC8C10B5890100469C67 /* JackClientInterface.h in Headers */, + 4B47AC8D10B5890100469C67 /* JackClientControl.h in Headers */, + 4B47AC8E10B5890100469C67 /* JackClient.h in Headers */, + 4B47AC8F10B5890100469C67 /* JackInternalClient.h in Headers */, + 4B47AC9010B5890100469C67 /* JackLibGlobals.h in Headers */, + 4B47AC9110B5890100469C67 /* JackLibClient.h in Headers */, + 4B47AC9210B5890100469C67 /* JackConnectionManager.h in Headers */, + 4B47AC9310B5890100469C67 /* JackFrameTimer.h in Headers */, + 4B47AC9410B5890100469C67 /* JackMachSemaphore.h in Headers */, + 4B47AC9510B5890100469C67 /* JackGlobals.h in Headers */, + 4B47AC9610B5890100469C67 /* JackMachThread.h in Headers */, + 4B47AC9710B5890100469C67 /* JackMachClientChannel.h in Headers */, + 4B47AC9810B5890100469C67 /* JackSynchro.h in Headers */, + 4B47AC9910B5890100469C67 /* JackDebugClient.h in Headers */, + 4B47AC9A10B5890100469C67 /* JackConstants.h in Headers */, + 4B47AC9B10B5890100469C67 /* JackTransportEngine.h in Headers */, + 4B47AC9C10B5890100469C67 /* timestamps.h in Headers */, + 4B47AC9D10B5890100469C67 /* intclient.h in Headers */, + 4B47AC9E10B5890100469C67 /* jack.h in Headers */, + 4B47AC9F10B5890100469C67 /* ringbuffer.h in Headers */, + 4B47ACA010B5890100469C67 /* statistics.h in Headers */, + 4B47ACA110B5890100469C67 /* thread.h in Headers */, + 4B47ACA210B5890100469C67 /* transport.h in Headers */, + 4B47ACA310B5890100469C67 /* types.h in Headers */, + 4B47ACA410B5890100469C67 /* JackPortType.h in Headers */, + 4B47ACA510B5890100469C67 /* JackMidiPort.h in Headers */, + 4B47ACA610B5890100469C67 /* midiport.h in Headers */, + 4B47ACA710B5890100469C67 /* JackTools.h in Headers */, + 4B47ACA810B5890100469C67 /* jslist.h in Headers */, + 4B47ACA910B5890100469C67 /* JackMessageBuffer.h in Headers */, + 4B47ACAA10B5890100469C67 /* JackPosixThread.h in Headers */, + 4B47ACAB10B5890100469C67 /* JackProcessSync.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB20CD1CB9E0005BF74 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3506,6 +3662,8 @@ 4BECB2F60F4451C10091B70A /* JackProcessSync.h in Headers */, 4BF339240F8B873E0080FB5B /* JackMidiDriver.h in Headers */, 4B94334B10A5E666002A187F /* systemdeps.h in Headers */, + 4BCBCE5E10C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, + 4BCBCE6010C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3681,6 +3839,8 @@ 4BA3396D10B2E36800190E3B /* JackMidiDriver.h in Headers */, 4BA3396E10B2E36800190E3B /* JackWaitThreadedDriver.h in Headers */, 4BA3396F10B2E36800190E3B /* JackArgParser.h in Headers */, + 4BCBCE6610C4FE3F00450FFE /* JackPhysicalMidiInput.h in Headers */, + 4BCBCE6810C4FE3F00450FFE /* JackPhysicalMidiOutput.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4650,6 +4810,25 @@ productReference = 4B43A8E71014615800E52943 /* jack_loopback.so */; productType = "com.apple.product-type.library.dynamic"; }; + 4B47AC8010B5890100469C67 /* Jackmp.framework 64 bits debugging */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B47ACD310B5890100469C67 /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits debugging" */; + buildPhases = ( + 4B47AC8110B5890100469C67 /* Headers */, + 4B47ACAC10B5890100469C67 /* Resources */, + 4B47ACAD10B5890100469C67 /* Sources */, + 4B47ACD010B5890100469C67 /* Rez */, + 4B47ACD110B5890100469C67 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Jackmp.framework 64 bits debugging"; + productName = Jack; + productReference = 4B47ACD710B5890100469C67 /* Jackmp.framework */; + productType = "com.apple.product-type.framework"; + }; 4B5A1BB10CD1CB9E0005BF74 /* jack_midiseq Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */; @@ -5522,6 +5701,7 @@ 4B5E08BF0E5B66EE00BEE4E0 /* netadapter Universal */, 4B35C41B0D4731D1000DE7AE /* jackdmp framework 64bits */, 4B35C4270D4731D1000DE7AE /* Jackmp.framework 64 bits */, + 4B47AC8010B5890100469C67 /* Jackmp.framework 64 bits debugging */, 4B35C4850D4731D1000DE7AE /* Jackservermp.framework 64 bits */, 4BA3393310B2E36800190E3B /* Jackservermp.framework 64 bits profiling */, 4B35C50A0D4731D1000DE7AE /* jack_midiseq 64 bits */, @@ -5581,6 +5761,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACAC10B5890100469C67 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B699C23097D421600A18468 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -5836,6 +6023,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACD010B5890100469C67 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB60CD1CB9E0005BF74 /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -6229,6 +6423,8 @@ 4BF339210F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, 4BDCDBD11001FD0100B15929 /* JackWaitThreadedDriver.cpp in Sources */, 4BDCDC091001FDA800B15929 /* JackArgParser.cpp in Sources */, + 4BCBCE6110C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, + 4BCBCE6310C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6490,6 +6686,47 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B47ACAD10B5890100469C67 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B47ACAE10B5890100469C67 /* JackMacLibClientRPC.cpp in Sources */, + 4B47ACAF10B5890100469C67 /* JackRPCEngineUser.c in Sources */, + 4B47ACB010B5890100469C67 /* JackMachPort.cpp in Sources */, + 4B47ACB110B5890100469C67 /* JackShmMem.cpp in Sources */, + 4B47ACB210B5890100469C67 /* shm.c in Sources */, + 4B47ACB310B5890100469C67 /* JackActivationCount.cpp in Sources */, + 4B47ACB410B5890100469C67 /* JackGraphManager.cpp in Sources */, + 4B47ACB510B5890100469C67 /* JackPort.cpp in Sources */, + 4B47ACB610B5890100469C67 /* JackClient.cpp in Sources */, + 4B47ACB710B5890100469C67 /* JackAPI.cpp in Sources */, + 4B47ACB810B5890100469C67 /* JackLibClient.cpp in Sources */, + 4B47ACB910B5890100469C67 /* JackLibAPI.cpp in Sources */, + 4B47ACBA10B5890100469C67 /* JackConnectionManager.cpp in Sources */, + 4B47ACBB10B5890100469C67 /* JackFrameTimer.cpp in Sources */, + 4B47ACBC10B5890100469C67 /* JackMachSemaphore.cpp in Sources */, + 4B47ACBD10B5890100469C67 /* JackMachThread.cpp in Sources */, + 4B47ACBE10B5890100469C67 /* JackMachClientChannel.cpp in Sources */, + 4B47ACBF10B5890100469C67 /* JackGlobals.cpp in Sources */, + 4B47ACC010B5890100469C67 /* ringbuffer.c in Sources */, + 4B47ACC110B5890100469C67 /* JackDebugClient.cpp in Sources */, + 4B47ACC210B5890100469C67 /* JackTransportEngine.cpp in Sources */, + 4B47ACC310B5890100469C67 /* timestamps.c in Sources */, + 4B47ACC410B5890100469C67 /* JackPortType.cpp in Sources */, + 4B47ACC510B5890100469C67 /* JackAudioPort.cpp in Sources */, + 4B47ACC610B5890100469C67 /* JackMidiPort.cpp in Sources */, + 4B47ACC710B5890100469C67 /* JackMidiAPI.cpp in Sources */, + 4B47ACC810B5890100469C67 /* JackEngineControl.cpp in Sources */, + 4B47ACC910B5890100469C67 /* JackTools.cpp in Sources */, + 4B47ACCA10B5890100469C67 /* JackError.cpp in Sources */, + 4B47ACCB10B5890100469C67 /* JackMessageBuffer.cpp in Sources */, + 4B47ACCC10B5890100469C67 /* JackPosixServerLaunch.cpp in Sources */, + 4B47ACCD10B5890100469C67 /* JackPosixThread.cpp in Sources */, + 4B47ACCE10B5890100469C67 /* JackMachTime.c in Sources */, + 4B47ACCF10B5890100469C67 /* JackProcessSync.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4B5A1BB30CD1CB9E0005BF74 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -6624,6 +6861,8 @@ 4BBAE4110F42FA6100B8BD3F /* JackEngineProfiling.cpp in Sources */, 4BECB2F50F4451C10091B70A /* JackProcessSync.cpp in Sources */, 4BF339230F8B873E0080FB5B /* JackMidiDriver.cpp in Sources */, + 4BCBCE5D10C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, + 4BCBCE5F10C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6802,6 +7041,8 @@ 4BA339A210B2E36800190E3B /* JackMidiDriver.cpp in Sources */, 4BA339A310B2E36800190E3B /* JackWaitThreadedDriver.cpp in Sources */, 4BA339A410B2E36800190E3B /* JackArgParser.cpp in Sources */, + 4BCBCE6510C4FE3F00450FFE /* JackPhysicalMidiInput.cpp in Sources */, + 4BCBCE6710C4FE3F00450FFE /* JackPhysicalMidiOutput.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -12152,6 +12393,199 @@ }; name = Default; }; + 4B47ACD410B5890100469C67 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-DJACK_32_64", + "-D__SMP__", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-D__CLIENTDEBUG__", + "-DMACH_RPC_MACH_SEMA", + "-D__SMP__", + "-DJACK_32_64", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackmp; + REZ_EXECUTABLE = NO; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + ZERO_LINK = YES; + }; + name = Development; + }; + 4B47ACD510B5890100469C67 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; + COPY_PHASE_STRIP = YES; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_AUTO_VECTORIZATION = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_ENABLE_SSE3_EXTENSIONS = YES; + GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + ../common, + ../posix, + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-DJACK_32_64", + "-D__SMP__", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-D__CLIENTDEBUG__", + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + "-D__SMP__", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackmp; + REZ_EXECUTABLE = NO; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4B47ACD610B5890100469C67 /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc64, + ppc, + i386, + x86_64, + ); + DEBUG_INFORMATION_FORMAT = dwarf; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + FRAMEWORK_VERSION = A; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + GENERATE_PKGINFO_FILE = NO; + HEADER_SEARCH_PATHS = ( + RPC, + ../common/jack, + ); + INFOPLIST_FILE = "Jack-Info copy 2.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.3; + OTHER_CFLAGS = ( + "-DUSE_POSIX_SHM", + "-DJACK_32_64", + "-D__SMP__", + ); + OTHER_CPLUSPLUSFLAGS = ( + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + "-D__SMP__", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1)", + "$(OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2)", + ); + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_1 = "-DJACK_LOCATION=\\\"/usr/local/bin\\\""; + OTHER_CPLUSPLUSFLAGS_QUOTED_FOR_TARGET_2 = "-DADDON_DIR=\\\"/usr/local/lib/jackmp\\\""; + OTHER_LDFLAGS = ( + "-framework", + Carbon, + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = Jackmp; + REZ_EXECUTABLE = NO; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + name = Default; + }; 4B5A1BB80CD1CB9E0005BF74 /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -17952,6 +18386,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4B47ACD310B5890100469C67 /* Build configuration list for PBXNativeTarget "Jackmp.framework 64 bits debugging" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B47ACD410B5890100469C67 /* Development */, + 4B47ACD510B5890100469C67 /* Deployment */, + 4B47ACD610B5890100469C67 /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4B5A1BB70CD1CB9E0005BF74 /* Build configuration list for PBXNativeTarget "jack_midiseq Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macosx/coreaudio/JackAudioQueueAdapter.cpp b/macosx/coreaudio/JackAudioQueueAdapter.cpp index 3cb9e9af..e6a1db35 100644 --- a/macosx/coreaudio/JackAudioQueueAdapter.cpp +++ b/macosx/coreaudio/JackAudioQueueAdapter.cpp @@ -18,59 +18,105 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "JackAudioQueueAdapter.h" -#include +//#include namespace Jack { // NOT YET WORKING.... -static void Print4CharCode(char* msg, long c) +static void Print4CharCode(const char* msg, long c) { UInt32 __4CC_number = (c); char __4CC_string[5]; - *((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number); + //*((SInt32*)__4CC_string) = EndianU32_NtoB(__4CC_number); __4CC_string[4] = 0; //printf("%s'%s'\n", (msg), __4CC_string); snprintf(__4CC_string, 5, "%s'%s'\n", (msg), __4CC_string); } + +static int ComputeRecordBufferSize(AudioQueueRef mQueue, const AudioStreamBasicDescription *format, float seconds) +{ + OSStatus err; + int packets, frames, bytes = 0; + frames = (int)ceil(seconds * format->mSampleRate); + + if (format->mBytesPerFrame > 0) + bytes = frames * format->mBytesPerFrame; + else { + UInt32 maxPacketSize; + if (format->mBytesPerPacket > 0) { + maxPacketSize = format->mBytesPerPacket; // constant packet size + } else { + UInt32 propertySize = sizeof(maxPacketSize); + if ((err = AudioQueueGetProperty(mQueue, kAudioQueueProperty_MaximumOutputPacketSize, &maxPacketSize, &propertySize)) != noErr) { + printf("Couldn't get queue's maximum output packet size\n"); + return 0; + } + } + if (format->mFramesPerPacket > 0) + packets = frames / format->mFramesPerPacket; + else + packets = frames; // worst-case scenario: 1 frame in a packet + if (packets == 0) // sanity check + packets = 1; + bytes = packets * maxPacketSize; + } + return bytes; +} void JackAudioQueueAdapter::CaptureCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inBuffer, - const AudioTimeStamp * inStartTime, - UInt32 inNumPackets, - const AudioStreamPacketDescription *inPacketDesc) + AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer, + const AudioTimeStamp * inStartTime, + UInt32 inNumPackets, + const AudioStreamPacketDescription *inPacketDesc) { JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; - + OSStatus err; printf("JackAudioQueueAdapter::CaptureCallback\n"); - if (AudioQueueEnqueueBuffer(adapter->fCaptureQueue, inBuffer, 0, NULL) != noErr) { - printf("JackAudioQueueAdapter::CaptureCallback error\n"); - } - // Use the adapter to communicate with audio callback // jack_adapter_push_input(adapter, audio_output, audio_output_buffer); + + if ((err = AudioQueueEnqueueBuffer(adapter->fCaptureQueue, inBuffer, 0, NULL)) != noErr) { + printf("JackAudioQueueAdapter::CaptureCallback error %d\n", err); + } else { + printf("JackAudioQueueAdapter::CaptureCallback enqueue buffer\n"); + } } void JackAudioQueueAdapter::PlaybackCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inCompleteAQBuffer) + AudioQueueRef inAQ, + AudioQueueBufferRef inCompleteAQBuffer) { JackAudioQueueAdapter* adapter = (JackAudioQueueAdapter*)inUserData; - + OSStatus err; printf("JackAudioQueueAdapter::PlaybackCallback\n"); - if (AudioQueueEnqueueBuffer(adapter->fPlaybackQueue, inCompleteAQBuffer, 0, &adapter->fPlaybackPacketDescs) != noErr) { - printf("JackAudioQueueAdapter::PlaybackCallback error\n"); - } - // Use the adapter to communicate with audio callback // jack_adapter_pull_output(adapter, audio_input, audio_input_buffer); + + //if (AudioQueueEnqueueBuffer(adapter->fPlaybackQueue, inCompleteAQBuffer, 0, &adapter->fPlaybackPacketDescs) != noErr) { + if ((err = AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL)) != noErr) { + printf("JackAudioQueueAdapter::PlaybackCallback error %d\n", err); + } else { + printf("JackAudioQueueAdapter::PlaybackCallback enqueue buffer\n"); + } } +void JackAudioQueueAdapter::InterruptionListener(void* inClientData, UInt32 inInterruptionState) +{ + JackAudioQueueAdapter* obj = (JackAudioQueueAdapter*)inClientData; +} + +void JackAudioQueueAdapter::PropListener(void* inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void* inData) +{} + JackAudioQueueAdapter::JackAudioQueueAdapter(int inchan, int outchan, jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_adapter_t* adapter) :fCaptureChannels(inchan), fPlaybackChannels(outchan), fBufferSize(buffer_size), fSampleRate(sample_rate), fAdapter(adapter) @@ -79,9 +125,46 @@ JackAudioQueueAdapter::JackAudioQueueAdapter(int inchan, int outchan, jack_nfram JackAudioQueueAdapter::~JackAudioQueueAdapter() {} -int JackAudioQueueAdapter::Open() +int JackAudioQueueAdapter::Open() { - OSStatus err; + OSStatus err; + int bufferByteSize; + UInt32 size; + + /* + err = AudioSessionInitialize(NULL, NULL, InterruptionListener, this); + if (err != noErr) { + fprintf(stderr, "AudioSessionInitialize error %d\n", err); + return -1; + } + + err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, PropListener, this); + if (err) { + fprintf(stderr, "kAudioSessionProperty_AudioRouteChange error %d\n", err); + } + + UInt32 inputAvailable = 0; + UInt32 size = sizeof(inputAvailable); + + // we do not want to allow recording if input is not available + err = AudioSessionGetProperty(kAudioSessionProperty_AudioInputAvailable, &size, &inputAvailable); + if (err != noErr) { + fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err); + } + + // we also need to listen to see if input availability changes + err = AudioSessionAddPropertyListener(kAudioSessionProperty_AudioInputAvailable, PropListener, this); + if (err != noErr) { + fprintf(stderr, "kAudioSessionProperty_AudioInputAvailable error %d\n", err); + } + + err = AudioSessionSetActive(true); + if (err != noErr) { + fprintf(stderr, "AudioSessionSetActive (true) failed %d", err); + return -1; + } + */ + AudioStreamBasicDescription captureDataFormat; /* @@ -95,26 +178,55 @@ int JackAudioQueueAdapter::Open() captureDataFormat.mChannelsPerFrame = fCaptureChannels; captureDataFormat.mBitsPerChannel = 32; */ - + + captureDataFormat.mSampleRate = fSampleRate; captureDataFormat.mFormatID = kAudioFormatLinearPCM; - captureDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; - captureDataFormat.mBytesPerPacket = 4; + captureDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + captureDataFormat.mBytesPerPacket = 4; captureDataFormat.mFramesPerPacket = 1; // this means each packet in the AQ has two samples, one for each channel -> 4 bytes/frame/packet captureDataFormat.mBytesPerFrame = 4; captureDataFormat.mChannelsPerFrame = 2; captureDataFormat.mBitsPerChannel = 16; + if ((err = AudioQueueNewInput(&captureDataFormat, CaptureCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fCaptureQueue)) != noErr) { Print4CharCode("error code : unknown", err); return -1; } + size = sizeof(captureDataFormat.mSampleRate); + if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &captureDataFormat.mSampleRate)) != noErr) { + printf("couldn't get hardware sample rate\n"); + } + + size = sizeof(captureDataFormat.mChannelsPerFrame); + if ((err = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &size, &captureDataFormat.mChannelsPerFrame)) != noErr) { + printf("couldn't get input channel count\n"); + } + + size = sizeof(captureDataFormat); + if ((err = AudioQueueGetProperty(fCaptureQueue, kAudioQueueProperty_StreamDescription, &captureDataFormat, &size)) != noErr) { + printf("couldn't get queue's format\n"); + } + + bufferByteSize = ComputeRecordBufferSize(fCaptureQueue, &captureDataFormat, kBufferDurationSeconds); // enough bytes for half a second + for (int i = 0; i < kNumberBuffers; ++i) { + if ((err = AudioQueueAllocateBuffer(fCaptureQueue, bufferByteSize, &fCaptureQueueBuffers[i])) != noErr) { + printf("Capture AudioQueueAllocateBuffer failed\n"); + } + if ((err = AudioQueueEnqueueBuffer(fCaptureQueue, fCaptureQueueBuffers[i], 0, NULL)) != noErr) { + printf("Capture AudioQueueEnqueueBuffer failed\n"); + } + } + + //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_MagicCookie, cookie, size) //AudioQueueSetProperty(fCaptureQueue, kAudioQueueProperty_ChannelLayout, acl, size AudioStreamBasicDescription playbackDataFormat; + /* playbackDataFormat.mSampleRate = fSampleRate; playbackDataFormat.mFormatID = kAudioFormatLinearPCM; playbackDataFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved; @@ -123,38 +235,78 @@ int JackAudioQueueAdapter::Open() playbackDataFormat.mBytesPerFrame = sizeof(float); playbackDataFormat.mChannelsPerFrame = fPlaybackChannels; playbackDataFormat.mBitsPerChannel = 32; + */ + + playbackDataFormat.mSampleRate = fSampleRate; + playbackDataFormat.mFormatID = kAudioFormatLinearPCM; + playbackDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + playbackDataFormat.mBytesPerPacket = 4; + playbackDataFormat.mFramesPerPacket = 1; + playbackDataFormat.mBytesPerFrame = 4; + playbackDataFormat.mChannelsPerFrame = fPlaybackChannels; + playbackDataFormat.mBitsPerChannel = 16; + if ((err = AudioQueueNewOutput(&playbackDataFormat, PlaybackCallback, this, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &fPlaybackQueue)) != noErr) { Print4CharCode("error code : unknown", err); return -1; } + for (int i = 0; i < kNumberBuffers; ++i) { + if ((err = AudioQueueAllocateBuffer(fPlaybackQueue, bufferByteSize, &fPlaybackQueueBuffers[i])) != noErr) { + printf("Playback AudioQueueAllocateBuffer failed %d\n", err); + } + //if ((err = AudioQueueEnqueueBuffer(fPlaybackQueue, fPlaybackQueueBuffers[i], 0, NULL)) != noErr) { + // printf("Playback AudioQueueEnqueueBuffer failed %d\n", err); + //} + } + + AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, 1.0); + //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_MagicCookie, cookie, size); //AudioQueueSetProperty(fPlaybackQueue, kAudioQueueProperty_ChannelLayout, acl, size); //AudioQueueSetParameter(fPlaybackQueue, kAudioQueueParam_Volume, volume - //AudioQueueStart(fCaptureQueue, NULL); - AudioQueueStart(fPlaybackQueue, NULL); - return 0; } -int JackAudioQueueAdapter::Close() +int JackAudioQueueAdapter::Close() { - AudioQueueStop(fCaptureQueue, true); - AudioQueueStop(fPlaybackQueue, true); + //AudioSessionSetActive(false); AudioQueueDispose(fCaptureQueue, true); AudioQueueDispose(fPlaybackQueue, true); return 0; } + +int JackAudioQueueAdapter::Start() +{ + for (int i = 0; i < kNumberBuffers; ++i) { + PlaybackCallback(this, fPlaybackQueue, fPlaybackQueueBuffers[i]); + } + + AudioQueueStart(fCaptureQueue, NULL); + AudioQueueStart(fPlaybackQueue, NULL); + + return 0; +} + +int JackAudioQueueAdapter::Stop() +{ + + AudioQueueStop(fCaptureQueue, NULL); + AudioQueueStop(fPlaybackQueue, NULL); + + return 0; +} + -int JackAudioQueueAdapter::SetSampleRate(jack_nframes_t sample_rate) +int JackAudioQueueAdapter::SetSampleRate(jack_nframes_t sample_rate) { return 0; } -int JackAudioQueueAdapter::SetBufferSize(jack_nframes_t buffer_size) +int JackAudioQueueAdapter::SetBufferSize(jack_nframes_t buffer_size) { return 0; } diff --git a/macosx/coreaudio/JackAudioQueueAdapter.h b/macosx/coreaudio/JackAudioQueueAdapter.h index 1de09959..da8f8430 100644 --- a/macosx/coreaudio/JackAudioQueueAdapter.h +++ b/macosx/coreaudio/JackAudioQueueAdapter.h @@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackAudioQueueAdapter__ #define __JackAudioQueueAdapter__ -#include -#include +//#include +//#include + +#include #include @@ -32,7 +34,8 @@ namespace Jack \brief Audio adapter using AudioQueue API. */ -static const int kNumberBuffers = 3; +#define kNumberBuffers 3 +#define kBufferDurationSeconds .5 class JackAudioQueueAdapter { @@ -44,7 +47,7 @@ class JackAudioQueueAdapter AudioQueueRef fPlaybackQueue; AudioQueueBufferRef fPlaybackQueueBuffers[kNumberBuffers]; - AudioStreamPacketDescription fPlaybackPacketDescs; + //AudioStreamPacketDescription fPlaybackPacketDescs; jack_nframes_t fBufferSize; @@ -55,17 +58,24 @@ class JackAudioQueueAdapter jack_adapter_t* fAdapter; - static void CaptureCallback(void * inUserData, + static void CaptureCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, - const AudioTimeStamp * inStartTime, + const AudioTimeStamp* inStartTime, UInt32 inNumPackets, - const AudioStreamPacketDescription *inPacketDesc); + const AudioStreamPacketDescription* inPacketDesc); - static void PlaybackCallback(void * inUserData, - AudioQueueRef inAQ, - AudioQueueBufferRef inCompleteAQBuffer); + static void PlaybackCallback(void* inUserData, + AudioQueueRef inAQ, + AudioQueueBufferRef inCompleteAQBuffer); + + static void InterruptionListener(void* inClientData, UInt32 inInterruptionState); + + static void PropListener(void* inClientData, + AudioSessionPropertyID inID, + UInt32 inDataSize, + const void* inData); public: @@ -74,6 +84,10 @@ class JackAudioQueueAdapter virtual int Open(); virtual int Close(); + + virtual int Start(); + virtual int Stop(); + virtual int SetSampleRate(jack_nframes_t sample_rate); virtual int SetBufferSize(jack_nframes_t buffer_size); diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index e540a164..2143170f 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -250,10 +250,10 @@ OSStatus JackCoreAudioDriver::MeasureCallback(AudioDeviceID inDevice, } OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, - UInt32 inChannel, - Boolean isInput, - AudioDevicePropertyID inPropertyID, - void* inClientData) + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; @@ -262,6 +262,16 @@ OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, case kAudioDevicePropertyNominalSampleRate: { jack_log("JackCoreAudioDriver::SRNotificationCallback kAudioDevicePropertyNominalSampleRate"); driver->fState = true; + // Check new sample rate + Float64 sampleRate; + UInt32 outSize = sizeof(Float64); + OSStatus err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("SRNotificationCallback : checked sample rate = %f", sampleRate); + } break; } } @@ -271,14 +281,23 @@ OSStatus JackCoreAudioDriver::SRNotificationCallback(AudioDeviceID inDevice, // A better implementation would possibly try to recover in case of hardware device change (see HALLAB HLFilePlayerWindowControllerAudioDevicePropertyListenerProc code) OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, - UInt32 inChannel, - Boolean isInput, - AudioDevicePropertyID inPropertyID, - void* inClientData) + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inClientData; switch (inPropertyID) { + + case kAudioDevicePropertyDeviceIsRunning: { + UInt32 isrunning = 0; + UInt32 outsize = sizeof(UInt32); + if (AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyDeviceIsRunning, &outsize, &isrunning) == noErr) { + jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDevicePropertyDeviceIsRunning = %d", isrunning); + } + break; + } case kAudioDeviceProcessorOverload: { jack_error("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload"); @@ -296,12 +315,52 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, } case kAudioDevicePropertyNominalSampleRate: { - jack_error("Cannot handle kAudioDevicePropertyNominalSampleRate : server will quit..."); - driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE - driver->CloseAUHAL(); - kill(JackTools::GetPID(), SIGINT); - return kAudioHardwareUnsupportedOperationError; - } + Float64 sampleRate = 0; + UInt32 outsize = sizeof(Float64); + OSStatus err = AudioDeviceGetProperty(driver->fDeviceID, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); + if (err != noErr) + return kAudioHardwareUnsupportedOperationError; + + char device_name[256]; + const char* digidesign_name = "Digidesign"; + driver->GetDeviceNameFromID(driver->fDeviceID, device_name); + + if (sampleRate != driver->fEngineControl->fSampleRate) { + + // Digidesign hardware, so "special" code : change the SR again here + if (strncmp(device_name, digidesign_name, sizeof(digidesign_name)) == 0) { + + jack_log("Digidesign HW = %s", device_name); + + // Set sample rate again... + sampleRate = driver->fEngineControl->fSampleRate; + err = AudioDeviceSetProperty(driver->fDeviceID, NULL, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, outsize, &sampleRate); + if (err != noErr) { + jack_error("Cannot set sample rate = %f", sampleRate); + printError(err); + } else { + jack_log("Set sample rate = %f", sampleRate); + } + + // Check new sample rate again... + outsize = sizeof(Float64); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outsize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("Checked sample rate = %f", sampleRate); + } + return noErr; + + } else { + driver->NotifyFailure(JackBackendError, "Another application has changed the sample rate."); // Message length limited to JACK_MESSAGE_SIZE + driver->CloseAUHAL(); + kill(JackTools::GetPID(), SIGINT); + return kAudioHardwareUnsupportedOperationError; + } + } + } } return noErr; @@ -926,8 +985,6 @@ int JackCoreAudioDriver::SetupDevices(const char* capture_driver_uid, if (fHogged) { if (TakeHog()) { jack_info("Device = %ld has been hogged", fDeviceID); - } else { - jack_error("Cannot hog device = %ld", fDeviceID); } } @@ -1020,6 +1077,8 @@ int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes jack_error("Cannot get current sample rate"); printError(err); return -1; + } else { + jack_log("Current sample rate = %f", sampleRate); } // If needed, set new sample rate @@ -1046,6 +1105,16 @@ int JackCoreAudioDriver::SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes usleep(100000); jack_log("Wait count = %d", count); } + + // Check new sample rate + outSize = sizeof(Float64); + err = AudioDeviceGetProperty(inDevice, 0, kAudioDeviceSectionGlobal, kAudioDevicePropertyNominalSampleRate, &outSize, &sampleRate); + if (err != noErr) { + jack_error("Cannot get current sample rate"); + printError(err); + } else { + jack_log("Checked sample rate = %f", sampleRate); + } // Remove SR change notification AudioDeviceRemovePropertyListener(inDevice, 0, true, kAudioDevicePropertyNominalSampleRate, SRNotificationCallback); @@ -1199,9 +1268,9 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (capturing && inchannels > 0) { size = sizeof(AudioStreamBasicDescription); - err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &srcFormat, &size); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &size); if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } @@ -1219,9 +1288,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, PrintStreamDesc(&srcFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); printError(err1); goto error; } @@ -1230,9 +1298,9 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, if (playing && outchannels > 0) { size = sizeof(AudioStreamBasicDescription); - err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &dstFormat, &size); + err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &size); if (err1 != noErr) { - jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + jack_error("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } @@ -1250,9 +1318,8 @@ int JackCoreAudioDriver::OpenAUHAL(bool capturing, PrintStreamDesc(&dstFormat); err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription)); - if (err1 != noErr) { - jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output"); + jack_error("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Input"); printError(err1); goto error; } @@ -1623,7 +1690,7 @@ int JackCoreAudioDriver::Start() return -1; } - // Waiting for Measure callback to be called ( = driver has started) + // Waiting for Measure callback to be called (= driver has started) fState = false; int count = 0; while (!fState && count++ < WAIT_COUNTER) { @@ -1695,7 +1762,7 @@ bool JackCoreAudioDriver::TakeHogAux(AudioDeviceID deviceID, bool isInput) hog_pid = getpid(); err = AudioDeviceSetProperty(deviceID, 0, 0, isInput, kAudioDevicePropertyHogMode, propSize, &hog_pid); if (err != noErr) { - jack_error("Can't hog device = %d because it's being hogged by another program", deviceID); + jack_error("Can't hog device = %d because it's being hogged by another program or cannot be hogged", deviceID); return false; } } diff --git a/macosx/coremidi/JackCoreMidiDriver.cpp b/macosx/coremidi/JackCoreMidiDriver.cpp index 891af946..08bd8c80 100644 --- a/macosx/coremidi/JackCoreMidiDriver.cpp +++ b/macosx/coremidi/JackCoreMidiDriver.cpp @@ -52,19 +52,17 @@ void JackCoreMidiDriver::ReadProcAux(const MIDIPacketList *pktlist, jack_ringbuf // TODO : use timestamp + // Check available size first.. + size = jack_ringbuffer_write_space(ringbuffer); + if (size < (sizeof(UInt16) + packet->length)) { + jack_error("ReadProc : ring buffer is full, skip events..."); + return; + } // Write length of each packet first - size = jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); - if (size != sizeof(UInt16)) { - jack_error("ReadProc : ring buffer is full, skip events..."); - return; - } + jack_ringbuffer_write(ringbuffer, (char*)&packet->length, sizeof(UInt16)); // Write event actual data - size = jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); - if (size != packet->length) { - jack_error("ReadProc : ring buffer is full, skip events..."); - return; - } - + jack_ringbuffer_write(ringbuffer, (char*)packet->data, packet->length); + packet = MIDIPacketNext(packet); } } diff --git a/macosx/iphone/Info.plist b/macosx/iphone/Info.plist index fdf83406..38cb25cf 100644 --- a/macosx/iphone/Info.plist +++ b/macosx/iphone/Info.plist @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} + fr.grame.iGrame.iPhoneFaustNet CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/macosx/iphone/freeverb.mm b/macosx/iphone/freeverb.mm index 9b7832f7..3daabc9a 100644 --- a/macosx/iphone/freeverb.mm +++ b/macosx/iphone/freeverb.mm @@ -38,6 +38,8 @@ #include #include +#include "JackAudioQueueAdapter.h" + using namespace std; // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero) @@ -690,19 +692,36 @@ static int net_process(jack_nframes_t buffer_size, // MAIN //------------------------------------------------------------------------- + +#define TEST_MASTER "194.5.49.5" + int main(int argc, char *argv[]) { UI* interface = new CMDUI(argc, argv); jack_net_slave_t* net; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + //Jack::JackAudioQueueAdapter audio(2, 2, 1024, 44100, NULL); + gNumInChans = DSP.getNumInputs(); gNumOutChans = DSP.getNumOutputs(); jack_slave_t request = { gNumInChans, gNumOutChans, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; jack_master_t result; - - if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { + + printf("Network\n"); + + //if (audio.Open() < 0) { + // fprintf(stderr, "Cannot open audio\n"); + // return 1; + //} + + //audio.Start(); + + // Hang around forever... + //while(1) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.25, false); + + if ((net = jack_net_slave_open(TEST_MASTER, DEFAULT_PORT, "iPhone", &request, &result)) == 0) { fprintf(stderr, "jack remote server not running ?\n"); return 1; } @@ -726,5 +745,10 @@ int main(int argc, char *argv[]) { // Wait for application end jack_net_slave_deactivate(net); jack_net_slave_close(net); + + //if (audio.Close() < 0) { + // fprintf(stderr, "Cannot close audio\n"); + //} + return retVal; } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index 8ce87173..a1211fef 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -56,7 +56,45 @@ 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B41469810BD3C4300C12F0C /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4B41469A10BD3C4300C12F0C /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4B41469B10BD3C4300C12F0C /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4B41469C10BD3C4300C12F0C /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4B41469D10BD3C4300C12F0C /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4B4146A110BD3C4300C12F0C /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; + 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4B4146A510BD3C4300C12F0C /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; + 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B4146A910BD3C4300C12F0C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; + 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; + 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93550F49ACFC00D3626B /* JackMachThread.cpp */; }; + 4BCF75DD10BC2FD90082C526 /* JackMachTime.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93870F49B0E300D3626B /* JackMachTime.c */; }; + 4BCF75DE10BC2FD90082C526 /* JackNetAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */; }; + 4BCF75DF10BC2FD90082C526 /* JackNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */; }; + 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */; }; + 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A93510F49ACF300D3626B /* JackNetUnixSocket.cpp */; }; + 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; + 4BCF75E310BC2FD90082C526 /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; + 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; + 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */; }; + 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF136540F4B0F9F00218A3F /* ringbuffer.c */; }; + 4BCF75E710BC2FD90082C526 /* iPhoneNetAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */; }; + 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4BCF75EB10BC2FD90082C526 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 4BCF75EC10BC2FD90082C526 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 4BCF75ED10BC2FD90082C526 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 4BCF75EE10BC2FD90082C526 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF75F610BC30140082C526 /* audio_thru.mm */; }; 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136130F4B0B5E00218A3F /* JackAudioAdapterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */; }; @@ -109,7 +147,10 @@ 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioQueueAdapter.h; path = ../coreaudio/JackAudioQueueAdapter.h; sourceTree = SOURCE_ROOT; }; 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; + 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iPhoneFaustNet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BCF75F610BC30140082C526 /* audio_thru.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = audio_thru.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; 4BF1364B0F4B0F7700218A3F /* JackResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackResampler.cpp; path = ../../common/JackResampler.cpp; sourceTree = SOURCE_ROOT; }; @@ -150,6 +191,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B4146A810BD3C4300C12F0C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B4146A910BD3C4300C12F0C /* Foundation.framework in Frameworks */, + 4B4146AA10BD3C4300C12F0C /* UIKit.framework in Frameworks */, + 4B4146AB10BD3C4300C12F0C /* CoreGraphics.framework in Frameworks */, + 4B4146AC10BD3C4300C12F0C /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BCF75EA10BC2FD90082C526 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCF75EB10BC2FD90082C526 /* Foundation.framework in Frameworks */, + 4BCF75EC10BC2FD90082C526 /* UIKit.framework in Frameworks */, + 4BCF75ED10BC2FD90082C526 /* CoreGraphics.framework in Frameworks */, + 4BCF75EE10BC2FD90082C526 /* AudioToolbox.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF456F0F4D5D9700106083 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -171,6 +234,8 @@ 4BFF45120F4D59DB00106083 /* libjacknet.a */, 4BFF45770F4D5D9700106083 /* iPhoneFaustNet.app */, 4B0772380F54018C000DC657 /* iPhoneNetMaster.app */, + 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */, + 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */, ); name = Products; sourceTree = ""; @@ -189,6 +254,7 @@ 29B97315FDCFA39411CA2CEA /* Other Sources */ = { isa = PBXGroup; children = ( + 4BCF75F610BC30140082C526 /* audio_thru.mm */, 4BBDC8F90F5420C000465F9C /* freeverb.mm */, 4B0773840F541EE2000DC657 /* iPhoneNetAppDelegate.h */, 4B0773850F541EE2000DC657 /* iPhoneNetAppDelegate.m */, @@ -307,6 +373,40 @@ productReference = 4BFF45120F4D59DB00106083 /* libjacknet.a */; productType = "com.apple.product-type.library.static"; }; + 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4B4146AD10BD3C4300C12F0C /* Build configuration list for PBXNativeTarget "iPhoneFaustNet Distribution" */; + buildPhases = ( + 4B41469710BD3C4300C12F0C /* Resources */, + 4B41469910BD3C4300C12F0C /* Sources */, + 4B4146A810BD3C4300C12F0C /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "iPhoneFaustNet Distribution"; + productName = iPhoneNet; + productReference = 4B4146B010BD3C4300C12F0C /* iPhoneFaustNet.app */; + productType = "com.apple.product-type.application"; + }; + 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */; + buildPhases = ( + 4BCF75D910BC2FD90082C526 /* Resources */, + 4BCF75DB10BC2FD90082C526 /* Sources */, + 4BCF75EA10BC2FD90082C526 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iPhoneThruNet; + productName = iPhoneNet; + productReference = 4BCF75F210BC2FD90082C526 /* iPhoneFaustNet.app */; + productType = "com.apple.product-type.application"; + }; 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */; @@ -339,6 +439,8 @@ 4B07721F0F54018C000DC657 /* iPhoneNetMaster */, 1D6058900D05DD3D006BFB54 /* iPhoneNetSlave */, 4BFF455E0F4D5D9700106083 /* iPhoneFaustNet */, + 4BCF75D810BC2FD90082C526 /* iPhoneThruNet */, + 4B41469610BD3C4300C12F0C /* iPhoneFaustNet Distribution */, 4B1A940F0F49BDE000D3626B /* jacknet */, ); }; @@ -361,6 +463,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B41469710BD3C4300C12F0C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B41469810BD3C4300C12F0C /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BCF75D910BC2FD90082C526 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCF75DA10BC2FD90082C526 /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF455F0F4D5D9700106083 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -432,6 +550,48 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4B41469910BD3C4300C12F0C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B41469A10BD3C4300C12F0C /* JackMachThread.cpp in Sources */, + 4B41469B10BD3C4300C12F0C /* JackMachTime.c in Sources */, + 4B41469C10BD3C4300C12F0C /* JackNetAPI.cpp in Sources */, + 4B41469D10BD3C4300C12F0C /* JackNetInterface.cpp in Sources */, + 4B41469E10BD3C4300C12F0C /* JackNetTool.cpp in Sources */, + 4B41469F10BD3C4300C12F0C /* JackNetUnixSocket.cpp in Sources */, + 4B4146A010BD3C4300C12F0C /* JackPosixThread.cpp in Sources */, + 4B4146A110BD3C4300C12F0C /* JackAudioQueueAdapter.cpp in Sources */, + 4B4146A210BD3C4300C12F0C /* JackAudioAdapterInterface.cpp in Sources */, + 4B4146A310BD3C4300C12F0C /* JackResampler.cpp in Sources */, + 4B4146A410BD3C4300C12F0C /* ringbuffer.c in Sources */, + 4B4146A510BD3C4300C12F0C /* iPhoneNetAppDelegate.m in Sources */, + 4B4146A610BD3C4300C12F0C /* freeverb.mm in Sources */, + 4B4146A710BD3C4300C12F0C /* JackGlobals.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4BCF75DB10BC2FD90082C526 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BCF75DC10BC2FD90082C526 /* JackMachThread.cpp in Sources */, + 4BCF75DD10BC2FD90082C526 /* JackMachTime.c in Sources */, + 4BCF75DE10BC2FD90082C526 /* JackNetAPI.cpp in Sources */, + 4BCF75DF10BC2FD90082C526 /* JackNetInterface.cpp in Sources */, + 4BCF75E010BC2FD90082C526 /* JackNetTool.cpp in Sources */, + 4BCF75E110BC2FD90082C526 /* JackNetUnixSocket.cpp in Sources */, + 4BCF75E210BC2FD90082C526 /* JackPosixThread.cpp in Sources */, + 4BCF75E310BC2FD90082C526 /* JackAudioQueueAdapter.cpp in Sources */, + 4BCF75E410BC2FD90082C526 /* JackAudioAdapterInterface.cpp in Sources */, + 4BCF75E510BC2FD90082C526 /* JackResampler.cpp in Sources */, + 4BCF75E610BC2FD90082C526 /* ringbuffer.c in Sources */, + 4BCF75E710BC2FD90082C526 /* iPhoneNetAppDelegate.m in Sources */, + 4BCF75E910BC2FD90082C526 /* JackGlobals.cpp in Sources */, + 4BCF75F710BC30140082C526 /* audio_thru.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFF45610F4D5D9700106083 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -585,6 +745,107 @@ }; name = Release; }; + 4B4146AE10BD3C4300C12F0C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Stéphane Letz (8LJEY2RN3N)"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = "Info copy 2.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneFaustNet; + "PROVISIONING_PROFILE[sdk=iphoneos*]" = "CEF78041-8E2A-499D-BF7C-8A1B22B6C2AC"; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + 4B4146AF10BD3C4300C12F0C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../common/jack, + ../../common, + ../../posix, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = iPhoneFaustNet; + SDKROOT = iphoneos3.1.2; + }; + name = Release; + }; + 4BCF75F010BC2FD90082C526 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../posix, + ../../common/jack, + ../../common, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + OTHER_LDFLAGS = ""; + PRODUCT_NAME = iPhoneThruNet; + SDKROOT = iphoneos2.2.1; + }; + name = Debug; + }; + 4BCF75F110BC2FD90082C526 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = iPhoneNet_Prefix.pch; + HEADER_SEARCH_PATHS = ( + ../../macosx, + ../../common/jack, + ../../common, + ../../posix, + ); + INFOPLIST_FILE = Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\\\\\\\"$(SRCROOT)/build/Debug-iphonesimulator\\\\\\\"", + ); + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = iPhoneFaustNet; + }; + name = Release; + }; 4BFF45750F4D5D9700106083 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -691,6 +952,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4B4146AD10BD3C4300C12F0C /* Build configuration list for PBXNativeTarget "iPhoneFaustNet Distribution" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4B4146AE10BD3C4300C12F0C /* Debug */, + 4B4146AF10BD3C4300C12F0C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4BCF75EF10BC2FD90082C526 /* Build configuration list for PBXNativeTarget "iPhoneThruNet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BCF75F010BC2FD90082C526 /* Debug */, + 4BCF75F110BC2FD90082C526 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4BFF45740F4D5D9700106083 /* Build configuration list for PBXNativeTarget "iPhoneFaustNet" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index a5625219..d2a59b33 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackClient.h" #include "JackTools.h" #include "JackNotification.h" +#include "JackException.h" + #include #include @@ -64,7 +66,7 @@ int JackSocketServerChannel::Open(const char* server_name, JackServer* server) void JackSocketServerChannel::Close() { - fThread.Kill(); + fThread.Stop(); fRequestListenSocket.Close(); // Close remaining client sockets @@ -387,8 +389,14 @@ bool JackSocketServerChannel::HandleRequest(int fd) case JackRequest::kNotification: { jack_log("JackRequest::Notification"); JackClientNotificationRequest req; - if (req.Read(socket) == 0) - fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + if (req.Read(socket) == 0) { + if (req.fNotify == kQUIT) { + jack_log("JackRequest::Notification kQUIT"); + throw JackQuitException(); + } else { + fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + } + } break; } @@ -436,35 +444,42 @@ bool JackSocketServerChannel::Init() bool JackSocketServerChannel::Execute() { - // Global poll - if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) { - jack_error("Engine poll failed err = %s request thread quits...", strerror(errno)); - return false; - } else { - - // Poll all clients - for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) { - int fd = fPollTable[i].fd; - jack_log("fPollTable i = %ld fd = %ld", i, fd); - if (fPollTable[i].revents & ~POLLIN) { - jack_log("Poll client error err = %s", strerror(errno)); - ClientKill(fd); - } else if (fPollTable[i].revents & POLLIN) { - if (!HandleRequest(fd)) - jack_log("Could not handle external client request"); + try { + + // Global poll + if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) { + jack_error("Engine poll failed err = %s request thread quits...", strerror(errno)); + return false; + } else { + + // Poll all clients + for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) { + int fd = fPollTable[i].fd; + jack_log("fPollTable i = %ld fd = %ld", i, fd); + if (fPollTable[i].revents & ~POLLIN) { + jack_log("Poll client error err = %s", strerror(errno)); + ClientKill(fd); + } else if (fPollTable[i].revents & POLLIN) { + if (!HandleRequest(fd)) + jack_log("Could not handle external client request"); + } } + + // Check the server request socket */ + if (fPollTable[0].revents & POLLERR) + jack_error("Error on server request socket err = %s", strerror(errno)); + + if (fPollTable[0].revents & POLLIN) + ClientCreate(); } - // Check the server request socket */ - if (fPollTable[0].revents & POLLERR) - jack_error("Error on server request socket err = %s", strerror(errno)); - - if (fPollTable[0].revents & POLLIN) - ClientCreate(); + BuildPoolTable(); + return true; + + } catch (JackQuitException& e) { + jack_log("JackMachServerChannel::Execute JackQuitException"); + return false; } - - BuildPoolTable(); - return true; } } // end of namespace diff --git a/posix/JackSocketServerNotifyChannel.cpp b/posix/JackSocketServerNotifyChannel.cpp index c4e4888a..df7381f1 100644 --- a/posix/JackSocketServerNotifyChannel.cpp +++ b/posix/JackSocketServerNotifyChannel.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackError.h" #include "JackRequest.h" #include "JackConstants.h" +#include "JackNotification.h" namespace Jack { @@ -55,6 +56,15 @@ void JackSocketServerNotifyChannel::Notify(int refnum, int notify, int value) } } +void JackSocketServerNotifyChannel::NotifyQuit() +{ + JackClientNotificationRequest req(-1, kQUIT, 0); + if (req.Write(&fRequestSocket) < 0) { + jack_error("Could not write request ref = %d notify = %d", -1, kQUIT); + } +} + + } // end of namespace diff --git a/posix/JackSocketServerNotifyChannel.h b/posix/JackSocketServerNotifyChannel.h index d8687dfa..261ddbd4 100644 --- a/posix/JackSocketServerNotifyChannel.h +++ b/posix/JackSocketServerNotifyChannel.h @@ -44,6 +44,7 @@ class JackSocketServerNotifyChannel void Close(); void Notify(int refnum, int notify, int value); + void NotifyQuit(); }; } // end of namespace diff --git a/tests/test.cpp b/tests/test.cpp index e77edf49..018b7499 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -85,6 +85,7 @@ int reorder = 0; // graph reorder callback int RT = 0; // is real time or not... int FW = 0; // freewheel mode int init_clbk = 0; // init callback +int port_rename_clbk = 0; // portrename callback int i, j, k = 0; int port_callback_reg = 0; jack_nframes_t cur_buffer_size, old_buffer_size, cur_pos; @@ -180,6 +181,13 @@ void Jack_Client_Registration_Callback(const char* name, int val, void *arg) client_register--; } +int Jack_Port_Rename_Callback(jack_port_id_t port, const char* old_name, const char* new_name, void *arg) +{ + Log("Rename callback has been successfully called with old_name '%s' and new_name '%s'. (msg from callback)\n"); + port_rename_clbk = 1; + return 0; +} + int Jack_Update_Buffer_Size(jack_nframes_t nframes, void *arg) { cur_buffer_size = jack_get_buffer_size(client1); @@ -679,6 +687,7 @@ int main (int argc, char *argv[]) printf("!!! ERROR !!! while calling jack_set_thread_init_callback()...\n"); if (jack_set_freewheel_callback(client1, Jack_Freewheel_Callback, 0) != 0 ) printf("\n!!! ERROR !!! while calling jack_set_freewheel_callback()...\n"); + if (jack_set_process_callback(client1, process1, 0) != 0) { printf("Error when calling jack_set_process_callback() !\n"); @@ -694,6 +703,9 @@ int main (int argc, char *argv[]) if (jack_set_graph_order_callback(client1, Jack_Graph_Order_Callback, 0) != 0) { printf("Error when calling Jack_Graph_Order_Callback() !\n"); } + + if (jack_set_port_rename_callback(client1, Jack_Port_Rename_Callback, 0) != 0 ) + printf("\n!!! ERROR !!! while calling jack_set_rename_callback()...\n"); if (jack_set_xrun_callback(client1, Jack_XRun_Callback, 0 ) != 0) { printf("Error when calling jack_set_xrun_callback() !\n"); @@ -818,13 +830,23 @@ int main (int argc, char *argv[]) printf ("Fatal error : cannot activate client1\n"); exit(1); } + + /** + * Test if portrename callback have been called. + * + */ + jack_port_set_name (output_port1, "renamed-port#"); + jack_sleep(1 * 1000); + if (port_rename_clbk == 0) + printf("!!! ERROR !!! Jack_Port_Rename_Callback was not called !!.\n"); + /** * Test if init callback initThread have been called. * */ if (init_clbk == 0) - printf("!!! ERROR !!! JackThreadInitCallback was not called !!.\n"); + printf("!!! ERROR !!! Jack_Thread_Init_Callback was not called !!.\n"); jack_sleep(10 * 1000); // test see the clock in the graph at the begining... diff --git a/windows/JackRouter/JackRouter.cpp b/windows/JackRouter/JackRouter.cpp new file mode 100644 index 00000000..47727af7 --- /dev/null +++ b/windows/JackRouter/JackRouter.cpp @@ -0,0 +1,840 @@ +/* +Copyright (C) 2006 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif + +#include +#include +#include +#include +#include "JackRouter.h" +#include "profport.h" + +/* + + 08/07/2007 SL : USe jack_client_open instead of jack_client_new (automatic client renaming). + 09/08/2007 SL : Add JackRouter.ini parameter file. + 09/20/2007 SL : Better error report in DllRegisterServer (for Vista). + 09/27/2007 SL : Add AUDO_CONNECT property in JackRouter.ini file. + 10/10/2007 SL : Use ASIOSTInt32LSB instead of ASIOSTInt16LSB. + + */ + +//------------------------------------------------------------------------------------------ +// extern +void getNanoSeconds(ASIOTimeStamp *time); + +// local +double AsioSamples2double (ASIOSamples* samples); + +static const double twoRaisedTo32 = 4294967296.; +static const double twoRaisedTo32Reciprocal = 1. / twoRaisedTo32; + +//------------------------------------------------------------------------------------------ +// on windows, we do the COM stuff. + +#if WINDOWS +#include "windows.h" +#include "mmsystem.h" +#include "psapi.h" + +using namespace std; + +// class id. +// {838FE50A-C1AB-4b77-B9B6-0A40788B53F3} +CLSID IID_ASIO_DRIVER = { 0x838fe50a, 0xc1ab, 0x4b77, { 0xb9, 0xb6, 0xa, 0x40, 0x78, 0x8b, 0x53, 0xf3 } }; + + +CFactoryTemplate g_Templates[1] = { + {L"ASIOJACK", &IID_ASIO_DRIVER, JackRouter::CreateInstance} +}; +int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); + +CUnknown* JackRouter::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) +{ + return (CUnknown*)new JackRouter(pUnk,phr); +}; + +STDMETHODIMP JackRouter::NonDelegatingQueryInterface(REFIID riid, void ** ppv) +{ + if (riid == IID_ASIO_DRIVER) { + return GetInterface(this, ppv); + } + return CUnknown::NonDelegatingQueryInterface(riid, ppv); +} + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Register ASIO Driver +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +extern LONG RegisterAsioDriver(CLSID,char *,char *,char *,char *); +extern LONG UnregisterAsioDriver(CLSID,char *,char *); + +// +// Server registration, called on REGSVR32.EXE "the dllname.dll" +// +HRESULT _stdcall DllRegisterServer() +{ + LONG rc; + char errstr[128]; + + rc = RegisterAsioDriver (IID_ASIO_DRIVER,"JackRouter.dll","JackRouter","JackRouter","Apartment"); + + if (rc) { + memset(errstr,0,128); + sprintf(errstr,"Register Server failed ! (%d)",rc); + MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); + return -1; + } + + return S_OK; +} + +// +// Server unregistration +// +HRESULT _stdcall DllUnregisterServer() +{ + LONG rc; + char errstr[128]; + + rc = UnregisterAsioDriver (IID_ASIO_DRIVER,"JackRouter.dll","JackRouter"); + + if (rc) { + memset(errstr,0,128); + sprintf(errstr,"Unregister Server failed ! (%d)",rc); + MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); + return -1; + } + + return S_OK; +} + +// Globals + +list > JackRouter::fConnections; +bool JackRouter::fFirstActivate = true; + +//------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------ +JackRouter::JackRouter (LPUNKNOWN pUnk, HRESULT *phr) + : CUnknown("ASIOJACK", pUnk, phr) + +//------------------------------------------------------------------------------------------ + +#else + +// when not on windows, we derive from AsioDriver +JackRouter::JackRouter() : AsioDriver() + +#endif +{ + long i; + + fSamplePosition = 0; + fActive = false; + fStarted = false; + fTimeInfoMode = false; + fTcRead = false; + fClient = NULL; + fAutoConnectIn = true; + fAutoConnectOut = true; + + for (i = 0; i < kNumInputs; i++) { + fInputBuffers[i] = 0; + fInputPorts[i] = 0; + fInMap[i] = 0; + } + for (i = 0; i < kNumOutputs; i++) { + fOutputBuffers[i] = 0; + fOutputPorts[i] = 0; + fOutMap[i] = 0; + } + fCallbacks = 0; + fActiveInputs = fActiveOutputs = 0; + fToggle = 0; + fBufferSize = 512; + fSampleRate = 44100; + printf("Constructor\n"); + + // Use "jackrouter.ini" parameters if available + HMODULE handle = LoadLibrary("JackRouter.dll"); + + if (handle) { + + // Get JackRouter.dll path + char dllName[512]; + string confPath; + DWORD res = GetModuleFileName(handle, dllName, 512); + + // Compute .ini file path + string fullPath = dllName; + int lastPos = fullPath.find_last_of(PATH_SEP); + string dllFolder = fullPath.substr(0, lastPos); + confPath = dllFolder + PATH_SEP + "JackRouter.ini"; + + // Get parameters + kNumInputs = get_private_profile_int("IO", "input", 2, confPath.c_str()); + kNumOutputs = get_private_profile_int("IO", "output", 2, confPath.c_str()); + + fAutoConnectIn = get_private_profile_int("AUTO_CONNECT", "input", 1, confPath.c_str()); + fAutoConnectOut = get_private_profile_int("AUTO_CONNECT", "output", 1, confPath.c_str()); + + FreeLibrary(handle); + + } else { + printf("LoadLibrary error\n"); + } +} + +//------------------------------------------------------------------------------------------ +JackRouter::~JackRouter() +{ + stop (); + disposeBuffers (); + printf("Destructor\n"); + jack_client_close(fClient); +} + +//------------------------------------------------------------------------------------------ +#include +#include +#include +#include "psapi.h" + +static bool GetEXEName(DWORD dwProcessID, char* name) +{ + DWORD aProcesses [1024], cbNeeded, cProcesses; + unsigned int i; + + // Enumerate all processes + if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) + return false; + + // Calculate how many process identifiers were returned. + cProcesses = cbNeeded / sizeof(DWORD); + + TCHAR szEXEName[MAX_PATH]; + // Loop through all process to find the one that matches + // the one we are looking for + + for (i = 0; i < cProcesses; i++) { + if (aProcesses [i] == dwProcessID) { + // Get a handle to the process + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, FALSE, dwProcessID); + + // Get the process name + if (NULL != hProcess) { + HMODULE hMod; + DWORD cbNeeded; + + if(EnumProcessModules(hProcess, &hMod, + sizeof(hMod), &cbNeeded)) { + //Get the name of the exe file + GetModuleBaseName(hProcess, hMod, szEXEName, + sizeof(szEXEName)/sizeof(TCHAR)); + int len = strlen((char*)szEXEName) - 4; // remove ".exe" + strncpy(name, (char*)szEXEName, len); + name[len] = '\0'; + return true; + } + } + } + } + + return false; +} + + //------------------------------------------------------------------------------------------ +static inline float ClipFloat(float sample) +{ + return (sample < -1.0f) ? -1.0f : (sample > 1.0f) ? 1.0f : sample; +} + +//------------------------------------------------------------------------------------------ +void JackRouter::shutdown(void* arg) +{ + JackRouter* driver = (JackRouter*)arg; + /* + //exit(1); + char errstr[128]; + + memset(errstr,0,128); + sprintf(errstr,"JACK server has quitted"); + MessageBox(0,(LPCTSTR)errstr,(LPCTSTR)"JackRouter",MB_OK); + */ +} + +//------------------------------------------------------------------------------------------ +int JackRouter::process(jack_nframes_t nframes, void* arg) +{ + JackRouter* driver = (JackRouter*)arg; + int i,j; + int pos = (driver->fToggle) ? 0 : driver->fBufferSize ; + + for (i = 0; i < driver->fActiveInputs; i++) { + +#ifdef LONG_SAMPLE + float* buffer = (float*)jack_port_get_buffer(driver->fInputPorts[i], nframes); + long* in = driver->fInputBuffers[i] + pos; + for (j = 0; j < nframes; j++) { + in[j] = buffer[j] * float(0x7fffffff); + } +#else + memcpy(driver->fInputBuffers[i] + pos, + jack_port_get_buffer(driver->fInputPorts[i], nframes), + nframes * sizeof(float)); +#endif + + } + + driver->bufferSwitch(); + + for (i = 0; i < driver->fActiveOutputs; i++) { + +#ifdef LONG_SAMPLE + float* buffer = (float*)jack_port_get_buffer(driver->fOutputPorts[i], nframes); + long* out = driver->fOutputBuffers[i] + pos; + float gain = 1.f/float(0x7fffffff); + for (j = 0; j < nframes; j++) { + buffer[j] = out[j] * gain; + } +#else + memcpy(jack_port_get_buffer(driver->fOutputPorts[i], nframes), + driver->fOutputBuffers[i] + pos, + nframes * sizeof(float)); +#endif + } + + return 0; +} + +//------------------------------------------------------------------------------------------ +void JackRouter::getDriverName(char *name) +{ + strcpy (name, "JackRouter"); +} + +//------------------------------------------------------------------------------------------ +long JackRouter::getDriverVersion() +{ + return 0x00000001L; +} + +//------------------------------------------------------------------------------------------ +void JackRouter::getErrorMessage(char *string) +{ + strcpy (string, fErrorMessage); +} + +//------------------------------------------------------------------------------------------ +ASIOBool JackRouter::init(void* sysRef) +{ + char name[MAX_PATH]; + sysRef = sysRef; + + if (fActive) + return true; + + HANDLE win = (HANDLE)sysRef; + int my_pid = _getpid(); + + if (!GetEXEName(my_pid, name)) { // If getting the .exe name fails, takes a generic one. + _snprintf(name, sizeof(name) - 1, "JackRouter_%d", my_pid); + } + + if (fClient) { + printf("Error: jack client still present...\n"); + return true; + } + + fClient = jack_client_open(name, JackNullOption, NULL); + if (fClient == NULL) { + strcpy (fErrorMessage, "Open error: is jack server running?"); + printf("Open error: is jack server running?\n"); + return false; + } + + fBufferSize = jack_get_buffer_size(fClient); + fSampleRate = jack_get_sample_rate(fClient); + jack_set_process_callback(fClient, process, this); + jack_on_shutdown(fClient, shutdown, this); + + fInputLatency = fBufferSize; // typically + fOutputLatency = fBufferSize * 2; + fMilliSeconds = (long)((double)(fBufferSize * 1000) / fSampleRate); + + // Typically fBufferSize * 2; try to get 1 by offering direct buffer + // access, and using asioPostOutput for lower latency + + printf("Init ASIO Jack\n"); + fActive = true; + return true; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::start() +{ + if (fCallbacks) { + fSamplePosition = 0; + fTheSystemTime.lo = fTheSystemTime.hi = 0; + fToggle = 0; + fStarted = true; + printf("Start ASIO Jack\n"); + + if (jack_activate(fClient) == 0) { + + if (fFirstActivate) { + AutoConnect(); + fFirstActivate = false; + } else { + RestoreConnections(); + } + + return ASE_OK; + + } else { + return ASE_NotPresent; + } + } + + return ASE_NotPresent; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::stop() +{ + fStarted = false; + printf("Stop ASIO Jack\n"); + SaveConnections(); + jack_deactivate(fClient); + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getChannels(long *numInputChannels, long *numOutputChannels) +{ + *numInputChannels = kNumInputs; + *numOutputChannels = kNumOutputs; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getLatencies(long *_inputLatency, long *_outputLatency) +{ + *_inputLatency = fInputLatency; + *_outputLatency = fOutputLatency; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) +{ + *minSize = *maxSize = *preferredSize = fBufferSize; // allow this size only + *granularity = 0; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::canSampleRate(ASIOSampleRate sampleRate) +{ + return (sampleRate == fSampleRate) ? ASE_OK : ASE_NoClock; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getSampleRate(ASIOSampleRate *sampleRate) +{ + *sampleRate = fSampleRate; + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::setSampleRate(ASIOSampleRate sampleRate) +{ + return (sampleRate == fSampleRate) ? ASE_OK : ASE_NoClock; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getClockSources(ASIOClockSource *clocks, long *numSources) +{ + // Internal + if (clocks && numSources) { + clocks->index = 0; + clocks->associatedChannel = -1; + clocks->associatedGroup = -1; + clocks->isCurrentSource = ASIOTrue; + strcpy(clocks->name, "Internal"); + *numSources = 1; + return ASE_OK; + } else { + return ASE_InvalidParameter; + } +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::setClockSource(long index) +{ + if (!index) { + fAsioTime.timeInfo.flags |= kClockSourceChanged; + return ASE_OK; + } else { + return ASE_NotPresent; + } +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) +{ + tStamp->lo = fTheSystemTime.lo; + tStamp->hi = fTheSystemTime.hi; + + if (fSamplePosition >= twoRaisedTo32) { + sPos->hi = (unsigned long)(fSamplePosition * twoRaisedTo32Reciprocal); + sPos->lo = (unsigned long)(fSamplePosition - (sPos->hi * twoRaisedTo32)); + } else { + sPos->hi = 0; + sPos->lo = (unsigned long)fSamplePosition; + } + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::getChannelInfo(ASIOChannelInfo *info) +{ + if (info->channel < 0 || (info->isInput ? info->channel >= kNumInputs : info->channel >= kNumOutputs)) + return ASE_InvalidParameter; +#ifdef LONG_SAMPLE + info->type = ASIOSTInt32LSB; +#else + info->type = ASIOSTFloat32LSB; +#endif + + info->channelGroup = 0; + info->isActive = ASIOFalse; + long i; + char buf[32]; + + if (info->isInput) { + for (i = 0; i < fActiveInputs; i++) { + if (fInMap[i] == info->channel) { + info->isActive = ASIOTrue; + //_snprintf(buf, sizeof(buf) - 1, "Jack::In%d ", info->channel); + //strcpy(info->name, buf); + //strcpy(info->name, jack_port_name(fInputPorts[i])); + break; + } + } + _snprintf(buf, sizeof(buf) - 1, "In%d ", info->channel); + strcpy(info->name, buf); + } else { + for (i = 0; i < fActiveOutputs; i++) { + if (fOutMap[i] == info->channel) { //NOT USED !! + info->isActive = ASIOTrue; + //_snprintf(buf, sizeof(buf) - 1, "Jack::Out%d ", info->channel); + //strcpy(info->name, buf); + //strcpy(info->name, jack_port_name(fOutputPorts[i])); + break; + } + } + _snprintf(buf, sizeof(buf) - 1, "Out%d ", info->channel); + strcpy(info->name, buf); + } + return ASE_OK; +} + +//------------------------------------------------------------------------------------------ +ASIOError JackRouter::createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks) +{ + ASIOBufferInfo *info = bufferInfos; + long i; + bool notEnoughMem = false; + char buf[256]; + fActiveInputs = 0; + fActiveOutputs = 0; + + for (i = 0; i < numChannels; i++, info++) { + if (info->isInput) { + if (info->channelNum < 0 || info->channelNum >= kNumInputs) + goto error; + fInMap[fActiveInputs] = info->channelNum; + #ifdef LONG_SAMPLE + fInputBuffers[fActiveInputs] = new long[fBufferSize * 2]; // double buffer + #else + fInputBuffers[fActiveInputs] = new float[fBufferSize * 2]; // double buffer + #endif + if (fInputBuffers[fActiveInputs]) { + info->buffers[0] = fInputBuffers[fActiveInputs]; + info->buffers[1] = fInputBuffers[fActiveInputs] + fBufferSize; + } else { + info->buffers[0] = info->buffers[1] = 0; + notEnoughMem = true; + } + + _snprintf(buf, sizeof(buf) - 1, "in%d", fActiveInputs + 1); + fInputPorts[fActiveInputs] + = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput,0); + if (fInputPorts[fActiveInputs] == NULL) + goto error; + + fActiveInputs++; + if (fActiveInputs > kNumInputs) { +error: + disposeBuffers(); + return ASE_InvalidParameter; + } + } else { // output + if (info->channelNum < 0 || info->channelNum >= kNumOutputs) + goto error; + fOutMap[fActiveOutputs] = info->channelNum; + + #ifdef LONG_SAMPLE + fOutputBuffers[fActiveOutputs] = new long[fBufferSize * 2]; // double buffer + #else + fOutputBuffers[fActiveOutputs] = new float[fBufferSize * 2]; // double buffer + #endif + + if (fOutputBuffers[fActiveOutputs]) { + info->buffers[0] = fOutputBuffers[fActiveOutputs]; + info->buffers[1] = fOutputBuffers[fActiveOutputs] + fBufferSize; + } else { + info->buffers[0] = info->buffers[1] = 0; + notEnoughMem = true; + } + + _snprintf(buf, sizeof(buf) - 1, "out%d", fActiveOutputs + 1); + fOutputPorts[fActiveOutputs] + = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput,0); + if (fOutputPorts[fActiveOutputs] == NULL) + goto error; + + fActiveOutputs++; + if (fActiveOutputs > kNumOutputs) { + fActiveOutputs--; + disposeBuffers(); + return ASE_InvalidParameter; + } + } + } + + if (notEnoughMem) { + disposeBuffers(); + return ASE_NoMemory; + } + + this->fCallbacks = callbacks; + if (callbacks->asioMessage (kAsioSupportsTimeInfo, 0, 0, 0)) { + fTimeInfoMode = true; + fAsioTime.timeInfo.speed = 1.; + fAsioTime.timeInfo.systemTime.hi = fAsioTime.timeInfo.systemTime.lo = 0; + fAsioTime.timeInfo.samplePosition.hi = fAsioTime.timeInfo.samplePosition.lo = 0; + fAsioTime.timeInfo.sampleRate = fSampleRate; + fAsioTime.timeInfo.flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid; + + fAsioTime.timeCode.speed = 1.; + fAsioTime.timeCode.timeCodeSamples.lo = fAsioTime.timeCode.timeCodeSamples.hi = 0; + fAsioTime.timeCode.flags = kTcValid | kTcRunning ; + } else { + fTimeInfoMode = false; + } + + return ASE_OK; +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::disposeBuffers() +{ + long i; + + fCallbacks = 0; + stop(); + + for (i = 0; i < fActiveInputs; i++) { + delete[] fInputBuffers[i]; + jack_port_unregister(fClient, fInputPorts[i]); + } + fActiveInputs = 0; + + for (i = 0; i < fActiveOutputs; i++) { + delete[] fOutputBuffers[i]; + jack_port_unregister(fClient, fOutputPorts[i]); + } + fActiveOutputs = 0; + + return ASE_OK; +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::controlPanel() +{ + return ASE_NotPresent; +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::future(long selector, void* opt) // !!! check properties +{ + ASIOTransportParameters* tp = (ASIOTransportParameters*)opt; + switch (selector) + { + case kAsioEnableTimeCodeRead: fTcRead = true; return ASE_SUCCESS; + case kAsioDisableTimeCodeRead: fTcRead = false; return ASE_SUCCESS; + case kAsioSetInputMonitor: return ASE_SUCCESS; // for testing!!! + case kAsioCanInputMonitor: return ASE_SUCCESS; // for testing!!! + case kAsioCanTimeInfo: return ASE_SUCCESS; + case kAsioCanTimeCode: return ASE_SUCCESS; + } + return ASE_NotPresent; +} + +//-------------------------------------------------------------------------------------------------------- +// private methods +//-------------------------------------------------------------------------------------------------------- + +//--------------------------------------------------------------------------------------------- +void JackRouter::bufferSwitch() +{ + if (fStarted && fCallbacks) { + getNanoSeconds(&fTheSystemTime); // latch system time + fSamplePosition += fBufferSize; + if (fTimeInfoMode) { + bufferSwitchX (); + } else { + fCallbacks->bufferSwitch (fToggle, ASIOFalse); + } + fToggle = fToggle ? 0 : 1; + } +} + +//--------------------------------------------------------------------------------------------- +// asio2 buffer switch +void JackRouter::bufferSwitchX () +{ + getSamplePosition (&fAsioTime.timeInfo.samplePosition, &fAsioTime.timeInfo.systemTime); + long offset = fToggle ? fBufferSize : 0; + if (fTcRead) { + // Create a fake time code, which is 10 minutes ahead of the card's sample position + // Please note that for simplicity here time code will wrap after 32 bit are reached + fAsioTime.timeCode.timeCodeSamples.lo = fAsioTime.timeInfo.samplePosition.lo + 600.0 * fSampleRate; + fAsioTime.timeCode.timeCodeSamples.hi = 0; + } + fCallbacks->bufferSwitchTimeInfo (&fAsioTime, fToggle, ASIOFalse); + fAsioTime.timeInfo.flags &= ~(kSampleRateChanged | kClockSourceChanged); +} + +//--------------------------------------------------------------------------------------------- +ASIOError JackRouter::outputReady() +{ + return ASE_NotPresent; +} + +//--------------------------------------------------------------------------------------------- +double AsioSamples2double(ASIOSamples* samples) +{ + double a = (double)(samples->lo); + if (samples->hi) + a += (double)(samples->hi) * twoRaisedTo32; + return a; +} + +//--------------------------------------------------------------------------------------------- +void getNanoSeconds(ASIOTimeStamp* ts) +{ + double nanoSeconds = (double)((unsigned long)timeGetTime ()) * 1000000.; + ts->hi = (unsigned long)(nanoSeconds / twoRaisedTo32); + ts->lo = (unsigned long)(nanoSeconds - (ts->hi * twoRaisedTo32)); +} + +//------------------------------------------------------------------------ +void JackRouter::SaveConnections() +{ + const char** connections; + int i; + + for (i = 0; i < fActiveInputs; ++i) { + if (fInputPorts[i] && (connections = jack_port_get_connections(fInputPorts[i])) != 0) { + for (int j = 0; connections[j]; j++) { + fConnections.push_back(make_pair(connections[j], jack_port_name(fInputPorts[i]))); + } + jack_free(connections); + } + } + + for (i = 0; i < fActiveOutputs; ++i) { + if (fOutputPorts[i] && (connections = jack_port_get_connections(fOutputPorts[i])) != 0) { + for (int j = 0; connections[j]; j++) { + fConnections.push_back(make_pair(jack_port_name(fOutputPorts[i]), connections[j])); + } + jack_free(connections); + } + } +} + +//------------------------------------------------------------------------ +void JackRouter::RestoreConnections() +{ + list >::const_iterator it; + + for (it = fConnections.begin(); it != fConnections.end(); it++) { + pair connection = *it; + jack_connect(fClient, connection.first.c_str(), connection.second.c_str()); + } + + fConnections.clear(); +} + +//------------------------------------------------------------------------------------------ +void JackRouter::AutoConnect() +{ + const char** ports; + + if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL) { + printf("Cannot find any physical capture ports\n"); + } else { + if (fAutoConnectIn) { + for (int i = 0; i < fActiveInputs; i++) { + if (!ports[i]) { + printf("source port is null i = %ld\n", i); + break; + } else if (jack_connect(fClient, ports[i], jack_port_name(fInputPorts[i])) != 0) { + printf("Cannot connect input ports\n"); + } + } + } + jack_free(ports); + } + + if ((ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput)) == NULL) { + printf("Cannot find any physical playback ports"); + } else { + if (fAutoConnectOut) { + for (int i = 0; i < fActiveOutputs; i++) { + if (!ports[i]){ + printf("destination port is null i = %ld\n", i); + break; + } else if (jack_connect(fClient, jack_port_name(fOutputPorts[i]), ports[i]) != 0) { + printf("Cannot connect output ports\n"); + } + } + } + jack_free(ports); + } +} + diff --git a/windows/JackRouter/JackRouter.def b/windows/JackRouter/JackRouter.def new file mode 100644 index 00000000..1316d71f --- /dev/null +++ b/windows/JackRouter/JackRouter.def @@ -0,0 +1,9 @@ +LIBRARY JackRouter +DESCRIPTION 'ASIO Jack Driver' +PROTMODE +EXPORTS + DllMain + DllGetClassObject + DllCanUnloadNow + DllRegisterServer + DllUnregisterServer diff --git a/windows/JackRouter/JackRouter.dsp b/windows/JackRouter/JackRouter.dsp new file mode 100644 index 00000000..c92ddf99 --- /dev/null +++ b/windows/JackRouter/JackRouter.dsp @@ -0,0 +1,163 @@ +# Microsoft Developer Studio Project File - Name="JackRouter" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=JackRouter - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "JackRouter.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "JackRouter.mak" CFG="JackRouter - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "JackRouter - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "JackRouter - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "JackRouter - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /machine:I386 + +!ELSEIF "$(CFG)" == "JackRouter - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /G5 /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\..\ASIOSDK2\common" /I "..\..\common" /I "..\..\common\jack" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Debug/JackRouter_debug.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "JackRouter - Win32 Release" +# Name "JackRouter - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\..\..\ASIOSDK2\common\combase.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\ASIOSDK2\common\dllentry.cpp +# End Source File +# Begin Source File + +SOURCE=.\JackRouter.cpp +# End Source File +# Begin Source File + +SOURCE=.\JackRouter.def +# End Source File +# Begin Source File + +SOURCE=.\profport.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\..\ASIOSDK2\common\register.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\common\asio.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\Asiodrvr.h +# End Source File +# Begin Source File + +SOURCE=..\asiosmpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\asiosys.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\combase.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\common\iasiodrv.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=.\Psapi.Lib +# End Source File +# Begin Source File + +SOURCE=..\Release\bin\libjack.lib +# End Source File +# End Target +# End Project diff --git a/windows/JackRouter/JackRouter.dsw b/windows/JackRouter/JackRouter.dsw new file mode 100644 index 00000000..e26ab1ee --- /dev/null +++ b/windows/JackRouter/JackRouter.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "JackRouter"=".\JackRouter.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/windows/JackRouter/JackRouter.h b/windows/JackRouter/JackRouter.h new file mode 100644 index 00000000..bf5d44c8 --- /dev/null +++ b/windows/JackRouter/JackRouter.h @@ -0,0 +1,174 @@ +/* +Copyright (C) 2006 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _asiosmpl_ +#define _asiosmpl_ + +#include "asiosys.h" + + +// Globals +static int kBlockFrames = 256; +static int kNumInputs = 4; +static int kNumOutputs = 4; + + +#if WINDOWS + +#include "jack.h" +#include "rpc.h" +#include "rpcndr.h" +#ifndef COM_NO_WINDOWS_H +#include +#include "ole2.h" + +#endif + +#include "combase.h" +#include "iasiodrv.h" + +#define MAX_PORTS 32 + +#define LONG_SAMPLE 1 + +#define PATH_SEP "\\" + +#include +#include + +class JackRouter : public IASIO, public CUnknown +{ +public: + JackRouter(LPUNKNOWN pUnk, HRESULT *phr); + ~JackRouter(); + + DECLARE_IUNKNOWN + //STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ + // return GetOwner()->QueryInterface(riid,ppv); \ + //}; \ + //STDMETHODIMP_(ULONG) AddRef() { \ + // return GetOwner()->AddRef(); \ + //}; \ + //STDMETHODIMP_(ULONG) Release() { \ + // return GetOwner()->Release(); \ + //}; + + // Factory method + static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); + // IUnknown + virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); +#else + +#include "asiodrvr.h" + + +//--------------------------------------------------------------------------------------------- +class JackRouter : public AsioDriver +{ +public: + JackRouter(); + ~JackRouter(); +#endif + + static int process(jack_nframes_t nframes, void* arg); + static void shutdown(void* arg); + + ASIOBool init(void* sysRef); + void getDriverName(char *name); // max 32 bytes incl. terminating zero + long getDriverVersion(); + void getErrorMessage(char *string); // max 128 bytes incl. + + ASIOError start(); + ASIOError stop(); + + ASIOError getChannels(long *numInputChannels, long *numOutputChannels); + ASIOError getLatencies(long *inputLatency, long *outputLatency); + ASIOError getBufferSize(long *minSize, long *maxSize, + long *preferredSize, long *granularity); + + ASIOError canSampleRate(ASIOSampleRate sampleRate); + ASIOError getSampleRate(ASIOSampleRate *sampleRate); + ASIOError setSampleRate(ASIOSampleRate sampleRate); + ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); + ASIOError setClockSource(long index); + + ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); + ASIOError getChannelInfo(ASIOChannelInfo *info); + + ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, + long bufferSize, ASIOCallbacks *callbacks); + ASIOError disposeBuffers(); + + ASIOError controlPanel(); + ASIOError future(long selector, void *opt); + ASIOError outputReady(); + + void bufferSwitch(); + long getMilliSeconds() {return fMilliSeconds;} + + static bool fFirstActivate; + static std::list > fConnections; // Connections list + +private: + + void bufferSwitchX(); + + double fSamplePosition; + ASIOCallbacks* fCallbacks; + ASIOTime fAsioTime; + ASIOTimeStamp fTheSystemTime; + +#ifdef LONG_SAMPLE + long* fInputBuffers[MAX_PORTS * 2]; + long* fOutputBuffers[MAX_PORTS * 2]; +#else + float* fInputBuffers[MAX_PORTS * 2]; + float* fOutputBuffers[MAX_PORTS * 2]; +#endif + long fInMap[MAX_PORTS]; + long fOutMap[MAX_PORTS]; + + long fInputLatency; + long fOutputLatency; + long fActiveInputs; + long fActiveOutputs; + long fToggle; + long fMilliSeconds; + bool fActive, fStarted; + bool fTimeInfoMode, fTcRead; + char fErrorMessage[128]; + + bool fAutoConnectIn; + bool fAutoConnectOut; + + // Jack part + jack_client_t* fClient; + jack_port_t* fInputPorts[MAX_PORTS]; + jack_port_t* fOutputPorts[MAX_PORTS]; + long fBufferSize; + ASIOSampleRate fSampleRate; + + void AutoConnect(); + void SaveConnections(); + void RestoreConnections(); + +}; + +#endif + diff --git a/windows/JackRouter/Psapi.Lib b/windows/JackRouter/Psapi.Lib new file mode 100644 index 00000000..ae896911 Binary files /dev/null and b/windows/JackRouter/Psapi.Lib differ diff --git a/windows/JackRouter/README b/windows/JackRouter/README new file mode 100644 index 00000000..5f2bce1d --- /dev/null +++ b/windows/JackRouter/README @@ -0,0 +1,3 @@ +This folder contains the sources for ASIO/JACK bridge ASIO driver called "JackRouter". The included project is a Microsoft VC++ 6 one. +It requires some files (combase.cpp, dllentry.cpp, register.cpp) that are part on the ASIO driver SDK. The produced "JackRouter.dll" file +has to be registered in the system using the "regsvr32" tool. \ No newline at end of file diff --git a/windows/JackRouter/profport.cpp b/windows/JackRouter/profport.cpp new file mode 100644 index 00000000..eb77937f --- /dev/null +++ b/windows/JackRouter/profport.cpp @@ -0,0 +1,315 @@ +/* +History : +01-28-02 : Change the location of temporary files created in write_private_profile_string + now done in TmpDirectory. +01-29-02 : Correct bug when the '=' character is not present. +06-18-02 : Return default value if file does not exist, new write_private_profile_int function. +*/ + +/***** Routines to read profile strings -- by Joseph J. Graf ******/ +/***** corrections and improvements -- by D. Fober - Grame ******/ +/* + corrections: buffer sizes control + improvements: behavior more similar to windows +*/ + +#include +#include +#include +#include + +#include + +#include +#include "profport.h" /* function prototypes in here */ + +#ifndef WIN32 + +static int read_line (FILE *fp, char *bp, int size); +static int read_section(FILE *fp, char *section); +static int read_entry (FILE *fp, char *entry, char *buff, int size); +static char * read_value (char *buff); +static int read_int_value (char *buff, int def); +static char * read_file (char *file); +static char * str_search (char * buff, char * str, int stopCond); + +/***************************************************************** +* Function: read_line() +* Arguments: fp - a pointer to the file to be read from +* bp - a pointer to the copy buffer +* size - size of the copy buffer +* Returns: the line length if successful -1 otherwise +******************************************************************/ +static int read_line(FILE *fp, char *bp, int size) +{ + char c = '\0'; + int i = 0, limit = size-2; + + /* Read one line from the source file */ + while (((c = getc(fp)) != '\n') && (i < limit)) { + if (c == EOF) { + if (!i) return -1; + else break; + } + bp[i++] = c; + } + bp[i] = '\0'; + return i; +} + +static int read_section (FILE *fp, char *section) +{ + char buff[MAX_LINE_LENGTH]; + char t_section[MAX_LINE_LENGTH]; + int n, slen; + + sprintf(t_section,"[%s]", section); /* Format the section name */ + slen = strlen (t_section); + /* Move through file 1 line at a time until a section is matched or EOF */ + do { + n = read_line(fp, buff, MAX_LINE_LENGTH); + if (n == -1) + return 0; + } while (strncmp (buff,t_section, slen)); + return 1; + } + +static int read_entry (FILE *fp, char *entry, char *buff, int size) +{ + int n, elen = strlen (entry); + + do { + n = read_line(fp, buff, size); + if (n == -1) + return 0; + else if (*buff == '[') + return 0; + } while (strncmp (buff, entry, elen)); + return 1; + } + +#define isBlank(c) ((c == ' ') || (c == '\t')) +static char * read_value (char *buff) +{ + char * eq = strrchr (buff,'='); /* Parse out the equal sign */ + if (eq) { + eq++; + while (*eq && isBlank(*eq)) + eq++; +// return *eq ? eq : 0; + return eq; + } + return eq; + } + +#define isSignedDigit(c) (isdigit(c) || (c == '+') || (c == '-')) +static int read_int_value (char *buff, int def) +{ + char * val = read_value (buff); + char value[20]; int i; + + if (!*val) return def; + + for (i = 0; isSignedDigit(*val) && (i <= 10); i++ ) + value[i] = *val++; + value[i] = '\0'; + return value[0] ? atoi(value) : def; +} + +static char * read_file (char *file) +{ + FILE *fd = fopen (file,"r"); + int size; char * buff = 0; + + if (!fd) return 0; + if (fseek (fd, 0, SEEK_END) == -1) goto err; + size = ftell (fd); + if (size < 0) goto err; + if (fseek (fd, 0, SEEK_SET) == -1) goto err; + buff = (char *) malloc (size+1); + if (buff) { + *buff = 0; + fread (buff, 1, size, fd); + buff[size] = 0; + } +err: + fclose (fd); + return buff; +} + +static char * str_search (char * buff, char * str, int stopCond) +{ + char *ptr = buff; + int len = strlen (str); + while (*ptr && strncmp (ptr, str, len)) { + while (*ptr && (*ptr++ != '\n')) + ; + if (*ptr == stopCond) + return 0; + } + return *ptr ? ptr : 0; +} + +/************************************************************************** +* Function: get_private_profile_int() +* Arguments: section - the name of the section to search for +* entry - the name of the entry to find the value of +* def - the default value in the event of a failed read +* file_name - the name of the .ini file to read from +* Returns: the value located at entry +***************************************************************************/ +int get_private_profile_int(char *section, + char *entry, int def, char *file_name) +{ + FILE *fp = fopen(file_name,"r"); + char buff[MAX_LINE_LENGTH]; + + if( !fp ) return def; /* Return default value if file does not exist */ + if (!read_section (fp, section)) goto err; + if (!read_entry (fp, entry, buff, MAX_LINE_LENGTH)) goto err; + def = read_int_value (buff, def); +err: + fclose (fp); + return def; +} + +/************************************************************************** +* Function: get_private_profile_string() +* Arguments: section - the name of the section to search for +* entry - the name of the entry to find the value of +* def - default string in the event of a failed read +* buffer - a pointer to the buffer to copy into +* buffer_len - the max number of characters to copy +* file_name - the name of the .ini file to read from +* Returns: the number of characters copied into the supplied buffer +***************************************************************************/ + +int get_private_profile_string(char *section, char *entry, char *def, + char *buffer, int buffer_len, char *file_name) +{ + FILE *fp = fopen (file_name,"r"); + char buff[MAX_LINE_LENGTH]; + char *val; + + if( !fp ) goto err; /* Return default value if file does not exist */ + if (!read_section (fp, section)) goto err; + if (!read_entry (fp, entry, buff, MAX_LINE_LENGTH)) goto err; + val = read_value (buff); + if(val) def = val; + +err: + if (fp) fclose (fp); + if (def) { + strncpy (buffer, def, buffer_len - 1); + buffer[buffer_len] = '\0'; + } + else buffer[buffer_len] = '\0'; + return strlen (buffer); +} + + +/*************************************************************************** + * Function: write_private_profile_string() + * Arguments: section - the name of the section to search for + * entry - the name of the entry to find the value of + * buffer - pointer to the buffer that holds the string + * file_name - the name of the .ini file to read from + * Returns: TRUE if successful, otherwise FALSE + ***************************************************************************/ +int write_private_profile_string(char *section, + char *entry, char *buffer, char *file_name) + +{ + char * content = read_file(file_name); + FILE * fd = fopen(file_name,"w"); + char t_section[MAX_LINE_LENGTH], *ptr; + int ret = 0; + + if (!fd) goto end; + if (!content) { + fprintf (fd, "[%s]\n%s = %s\n", section, entry, buffer); + ret = 1; + goto end; + } + sprintf(t_section,"[%s]",section); /* Format the section name */ + ptr = str_search (content, t_section, 0); /* look for the section start */ + if (!ptr) { + /* no such section: add the new section at end of file */ + fprintf (fd, "%s\n[%s]\n%s = %s\n", content, section, entry, buffer); + } + else { + char * eptr; + eptr = str_search (ptr, entry, '['); + if (!eptr) { + /* no such entry: looks for next section */ + eptr = str_search (++ptr, "[", 0); + if (!eptr) { + /* section is the last one */ + fprintf (fd, "%s\n%s = %s\n", content, entry, buffer); + } + else { + while (*ptr && (*ptr != '\n')) ptr++; + *ptr = 0; + fprintf (fd, "%s\n%s = %s", content, entry, buffer); + *ptr = '\n'; + fprintf (fd, "%s", ptr); + } + } + else { + *eptr++ = 0; + fprintf (fd, "%s%s = %s", content, entry, buffer); + while (*eptr && (*eptr != '\n')) eptr++; + if (eptr) fprintf (fd, "%s", eptr); + } + } + ret = 1; + +end: + if (content) free(content); + if (fd) fclose(fd); + return 0; +} + +/*************************************************************************** + * Function: write_private_profile_int() + * Arguments: section - the name of the section to search for + * entry - the name of the entry to find the value of + * buffer - the value to be written + * file_name - the name of the .ini file to read from + * Returns: TRUE if successful, otherwise FALSE + ***************************************************************************/ +int write_private_profile_int(char *section, + char *entry, int val, char *file_name) +{ + char buffer [64]; + sprintf(buffer, "%d", val); + return write_private_profile_string (section,entry, buffer, file_name); +} + +#endif // #ifndef WIN32 + + +/************************************************************************** +* Function: get_private_profile_float() +* Arguments: section - the name of the section to search for +* entry - the name of the entry to find the value of +* def - the default value in the event of a failed read +* file_name - the name of the .ini file to read from +* Returns: the value located at entry +* Warning: The float value to be read must not contain more than 100 digits. +* Author: CD, 15/11/2006. +***************************************************************************/ +#define maxFloatLen 100 +float get_private_profile_float (char * section, char * entry, float def, char * file_name) +{ + float result = def; + char buffer[ maxFloatLen ], *endptr; + + if ( get_private_profile_string(section, entry, "", buffer, maxFloatLen, file_name) > 0 ) + { + result = (float)strtod(buffer, &endptr); + if ((result==0) && (endptr==buffer)) + result = def; + } + return result; +} diff --git a/windows/JackRouter/profport.h b/windows/JackRouter/profport.h new file mode 100644 index 00000000..2f717177 --- /dev/null +++ b/windows/JackRouter/profport.h @@ -0,0 +1,37 @@ + +/****************************************************************************** + PORTABLE ROUTINES FOR WRITING PRIVATE PROFILE STRINGS -- by Joseph J. Graf + Header file containing prototypes and compile-time configuration. + + [09/05/02] D. Fober - Windows definitions added +******************************************************************************/ + +#ifndef __profport__ +#define __profport__ + +#define MAX_LINE_LENGTH 1024 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WIN32 +#include "Windows.h" +#define get_private_profile_int GetPrivateProfileInt +#define get_private_profile_string GetPrivateProfileString +#define write_private_profile_string WritePrivateProfileString +#define write_private_profile_int WritePrivateProfileInt +#else +int get_private_profile_int (char * section, char * entry, int def, char * file_name); +int get_private_profile_string (char * section, char * entry, char * def, char * buffer, int buffer_len, char * file_name); +int write_private_profile_string (char * section, char * entry, char * buffer, char * file_name); +int write_private_profile_int (char * section, char * entry, int val, char * file_name); +#endif + +float get_private_profile_float (char * section, char * entry, float def, char * file_name); + +#ifdef __cplusplus +} +#endif + +#endif //__profport__ diff --git a/windows/JackRouter/psapi.dll b/windows/JackRouter/psapi.dll new file mode 100644 index 00000000..ff4c964c Binary files /dev/null and b/windows/JackRouter/psapi.dll differ diff --git a/windows/JackRouter/psapi.h b/windows/JackRouter/psapi.h new file mode 100644 index 00000000..af72931e --- /dev/null +++ b/windows/JackRouter/psapi.h @@ -0,0 +1,95 @@ +/* + psapi.h - Include file for PSAPI.DLL APIs + + Written by Mumit Khan + + This file is part of a free library for the Win32 API. + + NOTE: This strictly does not belong in the Win32 API since it's + really part of Platform SDK. However,GDB needs it and we might + as well provide it here. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +*/ +#ifndef _PSAPI_H +#define _PSAPI_H +#if __GNUC__ >=3 +#pragma GCC system_header +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef RC_INVOKED + +typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; +} MODULEINFO,*LPMODULEINFO; + +typedef struct _PSAPI_WS_WATCH_INFORMATION { + LPVOID FaultingPc; + LPVOID FaultingVa; +} PSAPI_WS_WATCH_INFORMATION,*PPSAPI_WS_WATCH_INFORMATION; + +typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + DWORD PeakWorkingSetSize; + DWORD WorkingSetSize; + DWORD QuotaPeakPagedPoolUsage; + DWORD QuotaPagedPoolUsage; + DWORD QuotaPeakNonPagedPoolUsage; + DWORD QuotaNonPagedPoolUsage; + DWORD PagefileUsage; + DWORD PeakPagefileUsage; +} PROCESS_MEMORY_COUNTERS,*PPROCESS_MEMORY_COUNTERS; + +/* Grouped by application,not in alphabetical order. */ +BOOL WINAPI EnumProcesses(DWORD *,DWORD,DWORD *); +BOOL WINAPI EnumProcessModules(HANDLE,HMODULE *,DWORD,LPDWORD); +DWORD WINAPI GetModuleBaseNameA(HANDLE,HMODULE,LPSTR,DWORD); +DWORD WINAPI GetModuleBaseNameW(HANDLE,HMODULE,LPWSTR,DWORD); +DWORD WINAPI GetModuleFileNameExA(HANDLE,HMODULE,LPSTR,DWORD); +DWORD WINAPI GetModuleFileNameExW(HANDLE,HMODULE,LPWSTR,DWORD); +BOOL WINAPI GetModuleInformation(HANDLE,HMODULE,LPMODULEINFO,DWORD); +BOOL WINAPI EmptyWorkingSet(HANDLE); +BOOL WINAPI QueryWorkingSet(HANDLE,PVOID,DWORD); +BOOL WINAPI InitializeProcessForWsWatch(HANDLE); +BOOL WINAPI GetWsChanges(HANDLE,PPSAPI_WS_WATCH_INFORMATION,DWORD); +DWORD WINAPI GetMappedFileNameW(HANDLE,LPVOID,LPWSTR,DWORD); +DWORD WINAPI GetMappedFileNameA(HANDLE,LPVOID,LPSTR,DWORD); +BOOL WINAPI EnumDeviceDrivers(LPVOID *,DWORD,LPDWORD); +DWORD WINAPI GetDeviceDriverBaseNameA(LPVOID,LPSTR,DWORD); +DWORD WINAPI GetDeviceDriverBaseNameW(LPVOID,LPWSTR,DWORD); +DWORD WINAPI GetDeviceDriverFileNameA(LPVOID,LPSTR,DWORD); +DWORD WINAPI GetDeviceDriverFileNameW(LPVOID,LPWSTR,DWORD); +BOOL WINAPI GetProcessMemoryInfo(HANDLE,PPROCESS_MEMORY_COUNTERS,DWORD); + +#endif /* not RC_INVOKED */ + +#ifdef UNICODE +#define GetModuleBaseName GetModuleBaseNameW +#define GetModuleFileNameEx GetModuleFileNameExW +#define GetMappedFilenameEx GetMappedFilenameExW +#define GetDeviceDriverBaseName GetDeviceDriverBaseNameW +#define GetDeviceDriverFileName GetDeviceDriverFileNameW +#else +#define GetModuleBaseName GetModuleBaseNameA +#define GetModuleFileNameEx GetModuleFileNameExA +#define GetMappedFilenameEx GetMappedFilenameExA +#define GetDeviceDriverBaseName GetDeviceDriverBaseNameA +#define GetDeviceDriverFileName GetDeviceDriverFileNameA +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _PSAPI_H */ + diff --git a/windows/JackRouter/resource.h b/windows/JackRouter/resource.h new file mode 100644 index 00000000..673206e6 --- /dev/null +++ b/windows/JackRouter/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/windows/JackRouter/resource.rc b/windows/JackRouter/resource.rc new file mode 100644 index 00000000..4289ddc2 --- /dev/null +++ b/windows/JackRouter/resource.rc @@ -0,0 +1,109 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// French (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,2,0,0 + PRODUCTVERSION 0,2,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "JackRouter ASIO driver\0" + VALUE "FileVersion", "0, 2, 0, 0\0" + VALUE "InternalName", "JackRouter\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "JackRouter.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "JackRouter\0" + VALUE "ProductVersion", "0, 2, 0, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x40c, 1200 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // French (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/windows/JackWinNamedPipeServerChannel.cpp b/windows/JackWinNamedPipeServerChannel.cpp index da0da443..3e6daa9c 100644 --- a/windows/JackWinNamedPipeServerChannel.cpp +++ b/windows/JackWinNamedPipeServerChannel.cpp @@ -24,6 +24,8 @@ Copyright (C) 2004-2006 Grame #include "JackLockedEngine.h" #include "JackGlobals.h" #include "JackClient.h" +#include "JackNotification.h" +#include "JackException.h" #include using namespace std; @@ -57,7 +59,7 @@ int JackClientPipeThread::Open(JackServer* server) // Open the Server/Client con jack_error("Cannot start Jack server listener\n"); return -1; } - + fServer = server; return 0; } @@ -71,15 +73,20 @@ void JackClientPipeThread::Close() // Close the Server/Client connection all ressources will be desallocated at the end. */ - fThread.Kill(); + fThread.Stop(); fPipe->Close(); fRefNum = -1; } - + bool JackClientPipeThread::Execute() { - jack_log("JackClientPipeThread::Execute"); - return(HandleRequest()); + try{ + jack_log("JackClientPipeThread::Execute"); + return (HandleRequest()); + } catch (JackQuitException& e) { + jack_log("JackMachServerChannel::Execute JackQuitException"); + return false; + } } bool JackClientPipeThread::HandleRequest() @@ -307,8 +314,14 @@ bool JackClientPipeThread::HandleRequest() case JackRequest::kNotification: { jack_log("JackRequest::Notification"); JackClientNotificationRequest req; - if (req.Read(fPipe) == 0) - fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + if (req.Read(fPipe) == 0) { + if (req.fNotify == kQUIT) { + jack_log("JackRequest::Notification kQUIT"); + throw JackQuitException(); + } else { + fServer->Notify(req.fRefNum, req.fNotify, req.fValue); + } + } break; } @@ -317,7 +330,7 @@ bool JackClientPipeThread::HandleRequest() break; } } - + // Unlock the global mutex ReleaseMutex(fMutex); return ret; @@ -373,17 +386,17 @@ int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* ser { jack_log("JackWinNamedPipeServerChannel::Open "); snprintf(fServerName, sizeof(fServerName), server_name); - + // Needed for internal connection from JackWinNamedPipeServerNotifyChannel object if (fRequestListenPipe.Bind(jack_server_dir, server_name, 0) < 0) { jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe"); return -1; } - + fServer = server; return 0; } - + void JackWinNamedPipeServerChannel::Close() { /* TODO : solve WIN32 thread Kill issue @@ -403,11 +416,11 @@ int JackWinNamedPipeServerChannel::Start() if (fThread.Start() != 0) { jack_error("Cannot start Jack server listener"); return -1; - } - + } + return 0; -} - +} + bool JackWinNamedPipeServerChannel::Init() { jack_log("JackWinNamedPipeServerChannel::Init "); diff --git a/windows/JackWinNamedPipeServerNotifyChannel.cpp b/windows/JackWinNamedPipeServerNotifyChannel.cpp index 1e3c4e21..8036d81f 100644 --- a/windows/JackWinNamedPipeServerNotifyChannel.cpp +++ b/windows/JackWinNamedPipeServerNotifyChannel.cpp @@ -21,6 +21,7 @@ This program is free software; you can redistribute it and/or modify #include "JackError.h" #include "JackRequest.h" #include "JackConstants.h" +#include "JackNotification.h" namespace Jack { @@ -54,6 +55,14 @@ void JackWinNamedPipeServerNotifyChannel::Notify(int refnum, int notify, int val } } +void JackWinNamedPipeServerNotifyChannel::NotifyQuit() +{ + JackClientNotificationRequest req(-1, kQUIT, 0); + if (req.Write(&fRequestPipe) < 0) { + jack_error("Could not write request ref = %d notify = %d", -1, kQUIT); + } +} + } // end of namespace diff --git a/windows/JackWinNamedPipeServerNotifyChannel.h b/windows/JackWinNamedPipeServerNotifyChannel.h index aa1a6c91..be4d7ff2 100644 --- a/windows/JackWinNamedPipeServerNotifyChannel.h +++ b/windows/JackWinNamedPipeServerNotifyChannel.h @@ -45,6 +45,7 @@ class JackWinNamedPipeServerNotifyChannel void Close(); void Notify(int refnum, int notify, int value); + void NotifyQuit(); }; } // end of namespace diff --git a/windows/Setup/JackRouter.dll b/windows/Setup/JackRouter.dll index 226ea667..f06fe1b6 100644 Binary files a/windows/Setup/JackRouter.dll and b/windows/Setup/JackRouter.dll differ diff --git a/windows/Setup/jack.ci b/windows/Setup/jack.ci index 2c3eb9a0..25233392 100644 --- a/windows/Setup/jack.ci +++ b/windows/Setup/jack.ci @@ -1,9 +1,9 @@ <*project version = 4 civer = "Free v4.14.5" winver = "2.6/5.1.2600" > . - Jack_v1.9.4_setup.exe + Jack_v1.9.5_setup.exe - Jack v1.9.4 + Jack v1.9.5 Default - 2 @@ -72,6 +72,8 @@ <_>..\Release\bin\libsamplerate-0.dllinstovernewer0 <_>..\Release\bin\portaudio_x86.dllinstovernewer0 <_>..\Release\bin\jack\jack_net.dllinstjackovernewer0 +<_>..\Release\bin\jack\jack_netone.dllinstjackovernewer0 +<_>..\Release\bin\jack_netsource.exeinstovernewer0 <_>..\Release\bin\jack\jack_dummy.dllinstjackovernewer0 <_>..\Release\bin\jack\jack_loopback.dllinstjackovernewer0 <_>..\Release\bin\jack\jack_winmme.dllinstjackovernewer0 diff --git a/windows/jack_disconnect.cbp b/windows/jack_disconnect.cbp index cbb02515..994f2127 100644 --- a/windows/jack_disconnect.cbp +++ b/windows/jack_disconnect.cbp @@ -37,7 +37,7 @@ - + diff --git a/windows/jack_netonedriver.cbp b/windows/jack_netonedriver.cbp new file mode 100644 index 00000000..0aa97036 --- /dev/null +++ b/windows/jack_netonedriver.cbp @@ -0,0 +1,107 @@ + + + + + + diff --git a/windows/jack_netsource.cbp b/windows/jack_netsource.cbp new file mode 100644 index 00000000..ddfe02e8 --- /dev/null +++ b/windows/jack_netsource.cbp @@ -0,0 +1,110 @@ + + + + + + diff --git a/windows/jackaudioadapter.rc b/windows/jackaudioadapter.rc index 02d66940..25d4b155 100644 --- a/windows/jackaudioadapter.rc +++ b/windows/jackaudioadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Audio Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "audioadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "audioadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "audioadapter\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.rc b/windows/jackd.rc index 5f909413..db62e72c 100644 --- a/windows/jackd.rc +++ b/windows/jackd.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_APP BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jackd\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jackd.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jackd\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 7e09eb88..9be9ce63 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -11,6 +11,9 @@ + + + @@ -33,6 +36,10 @@ + + + + diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index 62a7a3c0..7488ea91 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "netadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netadapter\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetdriver.rc b/windows/jacknetdriver.rc index 8a7a1806..a98f2fc4 100644 --- a/windows/jacknetdriver.rc +++ b/windows/jacknetdriver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Driver for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jack_netdriver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_netdriver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_netdriver\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetmanager.rc b/windows/jacknetmanager.rc index ffc1dde8..c440861f 100644 --- a/windows/jacknetmanager.rc +++ b/windows/jacknetmanager.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Manager for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "netmanager\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "netmanager.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "netmanager\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jacknetonedriver.rc b/windows/jacknetonedriver.rc new file mode 100644 index 00000000..9c184d36 --- /dev/null +++ b/windows/jacknetonedriver.rc @@ -0,0 +1,41 @@ +// Generated by ResEdit 1.4.3 +// Copyright (C) 2006-2008 +// http://www.resedit.net + +#include "resource.h" +#include "afxres.h" + + +// +// Version Information resources +// +LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +1 VERSIONINFO + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 + FILEOS VOS_UNKNOWN + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "Grame\0" + VALUE "FileDescription", "Jackmp NetOne Driver for Windows\0" + VALUE "FileVersion", "1, 9, 5, 0\0" + VALUE "InternalName", "jack_netonedriver\0" + VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "jack_netonedriver.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "jack_netonedriver\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1036, 1200 + END +END diff --git a/windows/jackportaudio.rc b/windows/jackportaudio.rc index 7e8429a0..2c4e66da 100644 --- a/windows/jackportaudio.rc +++ b/windows/jackportaudio.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp PortAudio Driver for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_portaudio.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_portaudio\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/jackwinmme.rc b/windows/jackwinmme.rc index 5a38e821..6d8e19f3 100644 --- a/windows/jackwinmme.rc +++ b/windows/jackwinmme.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp WinMMEo Driver for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "jack_portaudio\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "jack_winmme.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "jack_winmme\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjack.rc b/windows/libjack.rc index b4e79369..7beda3d8 100644 --- a/windows/libjack.rc +++ b/windows/libjack.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack client library for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "libjack\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjack.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjack\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index 8a82c34b..b0b76f1f 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -156,6 +156,8 @@ + + diff --git a/windows/libjackserver.rc b/windows/libjackserver.rc index dc0bbb6b..b62a275e 100644 --- a/windows/libjackserver.rc +++ b/windows/libjackserver.rc @@ -11,8 +11,8 @@ // LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT 1 VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEOS VOS_UNKNOWN FILETYPE VFT_DLL BEGIN @@ -23,14 +23,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jack server library for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "libjackserver\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackserver.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackserver\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/windows/resource.rc b/windows/resource.rc index 51ba4994..e5d5f15c 100644 --- a/windows/resource.rc +++ b/windows/resource.rc @@ -14,8 +14,8 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH #ifndef _MAC VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,4,0 - PRODUCTVERSION 1,9,4,0 + FILEVERSION 1,9,5,0 + PRODUCTVERSION 1,9,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -33,14 +33,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp for Windows\0" - VALUE "FileVersion", "1, 9, 4, 0\0" + VALUE "FileVersion", "1, 9, 5, 0\0" VALUE "InternalName", "libjackmp\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2009\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libjackmp.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "libjackmp\0" - VALUE "ProductVersion", "1, 9, 4, 0\0" + VALUE "ProductVersion", "1, 9, 5, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/wscript b/wscript index a9128cca..33469397 100644 --- a/wscript +++ b/wscript @@ -68,8 +68,8 @@ def set_options(opt): opt.add_option('--profile', action='store_true', default=False, help='Build with engine profiling') opt.add_option('--mixed', action='store_true', default=False, help='Build with 32/64 bits mixed mode') opt.add_option('--clients', default=64, type="int", dest="clients", help='Maximum number of JACK clients') - opt.add_option('--ports', default=2048, type="int", dest="ports", help='Maximum number of ports') - opt.add_option('--ports-per-application', default=512, type="int", dest="application_ports", help='Maximum number of ports per application') + opt.add_option('--ports-per-application', default=768, type="int", dest="application_ports", help='Maximum number of ports per application') + opt.add_option('--debug', action='store_true', default=False, dest='debug', help="Build debuggable binaries") opt.sub_options('dbus') def configure(conf): @@ -112,6 +112,8 @@ def configure(conf): conf.sub_config('linux') if Options.options.dbus: conf.sub_config('dbus') + if conf.env['BUILD_JACKDBUS'] != True: + conf.fatal('jackdbus was explicitly requested but cannot be built') conf.sub_config('example-clients') if conf.check_cfg(package='celt', atleast_version='0.7.0', args='--cflags --libs'): @@ -136,8 +138,8 @@ def configure(conf): conf.env['BUILD_DOXYGEN_DOCS'] = Options.options.doxygen conf.env['BUILD_WITH_PROFILE'] = Options.options.profile conf.env['BUILD_WITH_32_64'] = Options.options.mixed - conf.env['BUILD_JACKDBUS'] = Options.options.dbus conf.env['BUILD_CLASSIC'] = Options.options.classic + conf.env['BUILD_DEBUG'] = Options.options.debug if conf.env['BUILD_JACKDBUS']: conf.env['BUILD_JACKD'] = conf.env['BUILD_CLASSIC'] @@ -149,8 +151,12 @@ def configure(conf): else: conf.env['LIBDIR'] = conf.env['PREFIX'] + '/lib' + if conf.env['BUILD_DEBUG']: + conf.env.append_unique('CXXFLAGS', '-g') + conf.env.append_unique('CCFLAGS', '-g') + conf.env.append_unique('LINKFLAGS', '-g') + conf.define('CLIENT_NUM', Options.options.clients) - conf.define('PORT_NUM', Options.options.ports) conf.define('PORT_NUM_FOR_CLIENT', Options.options.application_ports) conf.define('ADDON_DIR', os.path.normpath(os.path.join(conf.env['LIBDIR'], 'jack'))) @@ -184,12 +190,12 @@ def configure(conf): print version_msg print "Build with a maximum of %d JACK clients" % conf.env['CLIENT_NUM'] - print "Build with a maximum of %d ports" % conf.env['PORT_NUM'] print "Build with a maximum of %d ports per application" % conf.env['PORT_NUM_FOR_CLIENT'] display_msg("Install prefix", conf.env['PREFIX'], 'CYAN') display_msg("Library directory", conf.env['LIBDIR'], 'CYAN') display_msg("Drivers directory", conf.env['ADDON_DIR'], 'CYAN') + display_feature('Build debuggable binaries', conf.env['BUILD_DEBUG']) display_feature('Build doxygen documentation', conf.env['BUILD_DOXYGEN_DOCS']) display_feature('Build with engine profiling', conf.env['BUILD_WITH_PROFILE']) display_feature('Build with 32/64 bits mixed mode', conf.env['BUILD_WITH_32_64']) @@ -198,8 +204,9 @@ def configure(conf): display_feature('Build D-Bus JACK (jackdbus)', conf.env['BUILD_JACKDBUS']) if conf.env['BUILD_JACKDBUS'] and conf.env['BUILD_JACKD']: - print Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues!' + Logs.colors.NORMAL - + print Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues:' + Logs.colors.NORMAL + print Logs.colors.RED + 'WARNING !! jackdbus does not use .jackdrc nor qjackctl settings' + Logs.colors.NORMAL + if conf.env['IS_LINUX']: display_feature('Build with ALSA support', conf.env['BUILD_DRIVER_ALSA'] == True) display_feature('Build with FireWire (FreeBob) support', conf.env['BUILD_DRIVER_FREEBOB'] == True)