diff --git a/common/JackAudioAdapter.h b/common/JackAudioAdapter.h index 070a530d..60550ce9 100644 --- a/common/JackAudioAdapter.h +++ b/common/JackAudioAdapter.h @@ -34,7 +34,7 @@ namespace Jack class JackAudioAdapter { private: - + static int Process(jack_nframes_t, void* arg); static int BufferSize(jack_nframes_t buffer_size, void *arg); static int SampleRate(jack_nframes_t sample_rate, void *arg); @@ -55,7 +55,7 @@ class JackAudioAdapter void Reset(); public: - + JackAudioAdapter(jack_client_t* jack_client, JackAudioAdapterInterface* audio_io) : fJackClient(jack_client), fAudioAdapter(audio_io) {} diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index 93b34176..0b50f0bd 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -38,7 +38,7 @@ namespace Jack #define TABLE_MAX 100000 -struct Measure +struct Measure { int delta; int time1; @@ -49,7 +49,7 @@ struct Measure int pos2; }; -struct MeasureTable +struct MeasureTable { Measure fTable[TABLE_MAX]; @@ -77,26 +77,26 @@ class JackAudioAdapterInterface #ifdef JACK_MONITOR MeasureTable fTable; #endif - + int fCaptureChannels; int fPlaybackChannels; - + jack_nframes_t fBufferSize; jack_nframes_t fSampleRate; - + // DLL JackAtomicDelayLockedLoop fProducerDLL; JackAtomicDelayLockedLoop fConsumerDLL; - + JackResampler** fCaptureRingBuffer; JackResampler** fPlaybackRingBuffer; bool fRunning; - + public: - + JackAudioAdapterInterface(jack_nframes_t buffer_size, jack_nframes_t sample_rate) - :fBufferSize(buffer_size), + :fBufferSize(buffer_size), fSampleRate(sample_rate), fProducerDLL(buffer_size, sample_rate), fConsumerDLL(buffer_size, sample_rate), @@ -104,21 +104,21 @@ class JackAudioAdapterInterface {} virtual ~JackAudioAdapterInterface() {} - + void SetRingBuffers(JackResampler** input, JackResampler** output) { fCaptureRingBuffer = input; fPlaybackRingBuffer = output; } - + bool IsRunning() {return fRunning;} - + virtual void Reset() {fRunning = false;} void ResetRingBuffers(); - + virtual int Open(); virtual int Close(); - + virtual int SetBufferSize(jack_nframes_t buffer_size) { fBufferSize = buffer_size; @@ -126,7 +126,7 @@ class JackAudioAdapterInterface fProducerDLL.Init(fBufferSize, fSampleRate); return 0; } - + virtual int SetSampleRate(jack_nframes_t sample_rate) { fSampleRate = sample_rate; @@ -134,7 +134,7 @@ class JackAudioAdapterInterface // Producer (Audio) keeps the same SR return 0; } - + virtual int SetAudioSampleRate(jack_nframes_t sample_rate) { fSampleRate = sample_rate; @@ -142,24 +142,38 @@ class JackAudioAdapterInterface fProducerDLL.Init(fBufferSize, fSampleRate); return 0; } - + virtual void SetCallbackTime(jack_time_t callback_usec) { fConsumerDLL.IncFrame(callback_usec); } - + void ResampleFactor(jack_nframes_t& frame1, jack_nframes_t& frame2); - + + void SetInputs ( int inputs ) + { + jack_log ( "JackAudioAdapterInterface::SetInputs %d", inputs ); + fCaptureChannels = inputs; + } + + void SetOutputs ( int outputs ) + { + jack_log ( "JackAudioAdapterInterface::SetOutputs %d", outputs ); + fPlaybackChannels = outputs; + } + int GetInputs() { + jack_log ( "JackAudioAdapterInterface::GetInputs %d", fCaptureChannels ); return fCaptureChannels; - } - + } + int GetOutputs() { + jack_log ( "JackAudioAdapterInterface::GetOutputs %d", fPlaybackChannels ); return fPlaybackChannels; - } - + } + }; } diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 3552f7d7..9b268bf4 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -24,9 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { - JackNetAdapter::JackNetAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ) - : JackAudioAdapterInterface ( buffer_size, sample_rate ), fThread ( this ) + : JackAudioAdapterInterface ( buffer_size, sample_rate ), JackNetSlaveInterface(), fThread ( this ) { jack_log ( "JackNetAdapter::JackNetAdapter" ); @@ -36,7 +35,7 @@ namespace Jack //global parametering fMulticastIP = new char[16]; strcpy ( fMulticastIP, DEFAULT_MULTICAST_IP ); - fSocket.SetPort ( DEFAULT_PORT ); + uint port = DEFAULT_PORT; GetHostName ( fParams.fName, JACK_CLIENT_NAME_SIZE ); fSocket.GetName ( fParams.fSlaveNetName ); fParams.fMtu = 1500; @@ -45,8 +44,8 @@ namespace Jack fParams.fReturnAudioChannels = 2; fParams.fSendMidiChannels = 0; fParams.fReturnMidiChannels = 0; - fParams.fSampleRate = 48000; - fParams.fPeriodSize = 128; + fParams.fSampleRate = sample_rate; + fParams.fPeriodSize = buffer_size; fParams.fSlaveSyncMode = 1; fParams.fNetworkMode = 'n'; @@ -59,18 +58,21 @@ namespace Jack switch ( param->character ) { case 'a' : - fMulticastIP = strdup ( param->value.str ); + if ( strlen ( param->value.str ) < 16 ) + strcpy ( fMulticastIP, param->value.str ); + else + jack_error ( "Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP ); break; - case 'p': + case 'p' : fSocket.SetPort ( param->value.ui ); break; - case 'M': + case 'M' : fParams.fMtu = param->value.i; break; - case 'C': + case 'C' : fParams.fSendAudioChannels = param->value.i; break; - case 'P': + case 'P' : fParams.fReturnAudioChannels = param->value.i; break; case 'n' : @@ -91,11 +93,20 @@ namespace Jack break; case 'S' : fParams.fSlaveSyncMode = 1; + break; } } - fCaptureChannels = fParams.fSendAudioChannels; - fPlaybackChannels = fParams.fReturnAudioChannels; + fSocket.SetPort ( port ); + fSocket.SetAddress ( fMulticastIP, port ); + + jack_info ( "netadapter : this %x", this ); + jack_info ( "netadapter : input %x", &fCaptureChannels ); + jack_info ( "netadapter : output %x", &fPlaybackChannels ); + + SetInputs ( fParams.fSendAudioChannels ); + SetOutputs ( fParams.fReturnAudioChannels ); + fSoftCaptureBuffer = NULL; fSoftPlaybackBuffer = NULL; } @@ -113,35 +124,11 @@ namespace Jack int JackNetAdapter::Open() { - jack_log ( "JackNetAdapter::Open()" ); + jack_log ( "JackNetAdapter::Open" ); - int port_index; - - //display some additional infos jack_info ( "Net adapter started in %s mode %s Master's transport sync.", ( fParams.fSlaveSyncMode ) ? "sync" : "async", ( fParams.fTransportSync ) ? "with" : "without" ); - //init network connection - if ( !JackNetSlaveInterface::Init() ) - return -1; - - //then set global parameters - SetParams(); - - //set buffers - fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize]; - fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] ); - } - fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels]; - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize]; - fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] ); - } - fThread.AcquireRealTime ( 85 ); return fThread.StartSync(); @@ -149,6 +136,7 @@ namespace Jack int JackNetAdapter::Close() { + fThread.Stop(); fSocket.Close(); return 0; } @@ -161,25 +149,38 @@ namespace Jack bool JackNetAdapter::Init() { - jack_info ( "Starting NetAdapter." ); - return true; - } + jack_log ( "JackNetAdapter::Init" ); - bool JackNetAdapter::Execute() - { - //the sync mode is the equivalent of driver sync mode : data are sent back right after being computed - //TODO : verify async mode is appropriate here, because of the ringbuffer usage - switch ( fParams.fSlaveSyncMode ) + int port_index; + + //init network connection + if ( !JackNetSlaveInterface::Init() ) + return false; + + //then set global parameters + SetParams(); + + //set buffers + fSoftCaptureBuffer = new sample_t*[fCaptureChannels]; + for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) { - case true : - return ProcessSync(); - case false : - return ProcessAsync(); + fSoftCaptureBuffer[port_index] = new sample_t[fParams.fPeriodSize]; + fNetAudioCaptureBuffer->SetBuffer ( port_index, fSoftCaptureBuffer[port_index] ); } + fSoftPlaybackBuffer = new sample_t*[fPlaybackChannels]; + for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) + { + fSoftPlaybackBuffer[port_index] = new sample_t[fParams.fPeriodSize]; + fNetAudioPlaybackBuffer->SetBuffer ( port_index, fSoftPlaybackBuffer[port_index] ); + } + + //init done, display parameters + SessionParamsDisplay ( &fParams ); + return true; } - bool JackNetAdapter::ProcessSync() + bool JackNetAdapter::Execute() { bool failure = false; int port_index; @@ -195,6 +196,7 @@ namespace Jack jack_nframes_t time1, time2; ResampleFactor ( time1, time2 ); + for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) { fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 ); @@ -224,53 +226,6 @@ namespace Jack return true; } - - bool JackNetAdapter::ProcessAsync() - { - bool failure = false; - int port_index; - - //receive - if ( SyncRecv() == SOCKET_ERROR ) - return true; - - if ( DataRecv() == SOCKET_ERROR ) - return false; - - //send - if ( SyncSend() == SOCKET_ERROR ) - return false; - - if ( DataSend() == SOCKET_ERROR ) - return false; - - if ( failure ) - { - jack_error ( "JackNetAdapter::Execute ringbuffer failure...reset." ); - ResetRingBuffers(); - } - - //resample - jack_nframes_t time1, time2; - ResampleFactor ( time1, time2 ); - - for ( port_index = 0; port_index < fCaptureChannels; port_index++ ) - { - fCaptureRingBuffer[port_index]->SetRatio ( time1, time2 ); - if ( fCaptureRingBuffer[port_index]->WriteResample ( fSoftCaptureBuffer[port_index], fBufferSize ) < fBufferSize ) - failure = true; - } - - for ( port_index = 0; port_index < fPlaybackChannels; port_index++ ) - { - fPlaybackRingBuffer[port_index]->SetRatio ( time2, time1 ); - if ( fPlaybackRingBuffer[port_index]->ReadResample ( fSoftPlaybackBuffer[port_index], fBufferSize ) < fBufferSize ) - failure = true; - } - - return true; - } - } // namespace Jack #ifdef __cplusplus @@ -377,9 +332,7 @@ extern "C" assert ( adapter ); if ( adapter->Open() == 0 ) - { return 0; - } else { delete adapter; @@ -395,10 +348,8 @@ extern "C" JackArgParser parser ( load_init ); if ( parser.GetArgc() > 0 ) - { if ( parser.ParseParams ( desc, ¶ms ) != 0 ) jack_error ( "Internal client : JackArgParser::ParseParams error." ); - } return jack_internal_initialize ( jack_client, params ); } diff --git a/common/JackNetAdapter.h b/common/JackNetAdapter.h index 9a173e9d..4836b75e 100644 --- a/common/JackNetAdapter.h +++ b/common/JackNetAdapter.h @@ -20,13 +20,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #ifndef __JackNetAdapter__ #define __JackNetAdapter__ -#include -#include #include #include "JackAudioAdapterInterface.h" #include "JackPlatformThread.h" -#include "jack.h" -#include "jslist.h" #include "JackNetInterface.h" namespace Jack @@ -38,21 +34,14 @@ namespace Jack class JackNetAdapter : public JackAudioAdapterInterface, public JackNetSlaveInterface, public JackRunnableInterface { - private: - //jack data + //jack data net_transport_data_t fTransportData; //sample buffers sample_t** fSoftCaptureBuffer; sample_t** fSoftPlaybackBuffer; - int SetSyncPacket(); - int TransportSync(); - - bool ProcessSync(); - bool ProcessAsync(); - JackThread fThread; public: @@ -60,13 +49,13 @@ namespace Jack JackNetAdapter ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params ); ~JackNetAdapter(); - virtual int Open(); - virtual int Close(); + int Open(); + int Close(); - virtual int SetBufferSize ( jack_nframes_t buffer_size ); + int SetBufferSize ( jack_nframes_t buffer_size ); - virtual bool Init(); - virtual bool Execute(); + bool Init(); + bool Execute(); }; } diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 7c1f0013..1c22c167 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -32,7 +32,6 @@ namespace Jack JackNetInterface::JackNetInterface ( const char* multicast_ip, int port ) : fSocket ( multicast_ip, port ) { - fMulticastIP = strdup ( multicast_ip ); } @@ -78,8 +77,8 @@ namespace Jack //midi midi_size = fParams.fMtu * ( max ( fParams.fSendMidiChannels, fParams.fReturnMidiChannels ) * fParams.fPeriodSize * sizeof ( sample_t ) / ( fParams.fMtu - sizeof ( packet_header_t ) ) ); - //size of sync + audio + midi - bufsize = 2 * ( fParams.fMtu + ( int ) audio_size + ( int ) midi_size ); + //bufsize = sync + audio + midi + bufsize = fParams.fMtu + ( int ) audio_size + ( int ) midi_size; //tx buffer if ( fSocket.SetOption ( SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof ( bufsize ) ) == SOCKET_ERROR ) @@ -114,10 +113,10 @@ namespace Jack //same PcktID (cycle), next SubPcktID (subcycle) if ( ( fRxHeader.fSubCycle < ( fNSubProcess - 1 ) ) && ( rx_head->fCycle == fRxHeader.fCycle ) && ( rx_head->fSubCycle == ( fRxHeader.fSubCycle + 1 ) ) ) return true; - //next PcktID (cycle), SubPcktID reset to 1 (first subcyle) + //next PcktID (cycle), SubPcktID reset to 0 (first subcyle) if ( ( rx_head->fCycle == ( fRxHeader.fCycle + 1 ) ) && ( fRxHeader.fSubCycle == ( fNSubProcess - 1 ) ) && ( rx_head->fSubCycle == 0 ) ) return true; - //else, next is'nt next, return false + //else, packet(s) missing, return false return false; } @@ -187,8 +186,6 @@ namespace Jack //set the number of complete audio frames we can put in a packet SetFramesPerPacket(); - jack_log ( "JackNetMasterInterface::Init Frames per packet %u", fParams.fFramesPerPacket ); - //send 'SLAVE_SETUP' until 'START_MASTER' received jack_info ( "Sending parameters to %s ...", fParams.fSlaveNetName ); do @@ -231,10 +228,10 @@ namespace Jack float time = 0; //slow mode, very short timeout on recv if ( fParams.fNetworkMode == 's' ) - time = 1000000.f * ( static_cast ( fParams.fFramesPerPacket ) / static_cast ( fParams.fSampleRate ) ); + time = 2000000.f * ( static_cast ( fParams.fFramesPerPacket ) / static_cast ( fParams.fSampleRate ) ); //normal mode, short timeout on recv else if ( fParams.fNetworkMode == 'n' ) - time = 2000000.f * ( static_cast ( fParams.fFramesPerPacket ) / static_cast ( fParams.fSampleRate ) ); + time = 4000000.f * ( static_cast ( fParams.fFramesPerPacket ) / static_cast ( fParams.fSampleRate ) ); //fast mode, wait for the entire cycle duration else if ( fParams.fNetworkMode == 'f' ) time = 750000.f * ( static_cast ( fParams.fPeriodSize ) / static_cast ( fParams.fSampleRate ) ); @@ -345,8 +342,8 @@ namespace Jack { fTxHeader.fSubCycle = subproc; fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fSendAudioChannels ) ? 1 : 0; - fTxHeader.fPacketSize = fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); - fTxHeader.fPacketSize += sizeof ( packet_header_t ); + fTxHeader.fPacketSize = sizeof ( packet_header_t ); + fTxHeader.fPacketSize += fNetMidiCaptureBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) return SOCKET_ERROR; @@ -433,7 +430,7 @@ namespace Jack rx_bytes = Recv ( fParams.fMtu, MSG_PEEK ); if ( rx_bytes == SOCKET_ERROR ) return rx_bytes; - //if no data, + //if no data if ( ( rx_bytes == 0 ) && ( ++jumpcnt == fNSubProcess ) ) { jack_error ( "No data from %s...", fParams.fName ); @@ -736,8 +733,8 @@ namespace Jack { fTxHeader.fSubCycle = subproc; fTxHeader.fIsLastPckt = ( ( subproc == ( fTxHeader.fNMidiPckt - 1 ) ) && !fParams.fReturnAudioChannels ) ? 1 : 0; - fTxHeader.fPacketSize = fNetMidiPlaybackBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); - fTxHeader.fPacketSize += sizeof ( packet_header_t ); + fTxHeader.fPacketSize = sizeof ( packet_header_t ); + fTxHeader.fPacketSize += fNetMidiPlaybackBuffer->RenderToNetwork ( subproc, fTxHeader.fMidiDataSize ); memcpy ( fTxBuffer, &fTxHeader, sizeof ( packet_header_t ) ); if ( Send ( fTxHeader.fPacketSize, 0 ) == SOCKET_ERROR ) return SOCKET_ERROR; diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index 601c04d1..dca8454f 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -76,7 +76,7 @@ namespace Jack virtual int Send ( size_t size, int flags ) = 0; virtual int Recv ( size_t size, int flags ) = 0; - JackNetInterface() + JackNetInterface() : fSocket() {} JackNetInterface ( const char* multicast_ip, int port ); JackNetInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ); @@ -107,7 +107,7 @@ namespace Jack int Recv ( size_t size, int flags ); public: - JackNetMasterInterface() : fRunning ( false ) + JackNetMasterInterface() : JackNetInterface(), fRunning ( false ) {} JackNetMasterInterface ( session_params_t& params, JackNetSocket& socket, const char* multicast_ip ) : JackNetInterface ( params, socket, multicast_ip ) @@ -136,7 +136,7 @@ namespace Jack int Send ( size_t size, int flags ); public: - JackNetSlaveInterface() + JackNetSlaveInterface() : JackNetInterface() {} JackNetSlaveInterface ( const char* ip, int port ) : JackNetInterface ( ip, port ) {} diff --git a/windows/jack_audioadapter.cbp b/windows/jack_audioadapter.cbp index f7bebc51..15b0e2f0 100644 --- a/windows/jack_audioadapter.cbp +++ b/windows/jack_audioadapter.cbp @@ -128,6 +128,7 @@ + diff --git a/windows/jack_netadapter.cbp b/windows/jack_netadapter.cbp index 1eb27ec2..46e0c7d4 100644 --- a/windows/jack_netadapter.cbp +++ b/windows/jack_netadapter.cbp @@ -77,6 +77,7 @@ + diff --git a/windows/jackdmp.workspace b/windows/jackdmp.workspace index 3b4d6677..9938bff0 100644 --- a/windows/jackdmp.workspace +++ b/windows/jackdmp.workspace @@ -16,7 +16,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/windows/jacknetadapter.rc b/windows/jacknetadapter.rc index 859d6803..934df1de 100644 --- a/windows/jacknetadapter.rc +++ b/windows/jacknetadapter.rc @@ -24,12 +24,12 @@ BEGIN VALUE "CompanyName", "Grame\0" VALUE "FileDescription", "Jackmp Net Adapter for Windows\0" VALUE "FileVersion", "1, 9, 0, 0\0" - VALUE "InternalName", "jack_netadapter\0" + VALUE "InternalName", "netadapter\0" VALUE "LegalCopyright", "Copyright Grame © 2006-2008\0" VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "jack_netadapter.dll\0" + VALUE "OriginalFilename", "netadapter.dll\0" VALUE "PrivateBuild", "\0" - VALUE "ProductName", "jack_netadapter\0" + VALUE "ProductName", "netadapter\0" VALUE "ProductVersion", "1, 9, 0, 0\0" VALUE "SpecialBuild", "\0" END