git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3900 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
@@ -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 <gabriel@teuton.org> | |||
* Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF. | |||
2009-12-15 Stephane Letz <letz@grame.fr> | |||
* Shared memory manager was calling abort in case of fatal error, now return an error in caller. | |||
2009-12-13 Stephane Letz <letz@grame.fr> | |||
* Mario Lang alsa_io time calculation overflow patch. | |||
2009-12-10 Stephane Letz <letz@grame.fr> | |||
* 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 <letz@grame.fr> | |||
* When threads are cancelled, the exception has to be rethrown. | |||
2009-12-08 Stephane Letz <letz@grame.fr> | |||
* Josh Green ALSA driver capture only patch. | |||
2009-12-03 Stephane Letz <letz@grame.fr> | |||
* Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). | |||
2009-12-02 Stephane Letz <letz@grame.fr> | |||
* 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 <letz@grame.fr> | |||
* Fix port_rename callback : now both old name and new name are given as parameters. | |||
2009-11-30 Stephane Letz <letz@grame.fr> | |||
* Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). | |||
2009-11-29 Stephane Letz <letz@grame.fr> | |||
* More robust sample rate change handling code in JackCoreAudioDriver. | |||
2009-11-24 Stephane Letz <letz@grame.fr> | |||
* Dynamic choice of maximum port number. | |||
2009-11-23 Stephane Letz <letz@grame.fr> | |||
* Peter L Jones patch for NetJack1 compilation on Windows. | |||
2009-11-20 Stephane Letz <letz@grame.fr> | |||
* Version 1.9.5 started. | |||
* Client debugging code improved. | |||
2009-11-18 Stephane Letz <letz@grame.fr> | |||
* Sync JackCoreAudioAdapter code with JackCoreAudioDriver. | |||
@@ -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) { | |||
@@ -17,10 +17,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#include "JackAudioAdapter.h" | |||
#ifdef __APPLE__ | |||
#include <TargetConditionals.h> | |||
#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); | |||
} | |||
@@ -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; | |||
} | |||
} | |||
@@ -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(); | |||
} | |||
@@ -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<CONNECTION_NUM_FOR_PORT> fConnection[PORT_NUM]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */ | |||
JackFixedArray<CONNECTION_NUM_FOR_PORT> fConnection[PORT_NUM_MAX]; /*! Connection matrix: list of connected ports for a given port: needed to compute Mix buffer */ | |||
JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */ | |||
JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */ | |||
JackFixedMatrix<CLIENT_NUM> fConnectionRef; /*! Table of port connections by (refnum , refnum) */ | |||
@@ -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 | |||
@@ -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); | |||
@@ -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 <iostream> | |||
@@ -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); | |||
} | |||
@@ -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); | |||
}; | |||
@@ -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; | |||
@@ -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; | |||
} | |||
@@ -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(); | |||
}; | |||
@@ -25,6 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#include "JackGlobals.h" | |||
#include "JackTime.h" | |||
#include <iostream> | |||
#include <fstream> | |||
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 << "<?xml version='1.0' encoding='utf-8'?>\n"; | |||
fStream6 << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"; | |||
fStream6 << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; | |||
fStream6 << "<html xmlns='http://www.w3.org/1999/xhtml' lang='en'>\n"; | |||
fStream6 << " <head>\n"; | |||
fStream6 << " <title>JACK engine profiling</title>\n"; | |||
fStream6 << " <!-- assuming that images are 600px wide -->\n"; | |||
fStream6 << " <style media='all' type='text/css'>\n"; | |||
fStream6 << " .center { margin-left:auto ; margin-right: auto; width: 650px; height: 550px }\n"; | |||
fStream6 << " </style>\n"; | |||
fStream6 << " </head>\n"; | |||
fStream6 << " <body>\n"; | |||
fStream6 << " <h2 style='text-align:center'>JACK engine profiling</h2>\n"; | |||
fStream6 << " <div class='center'><object class='center' type='image/svg+xml' data='Timing1.svg'>Timing1</object></div>"; | |||
fStream6 << " <div class='center'><object class='center' type='image/svg+xml' data='Timing2.svg'>Timing2</object></div>"; | |||
fStream6 << " <div class='center'><object class='center' type='image/svg+xml' data='Timing3.svg'>Timing3</object></div>"; | |||
fStream6 << " <div class='center'><object class='center' type='image/svg+xml' data='Timing4.svg'>Timing4</object></div>"; | |||
fStream6 << " <div class='center'><object class='center' type='image/svg+xml' data='Timing5.svg'>Timing5</object></div>"; | |||
fStream6 << " </body>\n"; | |||
fStream6 << "</html>\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) | |||
@@ -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. | |||
*/ | |||
@@ -20,13 +20,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#ifndef __JackFilters__ | |||
#define __JackFilters__ | |||
#ifdef __APPLE__ | |||
#include <TargetConditionals.h> | |||
#endif | |||
#include "jack.h" | |||
#ifndef TARGET_OS_IPHONE | |||
#include "JackAtomicState.h" | |||
#endif | |||
#include <math.h> | |||
#include <stdlib.h> | |||
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 | |||
*/ | |||
@@ -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 |
@@ -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 <iostream> | |||
#include <fstream> | |||
#include <string> | |||
#include <time.h> | |||
#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. | |||
@@ -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) | |||
@@ -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; | |||
@@ -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; | |||
@@ -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); | |||
@@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#include "JackError.h" | |||
#include <assert.h> | |||
#include <signal.h> | |||
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 | |||
@@ -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 | |||
@@ -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(); | |||
} | |||
}; | |||
@@ -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; | |||
}; | |||
@@ -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 |
@@ -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 ) | |||
@@ -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 <malloc.h> | |||
#endif | |||
@@ -44,6 +44,7 @@ enum NotificationType { | |||
kPortRenameCallback = 13, | |||
kRealTimeCallback = 14, | |||
kShutDownCallback = 15, | |||
kQUIT = 16, | |||
kMaxNotification | |||
}; | |||
@@ -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 <cassert> | |||
#include <cstring> | |||
#include <new> | |||
#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); | |||
} | |||
} | |||
} |
@@ -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 |
@@ -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 <cassert> | |||
#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; | |||
} | |||
} |
@@ -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 |
@@ -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'; | |||
@@ -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(); | |||
@@ -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); | |||
@@ -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; | |||
@@ -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(); | |||
@@ -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(); | |||
@@ -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; | |||
} | |||
@@ -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 | |||
* <jack/weakjack.h> before jack.h. | |||
*************************************************************/ | |||
#include <jack/weakmacros.h> | |||
/** | |||
* 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 | |||
@@ -27,7 +27,7 @@ extern "C" { | |||
#include <jack/types.h> | |||
#include <stdlib.h> | |||
#include <jack/weakmacros.h> | |||
/** 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; | |||
/*@}*/ | |||
@@ -26,6 +26,7 @@ extern "C" | |||
#endif | |||
#include <jack/systemdeps.h> | |||
#include <jack/weakmacros.h> | |||
/** @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 | |||
@@ -26,6 +26,7 @@ extern "C" { | |||
#endif | |||
#include <jack/types.h> | |||
#include <jack/weakmacros.h> | |||
/** | |||
* @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; | |||
/*@}*/ | |||
@@ -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 | |||
@@ -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 */ |
@@ -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 | |||
* <jack/weakjack.h> 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__ */ |
@@ -42,6 +42,7 @@ $Id: net_driver.c,v 1.17 2006/04/16 20:16:10 torbenh Exp $ | |||
#ifdef WIN32 | |||
#include <winsock.h> | |||
#include <malloc.h> | |||
#define socklen_t int | |||
#else | |||
#include <sys/socket.h> | |||
#include <netinet/in.h> | |||
@@ -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 <samplerate.h> | |||
@@ -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 { | |||
@@ -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 <winsock2.h> | |||
#define socklen_t int | |||
#include <malloc.h> | |||
#define socklen_t int | |||
#else | |||
#include <sys/socket.h> | |||
#include <netinet/in.h> | |||
@@ -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); | |||
@@ -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; | |||
} | |||
} | |||
} | |||
@@ -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 <process.h> | |||
#include <process.h> | |||
#include <stdio.h> | |||
#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 ())) { | |||
@@ -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 | |||
@@ -130,7 +130,8 @@ def build(bld): | |||
'JackNetTool.cpp', | |||
'JackNetInterface.cpp', | |||
'JackArgParser.cpp', | |||
'JackDummyDriver.cpp', | |||
'JackPhysicalMidiInput.cpp', | |||
'JackPhysicalMidiOutput.cpp', | |||
] | |||
if bld.env['IS_LINUX']: | |||
@@ -283,8 +283,11 @@ jack_control_run_method( | |||
return true; | |||
not_started: | |||
jack_dbus_error (call, JACK_DBUS_ERROR_SERVER_NOT_RUNNING, | |||
"Can't execute method '%s' with stopped JACK server", call->method_name); | |||
jack_dbus_only_error( | |||
call, | |||
JACK_DBUS_ERROR_SERVER_NOT_RUNNING, | |||
"Can't execute method '%s' with stopped JACK server", | |||
call->method_name); | |||
exit: | |||
return true; | |||
@@ -281,6 +281,35 @@ jack_controller_patchbay_send_signal_ports_disconnected( | |||
DBUS_TYPE_INVALID); | |||
} | |||
void | |||
jack_controller_patchbay_send_signal_port_renamed( | |||
dbus_uint64_t new_graph_version, | |||
dbus_uint64_t client_id, | |||
const char * client_name, | |||
dbus_uint64_t port_id, | |||
const char * port_old_name, | |||
const char * port_new_name) | |||
{ | |||
jack_dbus_send_signal( | |||
JACK_CONTROLLER_OBJECT_PATH, | |||
JACK_DBUS_IFACE_NAME, | |||
"PortRenamed", | |||
DBUS_TYPE_UINT64, | |||
&new_graph_version, | |||
DBUS_TYPE_UINT64, | |||
&client_id, | |||
DBUS_TYPE_STRING, | |||
&client_name, | |||
DBUS_TYPE_UINT64, | |||
&port_id, | |||
DBUS_TYPE_STRING, | |||
&port_old_name, | |||
DBUS_TYPE_STRING, | |||
&port_new_name, | |||
DBUS_TYPE_INVALID); | |||
} | |||
static | |||
struct jack_graph_client * | |||
jack_controller_patchbay_find_client( | |||
@@ -1618,6 +1647,65 @@ jack_controller_port_connect_callback( | |||
} | |||
} | |||
int jack_controller_port_rename_callback(jack_port_id_t port, const char * old_name, const char * new_name, void * context) | |||
{ | |||
struct jack_graph_port * port_ptr; | |||
const char * port_new_short_name; | |||
const char * port_old_short_name; | |||
char * name_buffer; | |||
jack_info("port renamed: '%s' -> '%s'", old_name, new_name); | |||
port_new_short_name = strchr(new_name, ':'); | |||
if (port_new_short_name == NULL) | |||
{ | |||
jack_error("renamed port new name '%s' does not contain ':' separator char", new_name); | |||
return -1; | |||
} | |||
port_new_short_name++; /* skip ':' separator char */ | |||
port_old_short_name = strchr(old_name, ':'); | |||
if (port_old_short_name == NULL) | |||
{ | |||
jack_error("renamed port old name '%s' does not contain ':' separator char", old_name); | |||
return -1; | |||
} | |||
port_old_short_name++; /* skip ':' separator char */ | |||
port_ptr = jack_controller_patchbay_find_port_by_full_name(patchbay_ptr, old_name); | |||
if (port_ptr == NULL) | |||
{ | |||
jack_error("renamed port '%s' not found", old_name); | |||
return -1; | |||
} | |||
name_buffer = strdup(port_new_short_name); | |||
if (name_buffer == NULL) | |||
{ | |||
jack_error("strdup() call for port name '%s' failed.", port_new_short_name); | |||
return 1; | |||
} | |||
free(port_ptr->name); | |||
port_ptr->name = name_buffer; | |||
pthread_mutex_lock(&patchbay_ptr->lock); | |||
patchbay_ptr->graph.version++; | |||
jack_controller_patchbay_send_signal_port_renamed( | |||
patchbay_ptr->graph.version, | |||
port_ptr->client->id, | |||
port_ptr->client->name, | |||
port_ptr->id, | |||
port_old_short_name, | |||
port_ptr->name); | |||
jack_controller_patchbay_send_signal_graph_changed(patchbay_ptr->graph.version); | |||
pthread_mutex_unlock(&patchbay_ptr->lock); | |||
return 0; | |||
} | |||
#undef controller_ptr | |||
void | |||
@@ -1714,6 +1802,13 @@ jack_controller_patchbay_init( | |||
goto fail_uninit_mutex; | |||
} | |||
ret = jack_set_port_rename_callback(controller_ptr->client, jack_controller_port_rename_callback, controller_ptr); | |||
if (ret != 0) | |||
{ | |||
jack_error("jack_set_port_rename_callback() failed with error %d", ret); | |||
goto fail_uninit_mutex; | |||
} | |||
return true; | |||
fail_uninit_mutex: | |||
@@ -1838,6 +1933,15 @@ JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(PortsDisconnected) | |||
JACK_DBUS_SIGNAL_ARGUMENT("connection_id", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENTS_END | |||
JACK_DBUS_SIGNAL_ARGUMENTS_BEGIN(PortRenamed) | |||
JACK_DBUS_SIGNAL_ARGUMENT("new_graph_version", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("port_id", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("client_id", DBUS_TYPE_UINT64_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("client_name", DBUS_TYPE_STRING_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("port_old_name", DBUS_TYPE_STRING_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENT("port_new_name", DBUS_TYPE_STRING_AS_STRING) | |||
JACK_DBUS_SIGNAL_ARGUMENTS_END | |||
JACK_DBUS_SIGNALS_BEGIN | |||
JACK_DBUS_SIGNAL_DESCRIBE(GraphChanged) | |||
JACK_DBUS_SIGNAL_DESCRIBE(ClientAppeared) | |||
@@ -1846,6 +1950,7 @@ JACK_DBUS_SIGNALS_BEGIN | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortDisappeared) | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortsConnected) | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortsDisconnected) | |||
JACK_DBUS_SIGNAL_DESCRIBE(PortRenamed) | |||
JACK_DBUS_SIGNALS_END | |||
JACK_DBUS_IFACE_BEGIN(g_jack_controller_iface_patchbay, JACK_DBUS_IFACE_NAME) | |||
@@ -765,6 +765,34 @@ jack_dbus_error( | |||
va_end(ap); | |||
} | |||
void | |||
jack_dbus_only_error( | |||
void *dbus_call_context_ptr, | |||
const char *error_name, | |||
const char *format, | |||
...) | |||
{ | |||
va_list ap; | |||
char buffer[300]; | |||
va_start(ap, format); | |||
vsnprintf(buffer, sizeof(buffer), format, ap); | |||
if (((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply != NULL) | |||
{ | |||
dbus_message_unref(((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply); | |||
((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = NULL; | |||
} | |||
((struct jack_dbus_method_call *)dbus_call_context_ptr)->reply = dbus_message_new_error( | |||
((struct jack_dbus_method_call *)dbus_call_context_ptr)->message, | |||
error_name, | |||
buffer); | |||
va_end(ap); | |||
} | |||
int | |||
main (int argc, char **argv) | |||
{ | |||
@@ -257,6 +257,13 @@ jack_dbus_error( | |||
const char *format, | |||
...); | |||
void | |||
jack_dbus_only_error( | |||
void *dbus_call_context_ptr, | |||
const char *error_name, | |||
const char *format, | |||
...); | |||
bool | |||
jack_dbus_get_method_args( | |||
struct jack_dbus_method_call *call, | |||
@@ -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'] | |||
@@ -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. | |||
@@ -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)); | |||
@@ -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)); | |||
@@ -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" | |||
@@ -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 | |||
@@ -34,8 +34,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#include <string.h> | |||
#include <signal.h> | |||
#ifdef __linux__ | |||
#include "config.h" | |||
#endif | |||
#ifdef WIN32 | |||
#include <winsock2.h> | |||
#define socklen_t int | |||
#include <malloc.h> | |||
#else | |||
#include <netinet/in.h> | |||
@@ -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, | |||
@@ -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') | |||
@@ -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; | |||
} | |||
} | |||
} | |||
@@ -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 <string.h> | |||
#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); | |||
@@ -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 <cassert> | |||
#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; | |||
} | |||
} |
@@ -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 |
@@ -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 <cassert> | |||
#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; | |||
} | |||
} |
@@ -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 |
@@ -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 <types.h> | |||
#include <assert.h> | |||
#include <jack/midiport.h> | |||
#include "../alsa/midi_pack.h" | |||
#include "../alsa/midi_unpack.h" | |||
//#include <jack/midiport.h> | |||
// 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; | |||
@@ -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') | |||
@@ -7,7 +7,7 @@ | |||
<key>CFBundleExecutable</key> | |||
<string>Jackservermp</string> | |||
<key>CFBundleGetInfoString</key> | |||
<string>Jackdmp 1.9.4, @03-09 Paul Davis, Grame</string> | |||
<string>Jackdmp 1.9.5, @03-09 Paul Davis, Grame</string> | |||
<key>CFBundleIdentifier</key> | |||
<string>com.grame.Jackmp</string> | |||
<key>CFBundleInfoDictionaryVersion</key> | |||
@@ -19,6 +19,6 @@ | |||
<key>CFBundleSignature</key> | |||
<string>????</string> | |||
<key>CFBundleVersion</key> | |||
<string>1.9.4</string> | |||
<string>1.9.5</string> | |||
</dict> | |||
</plist> |
@@ -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 <assert.h> | |||
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; | |||
} | |||
} |
@@ -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" | |||
@@ -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 | |||
@@ -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 | |||
@@ -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 | |||
@@ -61,8 +61,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#ifndef __JackMachThread__ | |||
#define __JackMachThread__ | |||
#include <TargetConditionals.h> | |||
#ifdef TARGET_OS_IPHONE | |||
typedef unsigned char Boolean; | |||
#endif | |||
#include "JackPosixThread.h" | |||
#ifndef TARGET_OS_IPHONE | |||
#import <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h> | |||
#endif | |||
#include <mach/thread_policy.h> | |||
#include <mach/thread_act.h> | |||
@@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#ifndef __JackPlatformPlug_APPLE__ | |||
#define __JackPlatformPlug_APPLE__ | |||
#include <TargetConditionals.h> | |||
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" | |||
@@ -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 = "<group>"; }; | |||
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 = "<absolute>"; }; | |||
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 = "<group>"; | |||
@@ -2406,6 +2506,7 @@ | |||
4B32256110A3187800838A8E /* jack_netsource */, | |||
4B32257B10A3190C00838A8E /* jack_netsource */, | |||
4BA339AC10B2E36800190E3B /* Jackservermp.framework */, | |||
4B47ACD710B5890100469C67 /* Jackmp.framework */, | |||
); | |||
name = Products; | |||
sourceTree = "<group>"; | |||
@@ -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 = ( | |||
@@ -18,59 +18,105 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
*/ | |||
#include "JackAudioQueueAdapter.h" | |||
#include <CoreServices/CoreServices.h> | |||
//#include <CoreServices/CoreServices.h> | |||
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; | |||
} | |||
@@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
#ifndef __JackAudioQueueAdapter__ | |||
#define __JackAudioQueueAdapter__ | |||
#include <AudioToolbox/AudioConverter.h> | |||
#include <AudioToolbox/AudioQueue.h> | |||
//#include <AudioToolbox/AudioConverter.h> | |||
//#include <AudioToolbox/AudioQueue.h> | |||
#include <AudioToolbox/AudioToolbox.h> | |||
#include <jack/net.h> | |||
@@ -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); | |||
@@ -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; | |||
} | |||
} | |||
@@ -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); | |||
} | |||
} | |||
@@ -11,7 +11,7 @@ | |||
<key>CFBundleIconFile</key> | |||
<string></string> | |||
<key>CFBundleIdentifier</key> | |||
<string>com.yourcompany.${PRODUCT_NAME:identifier}</string> | |||
<string>fr.grame.iGrame.iPhoneFaustNet</string> | |||
<key>CFBundleInfoDictionaryVersion</key> | |||
<string>6.0</string> | |||
<key>CFBundleName</key> | |||
@@ -38,6 +38,8 @@ | |||
#include <list> | |||
#include <map> | |||
#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; | |||
} |
@@ -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 = "<absolute>"; }; | |||
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 = "<group>"; | |||
@@ -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 = ( | |||
@@ -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 <assert.h> | |||
#include <signal.h> | |||
@@ -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 | |||
@@ -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 | |||
@@ -44,6 +44,7 @@ class JackSocketServerNotifyChannel | |||
void Close(); | |||
void Notify(int refnum, int notify, int value); | |||
void NotifyQuit(); | |||
}; | |||
} // end of namespace | |||
@@ -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... | |||
@@ -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 <stdio.h> | |||
#include <string.h> | |||
#include <assert.h> | |||
#include <process.h> | |||
#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<pair<string, string> > 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 <windows.h> | |||
#include <stdio.h> | |||
#include <tchar.h> | |||
#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<pair<string, string> >::const_iterator it; | |||
for (it = fConnections.begin(); it != fConnections.end(); it++) { | |||
pair<string, string> 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); | |||
} | |||
} | |||
@@ -0,0 +1,9 @@ | |||
LIBRARY JackRouter | |||
DESCRIPTION 'ASIO Jack Driver' | |||
PROTMODE | |||
EXPORTS | |||
DllMain | |||
DllGetClassObject | |||
DllCanUnloadNow | |||
DllRegisterServer | |||
DllUnregisterServer |
@@ -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 |
@@ -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> | |||
{{{ | |||
}}} | |||
############################################################################### | |||
@@ -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 <windows.h> | |||
#include "ole2.h" | |||
#endif | |||
#include "combase.h" | |||
#include "iasiodrv.h" | |||
#define MAX_PORTS 32 | |||
#define LONG_SAMPLE 1 | |||
#define PATH_SEP "\\" | |||
#include <list> | |||
#include <string> | |||
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<std::pair<std::string, std::string> > 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 | |||