From a979d06e2f2bab0da81ec37dc977aa008fad02d2 Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 5 Mar 2009 15:17:15 +0000 Subject: [PATCH] Add auto_connect parameter in netmanager and netadapter. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3401 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 3 +- common/JackAudioAdapter.cpp | 42 ++++++++++++++++++++++ common/JackAudioAdapter.h | 7 ++-- common/JackNetAdapter.cpp | 49 ++++++++----------------- common/JackNetManager.cpp | 72 +++++++++++++++++++++++++++---------- common/JackNetManager.h | 10 +++--- windows/README | 12 ++++--- windows/Setup/src/README | 2 +- 8 files changed, 132 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5ca12b72..97c51e18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,7 +25,8 @@ Michael Voigt 2009-03-05 Stephane Letz - * Support for BIG_ENDIAN machines in NetJack2 for transport data. + * Support for BIG_ENDIAN machines in NetJack2 for transport data. + * Add auto_connect parameter in netmanager and netadapter. 2009-03-03 Stephane Letz diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index 06f7e0f1..6961a06f 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -69,6 +69,24 @@ namespace Jack } //JackAudioAdapter ********************************************************* + + JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system) + :fJackClient(jack_client), fAudioAdapter(audio_io) + { + const JSList* node; + const jack_driver_param_t* param; + fAutoConnect = false; + + for (node = params; node; node = jack_slist_next(node)) { + param = (const jack_driver_param_t*) node->data; + switch (param->character) { + case 'c': + fAutoConnect = param->value.i; + break; + } + } + } + JackAudioAdapter::~JackAudioAdapter() { // When called, Close has already been used for the client, thus ports are already unregistered. @@ -87,6 +105,27 @@ namespace Jack delete[] fCapturePortList; delete[] fPlaybackPortList; } + + void JackAudioAdapter::ConnectPorts() + { + const char **ports; + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + if (ports != NULL) { + for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { + jack_connect(fJackClient,jack_port_name(fCapturePortList[i]), ports[i]); + } + free(ports); + } + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); + if (ports != NULL) { + for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { + jack_connect(fJackClient, ports[i], jack_port_name(fPlaybackPortList[i])); + } + free(ports); + } + } void JackAudioAdapter::Reset() { @@ -126,6 +165,9 @@ namespace Jack goto fail; if ( jack_activate ( fJackClient ) < 0 ) goto fail; + + if (fAutoConnect) + ConnectPorts(); // Ring buffer are now allocated.. return fAudioAdapter->Open(); diff --git a/common/JackAudioAdapter.h b/common/JackAudioAdapter.h index 1a15c2a0..0eb93eed 100644 --- a/common/JackAudioAdapter.h +++ b/common/JackAudioAdapter.h @@ -21,6 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define __JackAudioAdapter__ #include "JackAudioAdapterInterface.h" +#include "driver_interface.h" namespace Jack { @@ -42,15 +43,15 @@ namespace Jack jack_client_t* fJackClient; JackAudioAdapterInterface* fAudioAdapter; + bool fAutoConnect; void FreePorts(); + void ConnectPorts(); void Reset(); public: - JackAudioAdapter ( jack_client_t* jack_client, JackAudioAdapterInterface* audio_io ) : - fJackClient ( jack_client ), fAudioAdapter ( audio_io ) - {} + JackAudioAdapter(jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params = NULL, bool system = false); ~JackAudioAdapter(); int Open(); diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index f8c4486d..67f99692 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -351,48 +351,21 @@ namespace Jack //process----------------------------------------------------------------------------- int JackNetAdapter::Process() { - bool failure = false; - int port_index; - //read data from the network //in case of fatal network error, stop the process - if ( Read() == SOCKET_ERROR ) + if (Read() == SOCKET_ERROR) return SOCKET_ERROR; - - //get the resample factor, - jack_time_t time1, time2; - ResampleFactor ( time1, time2 ); - - //resample input data, - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 ); - if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } - - //and output data, - for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) - { - fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 ); - if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fAdaptedBufferSize ) < fAdaptedBufferSize ) - failure = true; - } + + PushAndPull(fSoftCaptureBuffer, fSoftPlaybackBuffer, fAdaptedBufferSize); //then write data to network //in case of failure, stop process - if ( Write() == SOCKET_ERROR ) + if (Write() == SOCKET_ERROR) return SOCKET_ERROR; - //if there was any ringbuffer failure during resampling, reset - if ( failure ) - { - jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." ); - ResetRingBuffers(); - } - return 0; } + } // namespace Jack //loader------------------------------------------------------------------------------ @@ -413,7 +386,7 @@ extern "C" strcpy(desc->name, "netadapter"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy(desc->desc, "netjack net <==> audio backend adapter"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 9; + desc->nparams = 10; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); int i = 0; @@ -487,6 +460,14 @@ extern "C" desc->params[i].value.ui = 0; strcpy(desc->params[i].short_desc, "Resample algorithm quality (0 - 4)"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + + i++; + strcpy ( desc->params[i].name, "auto_connect" ); + desc->params[i].character = 'c'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" ); + strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); return desc; } @@ -501,7 +482,7 @@ extern "C" try { - adapter = new Jack::JackAudioAdapter ( jack_client, new Jack::JackNetAdapter ( jack_client, buffer_size, sample_rate, params ) ); + adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackNetAdapter(jack_client, buffer_size, sample_rate, params), params, false); assert ( adapter ); if ( adapter->Open() == 0 ) diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 13c61561..5f723b99 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -26,7 +26,7 @@ namespace Jack { //JackNetMaster****************************************************************************************************** - JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip ) + JackNetMaster::JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip) : JackNetMasterInterface ( params, socket, multicast_ip ) { jack_log ( "JackNetMaster::JackNetMaster" ); @@ -107,7 +107,7 @@ namespace Jack #endif } //init-------------------------------------------------------------------------------- - bool JackNetMaster::Init() + bool JackNetMaster::Init(bool auto_connect) { //network init if ( !JackNetMasterInterface::Init() ) @@ -141,9 +141,10 @@ namespace Jack jack_error ( "Can't activate jack client." ); goto fail; } - + + if (auto_connect) + ConnectPorts(); jack_info ( "New NetMaster started." ); - return true; fail: @@ -156,27 +157,26 @@ namespace Jack //jack ports-------------------------------------------------------------------------- int JackNetMaster::AllocPorts() { - jack_log ( "JackNetMaster::AllocPorts" ); - uint i; char name[24]; jack_nframes_t port_latency = jack_get_buffer_size ( fJackClient ); - unsigned long port_flags; + + jack_log ( "JackNetMaster::AllocPorts" ); + //audio - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for ( i = 0; i < fParams.fSendAudioChannels; i++ ) { sprintf ( name, "to_slave_%d", i+1 ); - if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fAudioCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency jack_port_set_latency ( fAudioCapturePorts[i], 0 ); } - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; + for ( i = 0; i < fParams.fReturnAudioChannels; i++ ) { sprintf ( name, "from_slave_%d", i+1 ); - if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fAudioPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency switch ( fParams.fNetworkMode ) @@ -192,21 +192,21 @@ namespace Jack break; } } + + //midi - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for ( i = 0; i < fParams.fSendMidiChannels; i++ ) { sprintf ( name, "midi_to_slave_%d", i+1 ); - if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fMidiCapturePorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency jack_port_set_latency ( fMidiCapturePorts[i], 0 ); } - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; for ( i = 0; i < fParams.fReturnMidiChannels; i++ ) { sprintf ( name, "midi_from_slave_%d", i+1 ); - if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, port_flags, 0 ) ) == NULL ) + if ( ( fMidiPlaybackPorts[i] = jack_port_register ( fJackClient, name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 ) ) == NULL ) return -1; //port latency switch ( fParams.fNetworkMode ) @@ -224,6 +224,27 @@ namespace Jack } return 0; } + + void JackNetMaster::ConnectPorts() + { + const char **ports; + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); + if (ports != NULL) { + for (unsigned int i = 0; i < fParams.fSendAudioChannels && ports[i]; i++) { + jack_connect(fJackClient, ports[i], jack_port_name(fAudioCapturePorts[i])); + } + free(ports); + } + + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + if (ports != NULL) { + for (unsigned int i = 0; i < fParams.fReturnAudioChannels && ports[i]; i++) { + jack_connect(fJackClient, jack_port_name(fAudioPlaybackPorts[i]), ports[i]); + } + free(ports); + } + } void JackNetMaster::FreePorts() { @@ -439,6 +460,7 @@ namespace Jack fSocket.SetPort ( DEFAULT_PORT ); fGlobalID = 0; fRunning = true; + fAutoConnect = false; const JSList* node; const jack_driver_param_t* param; @@ -453,8 +475,14 @@ namespace Jack else jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP); break; + case 'p': fSocket.SetPort ( param->value.ui ); + break; + + case 'c': + fAutoConnect = param->value.i; + break; } } @@ -613,8 +641,8 @@ namespace Jack SetSlaveName ( params ); //create a new master and add it to the list - JackNetMaster* master = new JackNetMaster ( fSocket, params, fMulticastIP ); - if ( master->Init() ) + JackNetMaster* master = new JackNetMaster(fSocket, params, fMulticastIP); + if ( master->Init(fAutoConnect) ) { fMasterList.push_back ( master ); return master; @@ -674,7 +702,7 @@ extern "C" strcpy ( desc->name, "netmanager" ); // size MUST be less then JACK_DRIVER_NAME_MAX + 1 strcpy ( desc->desc, "netjack multi-cast master component" ); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1 - desc->nparams = 2; + desc->nparams = 3; desc->params = ( jack_driver_param_desc_t* ) calloc ( desc->nparams, sizeof ( jack_driver_param_desc_t ) ); int i = 0; @@ -692,6 +720,14 @@ extern "C" desc->params[i].value.i = DEFAULT_PORT; strcpy ( desc->params[i].short_desc, "UDP port" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); + + i++; + strcpy ( desc->params[i].name, "auto_connect" ); + desc->params[i].character = 'c'; + desc->params[i].type = JackDriverParamBool; + desc->params[i].value.i = false; + strcpy ( desc->params[i].short_desc, "Auto connect netmaster to system ports" ); + strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); return desc; } diff --git a/common/JackNetManager.h b/common/JackNetManager.h index ac06764a..6e05759f 100644 --- a/common/JackNetManager.h +++ b/common/JackNetManager.h @@ -53,14 +53,14 @@ namespace Jack //sync and transport int fLastTransportState; - + //monitoring #ifdef JACK_MONITOR jack_time_t fPeriodUsecs; JackGnuPlotMonitor* fNetTimeMon; #endif - bool Init(); + bool Init(bool auto_connect); int AllocPorts(); void FreePorts(); void Exit(); @@ -71,9 +71,10 @@ namespace Jack int Process(); void TimebaseCallback ( jack_position_t* pos ); + void ConnectPorts(); public: - JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip ); + JackNetMaster ( JackNetSocket& socket, session_params_t& params, const char* multicast_ip); ~JackNetMaster (); bool IsSlaveReadyToRoll(); @@ -101,6 +102,7 @@ namespace Jack master_list_t fMasterList; uint32_t fGlobalID; bool fRunning; + bool fAutoConnect; void Run(); JackNetMaster* MasterInit ( session_params_t& params ); @@ -110,7 +112,7 @@ namespace Jack int SyncCallback ( jack_transport_state_t state, jack_position_t* pos ); public: - JackNetMasterManager ( jack_client_t* jack_client, const JSList* params ); + JackNetMasterManager ( jack_client_t* jack_client, const JSList* params); ~JackNetMasterManager(); }; } diff --git a/windows/README b/windows/README index ab94a3a3..f7cbebb7 100644 --- a/windows/README +++ b/windows/README @@ -1,5 +1,5 @@ ------------------------------- -Jackmp on windows +Jackmp on Windows ------------------------------- This folder contains all the windows specific sources. @@ -34,11 +34,11 @@ You can make a small installer ('setup.exe') with CreateInstallFree, a little fr A binary version of qjackctl is also included. ------------------------------- -Running Jack on windows +Running Jack on Windows ------------------------------- You can use two drivers : PortAudio and NetDriver. -The PortAudio backend allow the use of many soundcards, using ASIO or WMME drivers (any ASIO driver can be seen by PortAudio). +The PortAudio backend allow the use of many soundcards, using ASIO, DirectSound or WMME drivers (any ASIO driver can be seen by PortAudio). The NetDriver allow you to use NetJack2 on windows. Thus you can easily exchange midi and audio streams bitween computers (Linux, MacOSX or Windows). In both cases, you have to use the minimalist : 'jackd -R -d ...' @@ -46,7 +46,11 @@ In both cases, you have to use the minimalist : 'jackd -R -S -d portaudio -l' Other options still stay the same. -You can also pick a binary of Qjackctl, but this is still in development. +You can also pick a binary of Qjackctl, but this is still in development. + +------------------------------- +Running Jack on windows +------------------------------- More information at : 'http://www.grame.fr/~letz/jackdmp.html'. diff --git a/windows/Setup/src/README b/windows/Setup/src/README index 589d874d..eef08432 100644 --- a/windows/Setup/src/README +++ b/windows/Setup/src/README @@ -28,7 +28,7 @@ It is compiled from the latest CVS version which is using QT4 framework. To uses - quit qjackctl.exe and start is again, it should now launch the jack server. Quitting the qjackctl.exe will now close the jack server. Starting the jack server with another audio device installed on the machine (like an ASIO card) can now be done directly in qjackctl. -A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "Direct Sound", or "ASIO". +A ">" button at the right of the interface button allows to list the name of all available devices, driven either by "MME", "DirectSound", or "ASIO". Alternatively using the following command allows to display the names of available devices: - jackd -d portaudio -l to display the entire list of available audio devices. (jackd -d portaudio -h will display all portaudio driver features)