diff options
author | sletz <sletz@0c269be4-1314-0410-8aa9-9f06e86f4224> | 2011-11-04 13:54:47 +0000 |
---|---|---|
committer | sletz <sletz@0c269be4-1314-0410-8aa9-9f06e86f4224> | 2011-11-04 13:54:47 +0000 |
commit | 49d98099bf72f133de9d376025f83954e5000c47 (patch) | |
tree | 9954307ae45def8d493a0eebb7648924938c792e | |
parent | 2b7864ad5ebee559b459c6450ca1965b5906abbb (diff) | |
parent | 734e45092474d2f77933dc2075bfec799b731c37 (diff) | |
download | jack2-49d98099bf72f133de9d376025f83954e5000c47.tar.gz |
Merge branch 'netjack2-cleanup'
git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4563 0c269be4-1314-0410-8aa9-9f06e86f4224
49 files changed, 1650 insertions, 1255 deletions
diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index 5294bfd7..22120fb7 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -32,172 +32,188 @@ using namespace std; namespace Jack { -//static methods *********************************************************** - int JackAudioAdapter::Process (jack_nframes_t frames, void* arg) - { - JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); - jack_default_audio_sample_t* inputBuffer[adapter->fAudioAdapter->GetInputs()]; - jack_default_audio_sample_t* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; - - // Always clear output - for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { - #ifdef OPTIMIZED_PROTOCOL - inputBuffer[i] = (jack_port_connected(adapter->fCapturePortList[i]) > 0) - ? (jack_default_audio_sample_t*)(adapter->fCapturePortList[i], frames) - : NULL; - if (inputBuffer[i]) { - memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t)); - } - #else - inputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); - memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t)); - #endif - } - - for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { - #ifdef OPTIMIZED_PROTOCOL - outputBuffer[i] = (jack_port_connected(fAudioCapturePorts[audio_port_index] > 0) - ? (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames) - : NULL; - #else - outputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); - #endif - } - - adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); - return 0; +int JackAudioAdapter::Process(jack_nframes_t frames, void* arg) +{ + JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); + jack_default_audio_sample_t* inputBuffer[adapter->fAudioAdapter->GetInputs()]; + jack_default_audio_sample_t* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; + + // Always clear output + for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { + inputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); + memset(inputBuffer[i], 0, frames * sizeof(jack_default_audio_sample_t)); } - int JackAudioAdapter::BufferSize ( jack_nframes_t buffer_size, void* arg ) - { - JackAudioAdapter* adapter = static_cast<JackAudioAdapter*> ( arg ); - adapter->Reset(); - adapter->fAudioAdapter->SetHostBufferSize ( buffer_size ); - return 0; + for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { + outputBuffer[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); } - int JackAudioAdapter::SampleRate ( jack_nframes_t sample_rate, void* arg ) - { - JackAudioAdapter* adapter = static_cast<JackAudioAdapter*> ( arg ); - adapter->Reset(); - adapter->fAudioAdapter->SetHostSampleRate ( sample_rate ); - return 0; - } + adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); + return 0; +} + +int JackAudioAdapter::BufferSize(jack_nframes_t buffer_size, void* arg) +{ + JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); + adapter->Reset(); + adapter->fAudioAdapter->SetHostBufferSize(buffer_size); + return 0; +} -//JackAudioAdapter ********************************************************* +int JackAudioAdapter::SampleRate(jack_nframes_t sample_rate, void* arg) +{ + JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); + adapter->Reset(); + adapter->fAudioAdapter->SetHostSampleRate(sample_rate); + return 0; +} - 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; +void JackAudioAdapter::Latency(jack_latency_callback_mode_t mode, void* arg) +{ + JackAudioAdapter* adapter = static_cast<JackAudioAdapter*>(arg); - for (node = params; node; node = jack_slist_next(node)) { - param = (const jack_driver_param_t*) node->data; - switch (param->character) { - case 'c': - fAutoConnect = true; - break; - } + if (mode == JackCaptureLatency) { + for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { + jack_latency_range_t range; + range.min = range.max = adapter->fAudioAdapter->GetInputLatency(i); + jack_port_set_latency_range(adapter->fCapturePortList[i], JackCaptureLatency, &range); + } + + } else { + for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { + jack_latency_range_t range; + range.min = range.max = adapter->fAudioAdapter->GetOutputLatency(i); + jack_port_set_latency_range(adapter->fPlaybackPortList[i], JackPlaybackLatency, &range); } } +} - JackAudioAdapter::~JackAudioAdapter() - { - // When called, Close has already been used for the client, thus ports are already unregistered. - delete fAudioAdapter; +JackAudioAdapter::JackAudioAdapter(jack_client_t* client, JackAudioAdapterInterface* audio_io, const JSList* params) + :fClient(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 = true; + break; + } } +} - void JackAudioAdapter::FreePorts() - { - for (int i = 0; i < fAudioAdapter->GetInputs(); i++ ) - if ( fCapturePortList[i] ) - jack_port_unregister ( fJackClient, fCapturePortList[i] ); - for (int i = 0; i < fAudioAdapter->GetOutputs(); i++ ) - if ( fPlaybackPortList[i] ) - jack_port_unregister ( fJackClient, fPlaybackPortList[i] ); +JackAudioAdapter::~JackAudioAdapter() +{ + // When called, Close has already been used for the client, thus ports are already unregistered. + delete fAudioAdapter; +} - delete[] fCapturePortList; - delete[] fPlaybackPortList; +void JackAudioAdapter::FreePorts() +{ + for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { + if (fCapturePortList[i]) { + jack_port_unregister(fClient, fCapturePortList[i]); + } + } + for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { + if (fPlaybackPortList[i]) { + jack_port_unregister(fClient, fPlaybackPortList[i]); + } } - void JackAudioAdapter::ConnectPorts() - { - const char **ports; + delete[] fCapturePortList; + delete[] fPlaybackPortList; +} - 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); - } +void JackAudioAdapter::ConnectPorts() +{ + const char** 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); + ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); + if (ports != NULL) { + for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { + jack_connect(fClient,jack_port_name(fCapturePortList[i]), ports[i]); } + jack_free(ports); } - void JackAudioAdapter::Reset() - { - fAudioAdapter->Reset(); + ports = jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); + if (ports != NULL) { + for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { + jack_connect(fClient, ports[i], jack_port_name(fPlaybackPortList[i])); + } + jack_free(ports); } +} - int JackAudioAdapter::Open() - { - char name[32]; - jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); - fAudioAdapter->Create(); +void JackAudioAdapter::Reset() +{ + fAudioAdapter->Reset(); +} - //jack ports - fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; - fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; +int JackAudioAdapter::Open() +{ + char name[32]; + jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); + fAudioAdapter->Create(); - for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { - sprintf(name, "capture_%d", i + 1); - if ((fCapturePortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == NULL) - goto fail; - } + //jack ports + fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; + fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; - for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { - sprintf(name, "playback_%d", i + 1); - if ((fPlaybackPortList[i] = jack_port_register(fJackClient, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == NULL) - goto fail; + for (int i = 0; i < fAudioAdapter->GetInputs(); i++) { + sprintf(name, "capture_%d", i + 1); + if ((fCapturePortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, 0)) == NULL) { + goto fail; } + } - //callbacks and activation - if (jack_set_process_callback(fJackClient, Process, this) < 0) - goto fail; - if (jack_set_buffer_size_callback(fJackClient, BufferSize, this) < 0) + for (int i = 0; i < fAudioAdapter->GetOutputs(); i++) { + sprintf(name, "playback_%d", i + 1); + if ((fPlaybackPortList[i] = jack_port_register(fClient, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, 0)) == NULL) { goto fail; - if (jack_set_sample_rate_callback(fJackClient, SampleRate, this) < 0) - goto fail; - if (jack_activate(fJackClient) < 0) - goto fail; - - if (fAutoConnect) - ConnectPorts(); - - // Ring buffers are now allocated.. - return fAudioAdapter->Open(); - return 0; + } + } - fail: - FreePorts(); - fAudioAdapter->Destroy(); - return -1; + //callbacks and activation + if (jack_set_process_callback(fClient, Process, this) < 0) { + goto fail; + } + if (jack_set_buffer_size_callback(fClient, BufferSize, this) < 0) { + goto fail; + } + if (jack_set_sample_rate_callback(fClient, SampleRate, this) < 0) { + goto fail; + } + if (jack_set_latency_callback(fClient, Latency, this) < 0) { + goto fail; + } + if (jack_activate(fClient) < 0) { + goto fail; } - int JackAudioAdapter::Close() - { - fAudioAdapter->Close(); - fAudioAdapter->Destroy(); - return 0; + if (fAutoConnect) { + ConnectPorts(); } + // Ring buffers are now allocated... + return fAudioAdapter->Open(); + return 0; + +fail: + FreePorts(); + fAudioAdapter->Destroy(); + return -1; +} + +int JackAudioAdapter::Close() +{ + fAudioAdapter->Close(); + fAudioAdapter->Destroy(); + return 0; +} + } //namespace diff --git a/common/JackAudioAdapter.h b/common/JackAudioAdapter.h index 9af3f017..fd7ed13e 100644 --- a/common/JackAudioAdapter.h +++ b/common/JackAudioAdapter.h @@ -37,11 +37,12 @@ namespace Jack 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); + static void Latency(jack_latency_callback_mode_t mode, void* arg); jack_port_t** fCapturePortList; jack_port_t** fPlaybackPortList; - jack_client_t* fJackClient; + jack_client_t* fClient; JackAudioAdapterInterface* fAudioAdapter; bool fAutoConnect; @@ -51,7 +52,7 @@ namespace Jack public: - JackAudioAdapter(jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params = NULL, bool system = false); + JackAudioAdapter(jack_client_t* client, JackAudioAdapterInterface* audio_io, const JSList* params = NULL); ~JackAudioAdapter(); int Open(); @@ -60,4 +61,7 @@ namespace Jack } +#define CaptureDriverFlags static_cast<JackPortFlags>(JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal) +#define PlaybackDriverFlags static_cast<JackPortFlags>(JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal) + #endif diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index c4577293..6beeed5e 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -49,8 +49,7 @@ namespace Jack FILE* file = fopen("JackAudioAdapter.log", "w"); int max = (fCount) % TABLE_MAX - 1; - for (int i = 1; i < max; i++) - { + for (int i = 1; i < max; i++) { fprintf(file, "%d \t %d \t %d \t %f \t %f \t %d \t %d \n", fTable[i].delta, fTable[i].time1, fTable[i].time2, fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2); @@ -158,21 +157,25 @@ namespace Jack void JackAudioAdapterInterface::AdaptRingBufferSize() { - if (fHostBufferSize > fAdaptedBufferSize) + if (fHostBufferSize > fAdaptedBufferSize) { fRingbufferCurSize = 4 * fHostBufferSize; - else + } else { fRingbufferCurSize = 4 * fAdaptedBufferSize; + } } void JackAudioAdapterInterface::ResetRingBuffers() { - if (fRingbufferCurSize > DEFAULT_RB_SIZE) + if (fRingbufferCurSize > DEFAULT_RB_SIZE) { fRingbufferCurSize = DEFAULT_RB_SIZE; + } - for (int i = 0; i < fCaptureChannels; i++) + for (int i = 0; i < fCaptureChannels; i++) { fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); - for (int i = 0; i < fPlaybackChannels; i++) + } + for (int i = 0; i < fPlaybackChannels; i++) { fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); + } } void JackAudioAdapterInterface::Reset() @@ -195,8 +198,9 @@ namespace Jack AdaptRingBufferSize(); jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); } else { - if (fRingbufferCurSize > DEFAULT_RB_SIZE) + if (fRingbufferCurSize > DEFAULT_RB_SIZE) { fRingbufferCurSize = DEFAULT_RB_SIZE; + } jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); } @@ -209,19 +213,23 @@ namespace Jack fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } - if (fCaptureChannels > 0) + if (fCaptureChannels > 0) { jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); - if (fPlaybackChannels > 0) + } + if (fPlaybackChannels > 0) { jack_log("WriteSpace = %ld", fPlaybackRingBuffer[0]->WriteSpace()); + } } #endif void JackAudioAdapterInterface::Destroy() { - for (int i = 0; i < fCaptureChannels; i++ ) - delete ( fCaptureRingBuffer[i] ); - for (int i = 0; i < fPlaybackChannels; i++ ) - delete ( fPlaybackRingBuffer[i] ); + for (int i = 0; i < fCaptureChannels; i++) { + delete(fCaptureRingBuffer[i]); + } + for (int i = 0; i < fPlaybackChannels; i++) { + delete (fPlaybackRingBuffer[i]); + } delete[] fCaptureRingBuffer; delete[] fPlaybackRingBuffer; @@ -238,10 +246,11 @@ namespace Jack double ratio = 1; // TODO : done like this just to avoid crash when input only or output only... - if (fCaptureChannels > 0) + if (fCaptureChannels > 0) { ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); - else if (fPlaybackChannels > 0) + } else if (fPlaybackChannels > 0) { ratio = fPIControler.GetRatio(fPlaybackRingBuffer[0]->GetError() - delta_frames); + } #ifdef JACK_MONITOR if (fCaptureRingBuffer && fCaptureRingBuffer[0] != NULL) diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index bb79c75c..6b4cd3e6 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -49,7 +49,7 @@ namespace Jack Measure fTable[TABLE_MAX]; int fCount; - MeasureTable() :fCount ( 0 ) + MeasureTable() :fCount(0) {} void Write(int time1, int time2, float r1, float r2, int pos1, int pos2); @@ -102,13 +102,13 @@ namespace Jack public: - JackAudioAdapterInterface ( jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE): - fCaptureChannels ( 0 ), - fPlaybackChannels ( 0 ), - fHostBufferSize ( buffer_size ), - fHostSampleRate ( sample_rate ), - fAdaptedBufferSize ( buffer_size), - fAdaptedSampleRate ( sample_rate ), + JackAudioAdapterInterface(jack_nframes_t buffer_size, jack_nframes_t sample_rate, jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE): + fCaptureChannels(0), + fPlaybackChannels(0), + fHostBufferSize(buffer_size), + fHostSampleRate(sample_rate), + fAdaptedBufferSize(buffer_size), + fAdaptedSampleRate(sample_rate), fPIControler(sample_rate / sample_rate, 256), fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), fQuality(0), @@ -117,23 +117,23 @@ namespace Jack fRunning(false), fAdaptative(true) {} - JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, + JackAudioAdapterInterface(jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, jack_nframes_t adapted_buffer_size, jack_nframes_t adapted_sample_rate, - jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE ) : - fCaptureChannels ( 0 ), - fPlaybackChannels ( 0 ), - fHostBufferSize ( host_buffer_size ), - fHostSampleRate ( host_sample_rate ), - fAdaptedBufferSize ( adapted_buffer_size), - fAdaptedSampleRate ( adapted_sample_rate ), - fPIControler(host_sample_rate / host_sample_rate, 256), - fQuality(0), - fRingbufferCurSize(ring_buffer_size), - fPullAndPushTime(0), - fRunning(false), - fAdaptative(true) + jack_nframes_t ring_buffer_size = DEFAULT_ADAPTATIVE_SIZE) : + fCaptureChannels(0), + fPlaybackChannels(0), + fHostBufferSize(host_buffer_size), + fHostSampleRate(host_sample_rate), + fAdaptedBufferSize(adapted_buffer_size), + fAdaptedSampleRate(adapted_sample_rate), + fPIControler(host_sample_rate / host_sample_rate, 256), + fQuality(0), + fRingbufferCurSize(ring_buffer_size), + fPullAndPushTime(0), + fRunning(false), + fAdaptative(true) {} virtual ~JackAudioAdapterInterface() @@ -154,59 +154,61 @@ namespace Jack return 0; } - virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) + virtual int SetHostBufferSize(jack_nframes_t buffer_size) { fHostBufferSize = buffer_size; - if (fAdaptative) + if (fAdaptative) { AdaptRingBufferSize(); + } return 0; } - virtual int SetAdaptedBufferSize ( jack_nframes_t buffer_size ) + virtual int SetAdaptedBufferSize(jack_nframes_t buffer_size) { fAdaptedBufferSize = buffer_size; - if (fAdaptative) + if (fAdaptative) { AdaptRingBufferSize(); + } return 0; } - virtual int SetBufferSize ( jack_nframes_t buffer_size ) + virtual int SetBufferSize(jack_nframes_t buffer_size) { - SetHostBufferSize ( buffer_size ); - SetAdaptedBufferSize ( buffer_size ); + SetHostBufferSize(buffer_size); + SetAdaptedBufferSize(buffer_size); return 0; } - virtual int SetHostSampleRate ( jack_nframes_t sample_rate ) + virtual int SetHostSampleRate(jack_nframes_t sample_rate) { fHostSampleRate = sample_rate; fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } - virtual int SetAdaptedSampleRate ( jack_nframes_t sample_rate ) + virtual int SetAdaptedSampleRate(jack_nframes_t sample_rate) { fAdaptedSampleRate = sample_rate; fPIControler.Init(double(fHostSampleRate) / double(fAdaptedSampleRate)); return 0; } - virtual int SetSampleRate ( jack_nframes_t sample_rate ) + virtual int SetSampleRate(jack_nframes_t sample_rate) { - SetHostSampleRate ( sample_rate ); - SetAdaptedSampleRate ( sample_rate ); + SetHostSampleRate(sample_rate); + SetAdaptedSampleRate(sample_rate); return 0; } - void SetInputs ( int inputs ) + void SetInputs(int inputs) { - jack_log ( "JackAudioAdapterInterface::SetInputs %d", inputs ); + jack_log("JackAudioAdapterInterface::SetInputs %d", inputs); fCaptureChannels = inputs; } - void SetOutputs ( int outputs ) + void SetOutputs(int outputs) { - jack_log ( "JackAudioAdapterInterface::SetOutputs %d", outputs ); + jack_log("JackAudioAdapterInterface::SetOutputs %d", outputs); fPlaybackChannels = outputs; } @@ -222,6 +224,9 @@ namespace Jack return fPlaybackChannels; } + virtual int GetInputLatency(int port_index) { return 0; } + virtual int GetOutputLatency(int port_index) { return 0; } + int PushAndPull(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); int PullAndPush(jack_default_audio_sample_t** inputBuffer, jack_default_audio_sample_t** outputBuffer, unsigned int frames); diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 9d0cda32..9d58658e 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -50,8 +50,9 @@ int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size) fEngineControl->fBufferSize = buffer_size; fGraphManager->SetBufferSize(buffer_size); fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec - if (!fEngineControl->fTimeOut) + if (!fEngineControl->fTimeOut) { fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); + } UpdateLatencies(); @@ -63,8 +64,9 @@ int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate) { fEngineControl->fSampleRate = sample_rate; fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec - if (!fEngineControl->fTimeOut) + if (!fEngineControl->fTimeOut) { fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); + } return JackDriver::SetSampleRate(sample_rate); } @@ -87,7 +89,8 @@ int JackAudioDriver::Open(jack_nframes_t buffer_size, memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); - return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); + return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, + monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } int JackAudioDriver::Open(bool capturing, @@ -106,26 +109,32 @@ int JackAudioDriver::Open(bool capturing, memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); - return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); + return JackDriver::Open(capturing, playing, inchannels, outchannels, + monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } void JackAudioDriver::UpdateLatencies() { - jack_latency_range_t range; + jack_latency_range_t input_range; + jack_latency_range_t output_range; + jack_latency_range_t monitor_range; for (int i = 0; i < fCaptureChannels; i++) { - range.max = range.min = fEngineControl->fBufferSize; - fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); + input_range.max = input_range.min = fEngineControl->fBufferSize + fCaptureLatency; + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); } for (int i = 0; i < fPlaybackChannels; i++) { - if (! fEngineControl->fSyncMode) { - range.max = range.min = fEngineControl->fBufferSize * 2; + output_range.max = output_range.min = fPlaybackLatency; + if (fEngineControl->fSyncMode) { + output_range.max = output_range.min += fEngineControl->fBufferSize; + } else { + output_range.max = output_range.min += fEngineControl->fBufferSize * 2; } - fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); if (fWithMonitorPorts) { - range.min = range.max = fEngineControl->fBufferSize; - fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range); + monitor_range.min = monitor_range.max = fEngineControl->fBufferSize; + fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); } } } @@ -220,6 +229,16 @@ int JackAudioDriver::Process() return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); } +void JackAudioDriver::ProcessGraphAsync() +{ + // Process graph + if (fIsMaster) { + ProcessGraphAsyncMaster(); + } else { + ProcessGraphAsyncSlave(); + } +} + /* The driver ASYNC mode: output buffers computed at the *previous cycle* are used, the server does not synchronize to the end of client graph execution. @@ -240,17 +259,30 @@ int JackAudioDriver::ProcessAsync() } // Process graph - if (fIsMaster) { - ProcessGraphAsyncMaster(); - } else { - ProcessGraphAsyncSlave(); - } + ProcessGraphAsync(); // Keep end cycle time JackDriver::CycleTakeEndTime(); return 0; } +void JackAudioDriver::ProcessGraphSync() +{ + // Process graph + if (fIsMaster) { + if (ProcessGraphSyncMaster() < 0) { + //jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); + //goto end; + } + } else { + if (ProcessGraphSyncSlave() < 0) { + //jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); + //goto end; + } + } +} + + /* The driver SYNC mode: the server does synchronize to the end of client graph execution, if graph process succeed, output buffers computed at the *current cycle* are used. @@ -265,17 +297,7 @@ int JackAudioDriver::ProcessSync() } // Process graph - if (fIsMaster) { - if (ProcessGraphSyncMaster() < 0) { - //jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); - //goto end; - } - } else { - if (ProcessGraphSyncSlave() < 0) { - //jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); - //goto end; - } - } + ProcessGraphSync(); // Write output buffers from the current cycle if (Write() < 0) { @@ -283,8 +305,6 @@ int JackAudioDriver::ProcessSync() return -1; } -end: - // Keep end cycle time JackDriver::CycleTakeEndTime(); return 0; @@ -371,34 +391,24 @@ int JackAudioDriver::Stop() return res; } -/* -void JackAudioDriver::WaitUntilNextCycle() -{ - int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f)); - wait_time_usec = int(wait_time_usec - (GetMicroSeconds() - fBeginDateUst)); - if (wait_time_usec > 0) - JackSleep(wait_time_usec); -} -*/ - -jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index, bool nulled) +jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) { return fCapturePortList[port_index] - ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize, nulled) + ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize) : NULL; } -jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index, bool nulled) +jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index) { return fPlaybackPortList[port_index] - ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize, nulled) + ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize) : NULL; } -jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index, bool nulled) +jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) { return fPlaybackPortList[port_index] - ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize, nulled) + ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize) : NULL; } diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 42ccb22d..f064aeb1 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -35,15 +35,6 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver protected: - void ProcessGraphAsyncMaster(); - void ProcessGraphAsyncSlave(); - - int ProcessGraphSyncMaster(); - int ProcessGraphSyncSlave(); - - virtual int ProcessAsync(); - virtual int ProcessSync(); - int fCaptureChannels; int fPlaybackChannels; @@ -57,12 +48,22 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver std::list<std::pair<std::string, std::string> > fConnections; // Connections list - jack_default_audio_sample_t* GetInputBuffer(int port_index, bool nulled = false); - jack_default_audio_sample_t* GetOutputBuffer(int port_index, bool nulled = false); - jack_default_audio_sample_t* GetMonitorBuffer(int port_index, bool nulled = false); + jack_default_audio_sample_t* GetInputBuffer(int port_index); + jack_default_audio_sample_t* GetOutputBuffer(int port_index); + jack_default_audio_sample_t* GetMonitorBuffer(int port_index); void HandleLatencyCallback(int status); - void UpdateLatencies(); + virtual void UpdateLatencies(); + + int ProcessAsync(); + void ProcessGraphAsync(); + void ProcessGraphAsyncMaster(); + void ProcessGraphAsyncSlave(); + + int ProcessSync(); + void ProcessGraphSync(); + int ProcessGraphSyncMaster(); + int ProcessGraphSyncSlave(); public: diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index b81cdb48..945f0e2c 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -124,8 +124,9 @@ int JackDriver::Open(bool capturing, strcpy(fPlaybackDriverName, playback_driver_name); fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec - if (!fEngineControl->fTimeOut) + if (!fEngineControl->fTimeOut) { fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); + } fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode SetupDriverSync(fClientControl.fRefNum, false); @@ -177,8 +178,9 @@ int JackDriver::Open(jack_nframes_t buffer_size, strcpy(fPlaybackDriverName, playback_driver_name); fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec - if (!fEngineControl->fTimeOut) + if (!fEngineControl->fTimeOut) { fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); + } fGraphManager->SetBufferSize(buffer_size); fGraphManager->DirectConnect(fClientControl.fRefNum, fClientControl.fRefNum); // Connect driver to itself for "sync" mode @@ -309,9 +311,9 @@ int JackDriver::ProcessReadSlaves() list<JackDriverInterface*>::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; - if (slave->ProcessRead() < 0) + if (slave->ProcessRead() < 0) { res = -1; - + } } return res; } @@ -322,9 +324,9 @@ int JackDriver::ProcessWriteSlaves() list<JackDriverInterface*>::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; - if (slave->ProcessWrite() < 0) + if (slave->ProcessWrite() < 0) { res = -1; - + } } return res; } @@ -387,10 +389,8 @@ int JackDriver::StartSlaves() JackDriverInterface* slave = *it; if (slave->Start() < 0) { res = -1; - // XXX: We should attempt to stop all of the slaves that we've // started here. - break; } } @@ -403,8 +403,9 @@ int JackDriver::StopSlaves() list<JackDriverInterface*>::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; - if (slave->Stop() < 0) + if (slave->Stop() < 0) { res = -1; + } } return res; } @@ -417,14 +418,13 @@ bool JackDriver::IsFixedBufferSize() int JackDriver::SetBufferSize(jack_nframes_t buffer_size) { int res = 0; - list<JackDriverInterface*>::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; - if (slave->SetBufferSize(buffer_size) < 0) + if (slave->SetBufferSize(buffer_size) < 0) { res = -1; + } } - return res; } @@ -434,8 +434,9 @@ int JackDriver::SetSampleRate(jack_nframes_t sample_rate) list<JackDriverInterface*>::const_iterator it; for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { JackDriverInterface* slave = *it; - if (slave->SetSampleRate(sample_rate) < 0) + if (slave->SetSampleRate(sample_rate) < 0) { res = -1; + } } return res; } @@ -445,5 +446,4 @@ bool JackDriver::Initialize() return true; } - } // end of namespace diff --git a/common/JackDriverLoader.cpp b/common/JackDriverLoader.cpp index 3f7d9283..dd06b767 100644 --- a/common/JackDriverLoader.cpp +++ b/common/JackDriverLoader.cpp @@ -31,7 +31,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include <dirent.h> #endif -jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver_t * driver); +jack_driver_desc_t* jackctl_driver_get_desc(jackctl_driver_t * driver); SERVER_EXPORT void jack_print_driver_options(jack_driver_desc_t* desc, FILE* file) { @@ -50,17 +50,18 @@ SERVER_EXPORT void jack_print_driver_options(jack_driver_desc_t* desc, FILE* fil sprintf (arg_default, "%c", desc->params[i].value.c); break; case JackDriverParamString: - if (desc->params[i].value.str && strcmp (desc->params[i].value.str, "") != 0) + if (desc->params[i].value.str && strcmp (desc->params[i].value.str, "") != 0) { sprintf (arg_default, "%s", desc->params[i].value.str); - else + } else { sprintf (arg_default, "none"); + } break; case JackDriverParamBool: sprintf (arg_default, "%s", desc->params[i].value.i ? "true" : "false"); break; } - fprintf (file, "\t-%c, --%s \t%s (default: %s)\n", + fprintf(file, "\t-%c, --%s \t%s (default: %s)\n", desc->params[i].character, desc->params[i].name, desc->params[i].long_desc, @@ -69,7 +70,7 @@ SERVER_EXPORT void jack_print_driver_options(jack_driver_desc_t* desc, FILE* fil } static void -jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file) +jack_print_driver_param_usage (jack_driver_desc_t* desc, unsigned long param, FILE *file) { fprintf (file, "Usage information for the '%s' parameter for driver '%s':\n", desc->params[param].name, desc->name); @@ -78,8 +79,8 @@ jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, F SERVER_EXPORT void jack_free_driver_params(JSList * driver_params) { - JSList *node_ptr = driver_params; - JSList *next_node_ptr; + JSList*node_ptr = driver_params; + JSList*next_node_ptr; while (node_ptr) { next_node_ptr = node_ptr->next; @@ -90,14 +91,14 @@ SERVER_EXPORT void jack_free_driver_params(JSList * driver_params) } SERVER_EXPORT int -jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr) +jack_parse_driver_params(jack_driver_desc_t* desc, int argc, char* argv[], JSList** param_ptr) { struct option * long_options; - char * options, * options_ptr; + char* options, * options_ptr; unsigned long i; int opt; unsigned int param_index; - JSList * params = NULL; + JSList* params = NULL; jack_driver_param_t * driver_param; if (argc <= 1) { @@ -192,11 +193,8 @@ jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSLi strcasecmp("0", optarg) == 0 || strcasecmp("(null)", optarg) == 0 ) { driver_param->value.i = false; - } else { - driver_param->value.i = true; - } break; } @@ -214,31 +212,33 @@ jack_parse_driver_params(jack_driver_desc_t * desc, int argc, char* argv[], JSLi free (options); free (long_options); - if (param_ptr) + if (param_ptr) { *param_ptr = params; - + } return 0; } SERVER_EXPORT int jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[]) { - struct option * long_options; - char * options, * options_ptr; + struct option* long_options; + char* options, * options_ptr; unsigned long i; int opt; - JSList * node_ptr; + JSList* node_ptr; jackctl_parameter_t * param = NULL; union jackctl_parameter_value value; - if (argc <= 1) + if (argc <= 1) { return 0; + } - const JSList * driver_params = jackctl_driver_get_parameters(driver_ptr); - if (driver_params == NULL) + const JSList* driver_params = jackctl_driver_get_parameters(driver_ptr); + if (driver_params == NULL) { return 1; + } - jack_driver_desc_t * desc = jackctl_driver_get_desc(driver_ptr); + jack_driver_desc_t* desc = jackctl_driver_get_desc(driver_ptr); /* check for help */ if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { @@ -352,14 +352,14 @@ jackctl_parse_driver_params(jackctl_driver *driver_ptr, int argc, char* argv[]) return 0; } -jack_driver_desc_t * -jack_find_driver_descriptor (JSList * drivers, const char * name) +jack_driver_desc_t* +jack_find_driver_descriptor (JSList * drivers, const char* name) { - jack_driver_desc_t * desc = 0; - JSList * node; + jack_driver_desc_t* desc = 0; + JSList* node; for (node = drivers; node; node = jack_slist_next (node)) { - desc = (jack_driver_desc_t *) node->data; + desc = (jack_driver_desc_t*) node->data; if (strcmp (desc->name, name) != 0) { desc = NULL; @@ -371,18 +371,18 @@ jack_find_driver_descriptor (JSList * drivers, const char * name) return desc; } -static jack_driver_desc_t * -jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) +static jack_driver_desc_t* +jack_get_descriptor (JSList * drivers, const char* sofile, const char* symbol) { - jack_driver_desc_t * descriptor, * other_descriptor; + jack_driver_desc_t* descriptor, * other_descriptor; JackDriverDescFunction so_get_descriptor = NULL; - JSList * node; + JSList* node; void * dlhandle; - char * filename; + char* filename; #ifdef WIN32 int dlerr; #else - const char * dlerr; + const char* dlerr; #endif int err; @@ -410,7 +410,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) #endif } - filename = (char *)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1); + filename = (char*)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1); sprintf (filename, "%s/%s", driver_dir, sofile); if ((dlhandle = LoadDriverModule(filename)) == NULL) { @@ -458,7 +458,7 @@ jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) /* check it doesn't exist already */ for (node = drivers; node; node = jack_slist_next (node)) { - other_descriptor = (jack_driver_desc_t *) node->data; + other_descriptor = (jack_driver_desc_t*) node->data; if (strcmp(descriptor->name, other_descriptor->name) == 0) { jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first", @@ -502,7 +502,7 @@ static bool check_symbol(const char* sofile, const char* symbol) #endif } - char* filename = (char *)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1); + char* filename = (char*)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1); sprintf (filename, "%s/%s", driver_dir, sofile); if ((dlhandle = LoadDriverModule(filename)) == NULL) { @@ -524,14 +524,14 @@ static bool check_symbol(const char* sofile, const char* symbol) JSList * jack_drivers_load (JSList * drivers) { - char * driver_dir; + char* driver_dir; char driver_dir_storage[512]; char dll_filename[512]; WIN32_FIND_DATA filedata; HANDLE file; - const char * ptr = NULL; - JSList * driver_list = NULL; - jack_driver_desc_t * desc = NULL; + const char* ptr = NULL; + JSList* driver_list = NULL; + jack_driver_desc_t* desc = NULL; if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { // for WIN32 ADDON_DIR is defined in JackConstants.h as relative path @@ -601,10 +601,10 @@ JSList * jack_drivers_load (JSList * drivers) { struct dirent * dir_entry; DIR * dir_stream; - const char * ptr; + const char* ptr; int err; - JSList * driver_list = NULL; - jack_driver_desc_t * desc = NULL; + JSList* driver_list = NULL; + jack_driver_desc_t* desc = NULL; const char* driver_dir; if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { @@ -669,14 +669,14 @@ jack_drivers_load (JSList * drivers) { JSList * jack_internals_load (JSList * internals) { - char * driver_dir; + char* driver_dir; char driver_dir_storage[512]; char dll_filename[512]; WIN32_FIND_DATA filedata; HANDLE file; - const char * ptr = NULL; - JSList * driver_list = NULL; - jack_driver_desc_t * desc; + const char* ptr = NULL; + JSList* driver_list = NULL; + jack_driver_desc_t* desc; if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { // for WIN32 ADDON_DIR is defined in JackConstants.h as relative path @@ -742,10 +742,10 @@ JSList * jack_internals_load (JSList * internals) { struct dirent * dir_entry; DIR * dir_stream; - const char * ptr; + const char* ptr; int err; - JSList * driver_list = NULL; - jack_driver_desc_t * desc; + JSList* driver_list = NULL; + jack_driver_desc_t* desc; const char* driver_dir; if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { @@ -809,7 +809,7 @@ Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver #ifdef WIN32 int errstr; #else - const char * errstr; + const char* errstr; #endif fHandle = LoadDriverModule (driver_desc->file); @@ -852,7 +852,7 @@ JackDriverInfo::~JackDriverInfo() } SERVER_EXPORT -jack_driver_desc_t * +jack_driver_desc_t* jack_driver_descriptor_construct( const char * name, jack_driver_type_t type, @@ -861,7 +861,7 @@ jack_driver_descriptor_construct( { size_t name_len; size_t description_len; - jack_driver_desc_t * desc_ptr; + jack_driver_desc_t* desc_ptr; name_len = strlen(name); description_len = strlen(description); @@ -894,15 +894,15 @@ jack_driver_descriptor_construct( SERVER_EXPORT int jack_driver_descriptor_add_parameter( - jack_driver_desc_t * desc_ptr, + jack_driver_desc_t* desc_ptr, jack_driver_desc_filler_t * filler_ptr, - const char * name, + const char* name, char character, jack_driver_param_type_t type, const jack_driver_param_value_t * value_ptr, jack_driver_param_constraint_desc_t * constraint, - const char * short_desc, - const char * long_desc) + const char* short_desc, + const char* long_desc) { size_t name_len; size_t short_desc_len; diff --git a/common/JackDriverLoader.h b/common/JackDriverLoader.h index fafe5f57..cd4bfe44 100644 --- a/common/JackDriverLoader.h +++ b/common/JackDriverLoader.h @@ -27,7 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackDriver.h" #include "JackSystemDeps.h" -typedef jack_driver_desc_t * (*JackDriverDescFunction) (); +typedef jack_driver_desc_t* (*JackDriverDescFunction) (); typedef Jack::JackDriverClientInterface* (*driverInitialize) (Jack::JackLockedEngine*, Jack::JackSynchro*, const JSList*); class SERVER_EXPORT JackDriverInfo @@ -54,10 +54,10 @@ class SERVER_EXPORT JackDriverInfo }; -jack_driver_desc_t * jack_find_driver_descriptor(JSList * drivers, const char * name); +jack_driver_desc_t* jack_find_driver_descriptor(JSList* drivers, const char* name); -JSList * jack_drivers_load(JSList * drivers); -JSList * jack_internals_load(JSList * internals); +JSList* jack_drivers_load(JSList* drivers); +JSList* jack_internals_load(JSList* internals); #ifdef __cplusplus extern "C" diff --git a/common/JackDummyDriver.h b/common/JackDummyDriver.h index 284b026b..5bab9836 100644 --- a/common/JackDummyDriver.h +++ b/common/JackDummyDriver.h @@ -32,7 +32,7 @@ namespace Jack class JackDummyDriver : public JackTimedDriver { - + public: JackDummyDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) @@ -41,6 +41,18 @@ class JackDummyDriver : public JackTimedDriver virtual ~JackDummyDriver() {} + virtual int Process() + { + JackDriver::CycleTakeBeginTime(); + + if (JackAudioDriver::Process() < 0) { + return -1; + } else { + ProcessWait(); + return 0; + } + } + }; } // end of namespace diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 18949105..1f7ab5bc 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -166,7 +166,7 @@ bool JackGraphManager::IsDirectConnection(int ref1, int ref2) } // RT -void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buffer_size, bool nulled) +void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buffer_size) { AssertPort(port_index); AssertBufferSize(buffer_size); @@ -184,17 +184,13 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff // Output port if (port->fFlags & JackPortIsOutput) { - if (port->fTied != NO_PORT) { - return GetBuffer(port->fTied, buffer_size); - } else { - return (len == 0 && nulled) ? NULL : GetBuffer(port_index); - } - } + return (port->fTied != NO_PORT) ? GetBuffer(port->fTied, buffer_size) : GetBuffer(port_index); + } // No connections : return a zero-filled buffer if (len == 0) { port->ClearBuffer(buffer_size); - return (nulled) ? NULL : port->GetBuffer(); + return port->GetBuffer(); // One connection } else if (len == 1) { diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 65abcbf2..15f0275f 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -114,7 +114,7 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState int GetOutputRefNum(jack_port_id_t port_index); // Buffer management - void* GetBuffer(jack_port_id_t port_index, jack_nframes_t frames, bool nulled = false); + void* GetBuffer(jack_port_id_t port_index, jack_nframes_t frames); // Activation management void RunCurrentGraph(); diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index 4213a731..27e36b5e 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -58,8 +58,9 @@ JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) int error; fResampler = src_new(quality, 1, &error); - if (error != 0) + if (error != 0) { jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); + } } JackLibSampleRateResampler::~JackLibSampleRateResampler() diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index 47866647..b6234558 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -110,16 +110,6 @@ int JackMidiDriver::Detach() return 0; } -int JackMidiDriver::Read() -{ - return 0; -} - -int JackMidiDriver::Write() -{ - return 0; -} - void JackMidiDriver::UpdateLatencies() { jack_latency_range_t range; diff --git a/common/JackMidiDriver.h b/common/JackMidiDriver.h index 3e35ec08..347aef22 100644 --- a/common/JackMidiDriver.h +++ b/common/JackMidiDriver.h @@ -77,9 +77,6 @@ class SERVER_EXPORT JackMidiDriver : public JackDriver virtual int Attach(); virtual int Detach(); - virtual int Read(); - virtual int Write(); - }; } // end of namespace diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 4a7c40ee..6ebc32f4 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -166,36 +166,36 @@ struct JackNetExtMaster : public JackNetMasterInterface { { // Init socket API (win32) if (SocketAPIInit() < 0) { - fprintf(stderr, "Can't init Socket API, exiting...\n"); + jack_error("Can't init Socket API, exiting..."); return -1; } // Request socket if (fSocket.NewSocket() == SOCKET_ERROR) { - fprintf(stderr, "Can't create the network management input socket : %s\n", StrError(NET_ERROR_CODE)); + jack_error("Can't create the network management input socket : %s", StrError(NET_ERROR_CODE)); return -1; } // Bind the socket to the local port if (fSocket.Bind() == SOCKET_ERROR) { - fprintf(stderr, "Can't bind the network manager socket : %s\n", StrError(NET_ERROR_CODE)); + jack_error("Can't bind the network manager socket : %s", StrError(NET_ERROR_CODE)); fSocket.Close(); return -1; } // Join multicast group if (fSocket.JoinMCastGroup(fMulticastIP) == SOCKET_ERROR) { - fprintf(stderr, "Can't join multicast group : %s\n", StrError(NET_ERROR_CODE)); + jack_error("Can't join multicast group : %s", StrError(NET_ERROR_CODE)); } // Local loop if (fSocket.SetLocalLoop() == SOCKET_ERROR) { - fprintf(stderr, "Can't set local loop : %s\n", StrError(NET_ERROR_CODE)); + jack_error("Can't set local loop : %s", StrError(NET_ERROR_CODE)); } // Set a timeout on the multicast receive (the thread can now be cancelled) if (fSocket.SetTimeOut(MANAGER_INIT_TIMEOUT) == SOCKET_ERROR) { - fprintf(stderr, "Can't set timeout : %s\n", StrError(NET_ERROR_CODE)); + jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); } // Main loop, wait for data, deal with it and wait again @@ -209,9 +209,9 @@ struct JackNetExtMaster : public JackNetMasterInterface { SessionParamsNToH(&net_params, &fParams); if ((rx_bytes == SOCKET_ERROR) && (fSocket.GetError() != NET_NO_DATA)) { - fprintf(stderr, "Error in receive : %s\n", StrError(NET_ERROR_CODE)); + jack_error("Error in receive : %s", StrError(NET_ERROR_CODE)); if (++attempt == 10) { - fprintf(stderr, "Can't receive on the socket, exiting net manager.\n" ); + jack_error("Can't receive on the socket, exiting net manager" ); goto error; } } @@ -225,10 +225,10 @@ struct JackNetExtMaster : public JackNetMasterInterface { SessionParamsDisplay(&fParams); fRunning = false; } else { - fprintf(stderr, "Can't init new net master...\n"); + jack_error("Can't init new net master..."); goto error; } - jack_info ( "Waiting for a slave..." ); + jack_info("Waiting for a slave..."); break; case KILL_MASTER: @@ -259,7 +259,7 @@ struct JackNetExtMaster : public JackNetMasterInterface { { // Check MASTER <==> SLAVE network protocol coherency if (fParams.fProtocolVersion != MASTER_PROTOCOL) { - fprintf(stderr, "Error : slave is running with a different protocol %s\n", fParams.fName); + jack_error("Error : slave is running with a different protocol %s", fParams.fName); return -1; } @@ -465,7 +465,6 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf // Request parameters assert(strlen(ip) < 32); strcpy(fMulticastIP, ip); - fParams.fMtu = request->mtu; fParams.fTransportSync = 0; fParams.fSendAudioChannels = request->audio_input; @@ -494,17 +493,25 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Open(jack_master_t* result) { if (fParams.fNetworkLatency > NETWORK_MAX_LATENCY) { - printf("Error : network latency is limited to %d\n", NETWORK_MAX_LATENCY); + jack_error("Error : network latency is limited to %d", NETWORK_MAX_LATENCY); return -1; } // Init network connection if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) { + jack_error("Initing network fails..."); + return -1; + } + + // Finish connection... + if (!JackNetSlaveInterface::InitRendering()) { + jack_error("Starting network fails..."); return -1; } // Then set global parameters if (!SetParams()) { + jack_error("SetParams error..."); return -1; } @@ -532,11 +539,19 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf // Init network connection if (!JackNetSlaveInterface::InitConnection(fConnectTimeOut)) { + jack_error("Initing network fails..."); + return -1; + } + + // Finish connection... + if (!JackNetSlaveInterface::InitRendering()) { + jack_error("Starting network fails..."); return -1; } // Then set global parameters if (!SetParams()) { + jack_error("SetParams error..."); return -1; } @@ -630,8 +645,8 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf { // Will do "something" on OSX only... UInt64 period, constraint; - period = constraint = float(fParams.fPeriodSize) / float(fParams.fSampleRate) * 1000000; - UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize); + period = constraint = UInt64(1000000000.f * (float(fParams.fPeriodSize) / float(fParams.fSampleRate))); + UInt64 computation = JackTools::ComputationMicroSec(fParams.fPeriodSize) * 1000; fThread.SetParams(period, computation, constraint); return (fThread.AcquireRealTime(80) == 0); // TODO: get a value from the server @@ -713,11 +728,6 @@ struct JackNetExtSlave : public JackNetSlaveInterface, public JackRunnableInterf int Start() { - // Finish connection... - if (!JackNetSlaveInterface::InitRendering()) { - return -1; - } - return (fProcessCallback == 0) ? -1 : fThread.StartSync(); } @@ -974,7 +984,8 @@ SERVER_EXPORT int jack_adapter_pull_and_push(jack_adapter_t* adapter, float** in } -#ifdef MY_TARGET_OS_IPHONE +//#ifdef MY_TARGET_OS_IPHONE +#if 1 static void jack_format_and_log(int level, const char *prefix, const char *fmt, va_list ap) { @@ -1031,3 +1042,4 @@ SERVER_EXPORT void jack_log(const char *fmt, ...) {} #endif + diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index 60de93b9..a41ada28 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -35,9 +35,8 @@ namespace Jack because we don't have full parametering right now, parameters will be parsed from the param list, and then JackNetSlaveInterface will be filled with proper values. */ - - strcpy(fMulticastIP, DEFAULT_MULTICAST_IP); - uint port = DEFAULT_PORT; + char multicast_ip[32]; + uint udp_port; GetHostName(fParams.fName, JACK_CLIENT_NAME_SIZE); fSocket.GetName(fParams.fSlaveNetName); fParams.fMtu = DEFAULT_MTU; @@ -52,7 +51,18 @@ namespace Jack fParams.fSlaveSyncMode = 1; fParams.fNetworkLatency = 2; fParams.fSampleEncoder = JackFloatEncoder; - fJackClient = jack_client; + fClient = jack_client; + + // Possibly use env variable + const char* default_udp_port = getenv("JACK_NETJACK_PORT"); + udp_port = (default_udp_port) ? atoi(default_udp_port) : DEFAULT_PORT; + + const char* default_multicast_ip = getenv("JACK_NETJACK_MULTICAST"); + if (default_multicast_ip) { + strcpy(multicast_ip, default_multicast_ip); + } else { + strcpy(multicast_ip, DEFAULT_MULTICAST_IP); + } //options parsing const JSList* node; @@ -63,14 +73,11 @@ namespace Jack switch (param->character) { case 'a' : - if (strlen(param->value.str) < 32) { - strcpy(fMulticastIP, param->value.str); - } else { - jack_error("Can't use multicast address %s, using default %s", param->value.ui, DEFAULT_MULTICAST_IP); - } + assert(strlen(param->value.str) < 32); + strcpy(multicast_ip, param->value.str); break; case 'p' : - fSocket.SetPort(param->value.ui); + udp_port = param->value.ui; break; case 'M' : fParams.fMtu = param->value.i; @@ -85,7 +92,7 @@ namespace Jack strncpy(fParams.fName, param->value.str, JACK_CLIENT_NAME_SIZE); break; case 't' : - //fParams.fTransportSync = param->value.ui; + fParams.fTransportSync = param->value.ui; break; #if HAVE_CELT case 'c': @@ -112,9 +119,11 @@ namespace Jack } } + strcpy(fMulticastIP, multicast_ip); + // Set the socket parameters - fSocket.SetPort(port); - fSocket.SetAddress(fMulticastIP, port); + fSocket.SetPort(udp_port); + fSocket.SetAddress(fMulticastIP, udp_port); // If not set, takes default fParams.fSendAudioChannels = (send_audio == -1) ? 2 : send_audio; @@ -136,13 +145,15 @@ namespace Jack jack_log("JackNetAdapter::~JackNetAdapter"); if (fSoftCaptureBuffer) { - for (int port_index = 0; port_index < fCaptureChannels; port_index++) + for (int port_index = 0; port_index < fCaptureChannels; port_index++) { delete[] fSoftCaptureBuffer[port_index]; + } delete[] fSoftCaptureBuffer; } if (fSoftPlaybackBuffer) { - for (int port_index = 0; port_index < fPlaybackChannels; port_index++) + for (int port_index = 0; port_index < fPlaybackChannels; port_index++) { delete[] fSoftPlaybackBuffer[port_index]; + } delete[] fSoftPlaybackBuffer; } } @@ -244,8 +255,9 @@ namespace Jack try { // Keep running even in case of error while (fThread.GetStatus() == JackThread::kRunning) - if (Process() == SOCKET_ERROR) + if (Process() == SOCKET_ERROR) { return false; + } return false; } catch (JackNetException& e) { e.PrintMessage(); @@ -268,17 +280,17 @@ namespace Jack //TODO : we need here to get the actual timebase master to eventually release it from its duty (see JackNetDriver) //is there a new transport state ? - if (fSendTransportData.fNewState &&(fSendTransportData.fState != jack_transport_query(fJackClient, NULL))) { + if (fSendTransportData.fNewState &&(fSendTransportData.fState != jack_transport_query(fClient, NULL))) { switch (fSendTransportData.fState) { case JackTransportStopped : - jack_transport_stop(fJackClient); + jack_transport_stop(fClient); jack_info("NetMaster : transport stops"); break; case JackTransportStarting : - jack_transport_reposition(fJackClient, &fSendTransportData.fPosition); - jack_transport_start(fJackClient); + jack_transport_reposition(fClient, &fSendTransportData.fPosition); + jack_transport_start(fClient); jack_info("NetMaster : transport starts"); break; @@ -314,13 +326,14 @@ namespace Jack } //update transport state and position - fReturnTransportData.fState = jack_transport_query(fJackClient, &fReturnTransportData.fPosition); + fReturnTransportData.fState = jack_transport_query(fClient, &fReturnTransportData.fPosition); //is it a new state (that the master need to know...) ? fReturnTransportData.fNewState = ((fReturnTransportData.fState != fLastTransportState) && (fReturnTransportData.fState != fSendTransportData.fState)); - if (fReturnTransportData.fNewState) + if (fReturnTransportData.fNewState) { jack_info("Sending transport state '%s'.", GetTransportState(fReturnTransportData.fState)); + } fLastTransportState = fReturnTransportData.fState; } @@ -329,8 +342,9 @@ namespace Jack { //don't return -1 in case of sync recv failure //we need the process to continue for network error detection - if (SyncRecv() == SOCKET_ERROR) + if (SyncRecv() == SOCKET_ERROR) { return 0; + } DecodeSyncPacket(); return DataRecv(); @@ -340,8 +354,9 @@ namespace Jack { EncodeSyncPacket(); - if (SyncSend() == SOCKET_ERROR) + if (SyncSend() == SOCKET_ERROR) { return SOCKET_ERROR; + } return DataSend(); } @@ -351,15 +366,17 @@ namespace Jack { //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; + } 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; + } return 0; } @@ -386,10 +403,10 @@ extern "C" desc = jack_driver_descriptor_construct("netadapter", JackDriverNone, "netjack net <==> audio backend adapter", &filler); strcpy(value.str, DEFAULT_MULTICAST_IP); - jack_driver_descriptor_add_parameter(desc, &filler, "multicast_ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL); value.i = DEFAULT_PORT; - jack_driver_descriptor_add_parameter(desc, &filler, "udp_net_port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL); value.i = DEFAULT_MTU; jack_driver_descriptor_add_parameter(desc, &filler, "mtu", 'M', JackDriverParamInt, &value, NULL, "MTU to the master", NULL); @@ -406,7 +423,7 @@ extern "C" strcpy(value.str, "'hostname'"); jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL); - value.ui = 1U; + value.ui = 0U; jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL); value.ui = 5U; @@ -424,17 +441,17 @@ extern "C" return desc; } - SERVER_EXPORT int jack_internal_initialize(jack_client_t* jack_client, const JSList* params) + SERVER_EXPORT int jack_internal_initialize(jack_client_t* client, const JSList* params) { jack_log("Loading netadapter"); Jack::JackAudioAdapter* adapter; - jack_nframes_t buffer_size = jack_get_buffer_size(jack_client); - jack_nframes_t sample_rate = jack_get_sample_rate(jack_client); + jack_nframes_t buffer_size = jack_get_buffer_size(client); + jack_nframes_t sample_rate = jack_get_sample_rate(client); try { - adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackNetAdapter(jack_client, buffer_size, sample_rate, params), params, false); + adapter = new Jack::JackAudioAdapter(client, new Jack::JackNetAdapter(client, buffer_size, sample_rate, params), params); assert(adapter); if (adapter->Open() == 0) { @@ -458,8 +475,9 @@ extern "C" jack_driver_desc_t* desc = jack_get_descriptor(); Jack::JackArgParser parser(load_init); - if (parser.GetArgc() > 0) + if (parser.GetArgc() > 0) { parse_params = parser.ParseParams(desc, ¶ms); + } if (parse_params) { res = jack_internal_initialize(jack_client, params); diff --git a/common/JackNetAdapter.h b/common/JackNetAdapter.h index d76c8b1a..05de4632 100644 --- a/common/JackNetAdapter.h +++ b/common/JackNetAdapter.h @@ -38,7 +38,7 @@ namespace Jack private: //jack data - jack_client_t* fJackClient; + jack_client_t* fClient; //transport data int fLastTransportState; diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index 618d1a0b..b2240040 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -29,7 +29,7 @@ namespace Jack JackNetDriver::JackNetDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, const char* ip, int udp_port, int mtu, int midi_input_ports, int midi_output_ports, char* net_name, uint transport_sync, int network_latency, int celt_encoding) - : JackTimedDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port) + : JackWaiterDriver(name, alias, engine, table), JackNetSlaveInterface(ip, udp_port) { jack_log("JackNetDriver::JackNetDriver ip %s, port %d", ip, udp_port); @@ -46,6 +46,7 @@ namespace Jack fParams.fKBps = celt_encoding; } else { fParams.fSampleEncoder = JackFloatEncoder; + //fParams.fSampleEncoder = JackIntEncoder; } strcpy(fParams.fName, net_name); fSocket.GetName(fParams.fSlaveNetName); @@ -82,7 +83,7 @@ namespace Jack } #endif FreeAll(); - return JackTimedDriver::Close(); + return JackWaiterDriver::Close(); } // Attach and Detach are defined as empty methods: port allocation is done when driver actually start (that is in Init) @@ -104,7 +105,7 @@ namespace Jack bool JackNetDriver::Initialize() { - jack_log("JackNetDriver::Initialize()"); + jack_log("JackNetDriver::Initialize"); SaveConnections(); FreePorts(); @@ -233,22 +234,29 @@ namespace Jack { jack_log("JackNetDriver::AllocPorts fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); + /* + fNetAudioCaptureBuffer fNetAudioPlaybackBuffer + fSendAudioChannels fReturnAudioChannels + + fCapturePortList fPlaybackPortList + fCaptureChannels ==> SLAVE ==> fPlaybackChannels + "capture_" "playback_" + */ + JackPort* port; jack_port_id_t port_index; char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; - unsigned long port_flags; int audio_port_index; int midi_port_index; jack_latency_range_t range; //audio - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; for (audio_port_index = 0; audio_port_index < fCaptureChannels; audio_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, audio_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, audio_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, - static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { + CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -262,12 +270,11 @@ namespace Jack jack_log("JackNetDriver::AllocPorts() fCapturePortList[%d] audio_port_index = %ld fPortLatency = %ld", audio_port_index, port_index, port->GetLatency()); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for (audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, audio_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:playback_%d",fClientControl.fName, audio_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, - static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { + PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -282,12 +289,11 @@ namespace Jack } //midi - port_flags = JackPortIsOutput | JackPortIsPhysical | JackPortIsTerminal; for (midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, midi_port_index + 1); snprintf(name, sizeof (name) - 1, "%s:midi_capture_%d", fClientControl.fName, midi_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, - static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { + CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -300,12 +306,11 @@ namespace Jack jack_log("JackNetDriver::AllocPorts() fMidiCapturePortList[%d] midi_port_index = %ld fPortLatency = %ld", midi_port_index, port_index, port->GetLatency()); } - port_flags = JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal; for (midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, midi_port_index + 1); snprintf(name, sizeof(name) - 1, "%s:midi_playback_%d", fClientControl.fName, midi_port_index + 1); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, - static_cast<JackPortFlags>(port_flags), fEngineControl->fBufferSize, &port_index) < 0) { + PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { jack_error("driver: cannot register port for %s", name); return -1; } @@ -469,20 +474,20 @@ namespace Jack //driver processes-------------------------------------------------------------------- - int JackNetDriver::Process() - { - return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); - } - int JackNetDriver::Read() { //buffers for (int midi_port_index = 0; midi_port_index < fParams.fSendMidiChannels; midi_port_index++) { fNetMidiCaptureBuffer->SetBuffer(midi_port_index, GetMidiInputBuffer(midi_port_index)); } + for (int audio_port_index = 0; audio_port_index < fParams.fSendAudioChannels; audio_port_index++) { #ifdef OPTIMIZED_PROTOCOL - fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index, true)); + if (fGraphManager->GetConnectionsNum(fCapturePortList[audio_port_index]) > 0) { + fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index)); + } else { + fNetAudioCaptureBuffer->SetBuffer(audio_port_index, NULL); + } #else fNetAudioCaptureBuffer->SetBuffer(audio_port_index, GetInputBuffer(audio_port_index)); #endif @@ -507,7 +512,7 @@ namespace Jack DecodeSyncPacket(); #ifdef JACK_MONITOR - fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); + fNetTimeMon->Add((float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); #endif //audio, midi or sync if driver is late int res = DataRecv(); @@ -515,14 +520,14 @@ namespace Jack return SOCKET_ERROR; } else if (res == NET_PACKET_ERROR) { jack_time_t cur_time = GetMicroSeconds(); - NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... + NotifyXRun(cur_time, float(cur_time - fBeginDateUst)); // Better this value than nothing... } //take the time at the beginning of the cycle JackDriver::CycleTakeBeginTime(); #ifdef JACK_MONITOR - fNetTimeMon->Add(((float)(GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); + fNetTimeMon->Add((float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); #endif return 0; @@ -534,11 +539,16 @@ namespace Jack for (int midi_port_index = 0; midi_port_index < fParams.fReturnMidiChannels; midi_port_index++) { fNetMidiPlaybackBuffer->SetBuffer(midi_port_index, GetMidiOutputBuffer(midi_port_index)); } + for (int audio_port_index = 0; audio_port_index < fPlaybackChannels; audio_port_index++) { #ifdef OPTIMIZED_PROTOCOL // Port is connected on other side... if (fNetAudioPlaybackBuffer->GetConnected(audio_port_index)) { - fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index, true)); + if (fGraphManager->GetConnectionsNum(fPlaybackPortList[audio_port_index]) > 0) { + fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, GetOutputBuffer(audio_port_index)); + } else { + fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL); + } } else { fNetAudioPlaybackBuffer->SetBuffer(audio_port_index, NULL); } @@ -548,7 +558,7 @@ namespace Jack } #ifdef JACK_MONITOR - fNetTimeMon->Add(((float) (GetMicroSeconds() - fRcvSyncUst) / (float)fEngineControl->fPeriodUsecs) * 100.f); + fNetTimeMon->AddLast((float(GetMicroSeconds() - fRcvSyncUst) / float(fEngineControl->fPeriodUsecs) * 100.f); #endif //sync @@ -590,31 +600,31 @@ namespace Jack desc = jack_driver_descriptor_construct("net", JackDriverMaster, "netjack slave backend component", &filler); strcpy(value.str, DEFAULT_MULTICAST_IP); - jack_driver_descriptor_add_parameter(desc, &filler, "multicast_ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "multicast-ip", 'a', JackDriverParamString, &value, NULL, "Multicast Address", NULL); value.i = DEFAULT_PORT; - jack_driver_descriptor_add_parameter(desc, &filler, "udp_net_port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "udp-net-port", 'p', JackDriverParamInt, &value, NULL, "UDP port", NULL); value.i = DEFAULT_MTU; jack_driver_descriptor_add_parameter(desc, &filler, "mtu", 'M', JackDriverParamInt, &value, NULL, "MTU to the master", NULL); value.i = -1; - jack_driver_descriptor_add_parameter(desc, &filler, "input_ports", 'C', JackDriverParamInt, &value, NULL, "Number of audio input ports", "Number of audio input ports. If -1, audio physical input from the master"); - jack_driver_descriptor_add_parameter(desc, &filler, "output_ports", 'P', JackDriverParamInt, &value, NULL, "Number of audio output ports", "Number of audio output ports. If -1, audio physical output from the master"); + jack_driver_descriptor_add_parameter(desc, &filler, "input-ports", 'C', JackDriverParamInt, &value, NULL, "Number of audio input ports", "Number of audio input ports. If -1, audio physical input from the master"); + jack_driver_descriptor_add_parameter(desc, &filler, "output-ports", 'P', JackDriverParamInt, &value, NULL, "Number of audio output ports", "Number of audio output ports. If -1, audio physical output from the master"); value.i = 0; - jack_driver_descriptor_add_parameter(desc, &filler, "midi_in_ports", 'i', JackDriverParamInt, &value, NULL, "Number of midi input ports", NULL); - jack_driver_descriptor_add_parameter(desc, &filler, "midi_out_ports", 'o', JackDriverParamInt, &value, NULL, "Number of midi output ports", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "midi-in-ports", 'i', JackDriverParamInt, &value, NULL, "Number of midi input ports", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "midi-out-ports", 'o', JackDriverParamInt, &value, NULL, "Number of midi output ports", NULL); #if HAVE_CELT value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "celt", 'c', JackDriverParamInt, &value, NULL, "Set CELT encoding and number of kBits per channel", NULL); #endif strcpy(value.str, "'hostname'"); - jack_driver_descriptor_add_parameter(desc, &filler, "client_name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "client-name", 'n', JackDriverParamString, &value, NULL, "Name of the jack client", NULL); value.ui = 0U; - jack_driver_descriptor_add_parameter(desc, &filler, "transport_sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "transport-sync", 't', JackDriverParamUInt, &value, NULL, "Sync transport with master's", NULL); value.ui = 5U; jack_driver_descriptor_add_parameter(desc, &filler, "latency", 'l', JackDriverParamUInt, &value, NULL, "Network latency", NULL); @@ -624,13 +634,13 @@ namespace Jack SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { - char multicast_ip[16]; + char multicast_ip[32]; char net_name[JACK_CLIENT_NAME_SIZE + 1]; int udp_port; int mtu = DEFAULT_MTU; // Desactivated for now... uint transport_sync = 0; - jack_nframes_t period_size = 128; + jack_nframes_t period_size = 256; jack_nframes_t sample_rate = 48000; int audio_capture_ports = -1; int audio_playback_ports = -1; @@ -660,7 +670,8 @@ namespace Jack switch (param->character) { case 'a' : - strncpy(multicast_ip, param->value.str, 15); + assert(strlen(param->value.str) < 32); + strcpy(multicast_ip, param->value.str); break; case 'p': udp_port = param->value.ui; diff --git a/common/JackNetDriver.h b/common/JackNetDriver.h index 98f512ab..48a733bf 100644 --- a/common/JackNetDriver.h +++ b/common/JackNetDriver.h @@ -25,17 +25,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //#define JACK_MONITOR -#ifdef JACK_MONITOR -#include "JackFrameTimer.h" -#endif - namespace Jack { /** \Brief This class describes the Net Backend */ - class JackNetDriver : public JackTimedDriver, public JackNetSlaveInterface + class JackNetDriver : public JackWaiterDriver, public JackNetSlaveInterface { private: @@ -77,10 +73,7 @@ namespace Jack virtual ~JackNetDriver(); int Close(); - - // The - int Process(); - + int Attach(); int Detach(); diff --git a/common/JackNetOneDriver.cpp b/common/JackNetOneDriver.cpp index c0db768d..ca012864 100644 --- a/common/JackNetOneDriver.cpp +++ b/common/JackNetOneDriver.cpp @@ -50,7 +50,7 @@ JackNetOneDriver::JackNetOneDriver(const char* name, const char* alias, JackLock int sample_rate, int period_size, int resample_factor, const char* net_name, uint transport_sync, int bitdepth, int use_autoconfig, int latency, int redundancy, int dont_htonl_floats, int always_deadline, int jitter_val) - : JackTimedDriver(name, alias, engine, table) + : JackWaiterDriver(name, alias, engine, table) { jack_log("JackNetOneDriver::JackNetOneDriver port %d", port); @@ -91,7 +91,7 @@ JackNetOneDriver::~JackNetOneDriver() int JackNetOneDriver::Close() { // Generic audio driver close - int res = JackTimedDriver::Close(); + int res = JackWaiterDriver::Close(); FreePorts(); netjack_release(&netj); @@ -122,10 +122,10 @@ int JackNetOneDriver::AllocPorts() if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { - jack_error ( "driver: cannot register port for %s", buf ); + jack_error("driver: cannot register port for %s", buf); return -1; } - //port = fGraphManager->GetPort ( port_index ); + //port = fGraphManager->GetPort(port_index); netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index); @@ -133,18 +133,18 @@ int JackNetOneDriver::AllocPorts() #if HAVE_CELT #if HAVE_CELT_API_0_11 celt_int32 lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); + CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create_custom(celt_mode, 1, NULL)); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 celt_int32 lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); + CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode, 1, NULL)); #else celt_int32_t lookahead; - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create( celt_mode ) ); + CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL); + netj.capture_srcs = jack_slist_append(netj.capture_srcs, celt_decoder_create(celt_mode)); #endif - celt_mode_info( celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + celt_mode_info(celt_mode, CELT_GET_LOOKAHEAD, &lookahead); netj.codec_latency = 2 * lookahead; #endif } else { @@ -159,10 +159,10 @@ int JackNetOneDriver::AllocPorts() if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { - jack_error ( "driver: cannot register port for %s", buf ); + jack_error("driver: cannot register port for %s", buf); return -1; } - //port = fGraphManager->GetPort ( port_index ); + //port = fGraphManager->GetPort(port_index); netj.capture_ports = jack_slist_append (netj.capture_ports, (void *)(intptr_t)port_index); @@ -173,23 +173,23 @@ int JackNetOneDriver::AllocPorts() if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { - jack_error ( "driver: cannot register port for %s", buf ); + jack_error("driver: cannot register port for %s", buf); return -1; } - //port = fGraphManager->GetPort ( port_index ); + //port = fGraphManager->GetPort(port_index); netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index); - if( netj.bitdepth == CELT_MODE ) { + if (netj.bitdepth == CELT_MODE) { #if HAVE_CELT #if HAVE_CELT_API_0_11 - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); + CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create_custom(celt_mode, 1, NULL)); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); + CELTMode *celt_mode = celt_mode_create(netj.sample_rate, netj.period_size, NULL); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode, 1, NULL)); #else - CELTMode *celt_mode = celt_mode_create( netj.sample_rate, 1, netj.period_size, NULL ); - netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create( celt_mode ) ); + CELTMode *celt_mode = celt_mode_create(netj.sample_rate, 1, netj.period_size, NULL); + netj.playback_srcs = jack_slist_append(netj.playback_srcs, celt_encoder_create(celt_mode)); #endif #endif } else { @@ -203,10 +203,10 @@ int JackNetOneDriver::AllocPorts() if (fEngine->PortRegister(fClientControl.fRefNum, buf, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { - jack_error ( "driver: cannot register port for %s", buf ); + jack_error("driver: cannot register port for %s", buf); return -1; } - //port = fGraphManager->GetPort ( port_index ); + //port = fGraphManager->GetPort(port_index); netj.playback_ports = jack_slist_append (netj.playback_ports, (void *)(intptr_t)port_index); @@ -217,33 +217,33 @@ int JackNetOneDriver::AllocPorts() //init and restart-------------------------------------------------------------------- bool JackNetOneDriver::Initialize() { - jack_log ( "JackNetOneDriver::Init()" ); + jack_log("JackNetOneDriver::Init"); FreePorts(); - netjack_release( &netj ); + netjack_release(&netj); //display some additional infos - jack_info ( "NetOne driver started" ); - if( netjack_startup( &netj ) ) { + jack_info("NetOne driver started"); + if (netjack_startup(&netj)) { return false; } //register jack ports - if ( AllocPorts() != 0 ) { - jack_error ( "Can't allocate ports." ); + if (AllocPorts() != 0) { + jack_error("Can't allocate ports."); return false; } //monitor //driver parametering - JackTimedDriver::SetBufferSize ( netj.period_size ); - JackTimedDriver::SetSampleRate ( netj.sample_rate ); + JackTimedDriver::SetBufferSize(netj.period_size); + JackTimedDriver::SetSampleRate(netj.sample_rate); - JackDriver::NotifyBufferSize ( netj.period_size ); - JackDriver::NotifySampleRate ( netj.sample_rate ); + JackDriver::NotifyBufferSize(netj.period_size); + JackDriver::NotifySampleRate(netj.sample_rate); //transport engine parametering - fEngineControl->fTransport.SetNetworkSync ( true ); + fEngineControl->fTransport.SetNetworkSync(true); return true; } @@ -252,24 +252,19 @@ bool JackNetOneDriver::Initialize() //driver processes-------------------------------------------------------------------- -int JackNetOneDriver::Process() -{ - return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); -} - int JackNetOneDriver::Read() { int delay; - delay = netjack_wait( &netj ); - if( delay ) { + delay = netjack_wait(&netj); + if (delay) { NotifyXRun(fBeginDateUst, (float) delay); - jack_error( "netxruns... duration: %dms", delay / 1000 ); + jack_error("netxruns... duration: %dms", delay / 1000); } - if( (netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2 ) + if ((netj.num_lost_packets * netj.period_size / netj.sample_rate) > 2) JackTools::ThrowJackNetException(); - //netjack_read( &netj, netj.period_size ); + //netjack_read(&netj, netj.period_size); JackDriver::CycleTakeBeginTime(); jack_position_t local_trans_pos; @@ -277,9 +272,9 @@ int JackNetOneDriver::Read() unsigned int *packet_buf, *packet_bufX; - if( ! netj.packet_data_valid ) { - jack_log( "data not valid" ); - render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); + if (! netj.packet_data_valid) { + jack_log("data not valid"); + render_payload_to_jack_ports (netj.bitdepth, NULL, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats); return 0; } packet_buf = netj.rx_buf; @@ -292,10 +287,10 @@ int JackNetOneDriver::Read() netj.latency = pkthdr->latency; // Special handling for latency=0 - if( netj.latency == 0 ) + if (netj.latency == 0) netj.resync_threshold = 0; else - netj.resync_threshold = MIN( 15, pkthdr->latency - 1 ); + netj.resync_threshold = MIN(15, pkthdr->latency - 1); // check whether, we should handle the transport sync stuff, or leave trnasports untouched. if (netj.handle_transport_sync) { @@ -305,7 +300,7 @@ int JackNetOneDriver::Read() // read local transport info.... //local_trans_state = jack_transport_query(netj.client, &local_trans_pos); - local_trans_state = fEngineControl->fTransport.Query ( &local_trans_pos ); + local_trans_state = fEngineControl->fTransport.Query(&local_trans_pos); // Now check if we have to start or stop local transport to sync to remote... switch (pkthdr->transport_state) { @@ -313,7 +308,7 @@ int JackNetOneDriver::Read() case JackTransportStarting: // the master transport is starting... so we set our reply to the sync_callback; if (local_trans_state == JackTransportStopped) { - fEngineControl->fTransport.SetCommand ( TransportCommandStart ); + fEngineControl->fTransport.SetCommand(TransportCommandStart); //jack_transport_start(netj.client); //last_transport_state = JackTransportStopped; netj.sync_state = 0; @@ -326,11 +321,11 @@ int JackNetOneDriver::Read() new_pos.valid = (jack_position_bits_t) 0; - fEngineControl->fTransport.RequestNewPos ( &new_pos ); + fEngineControl->fTransport.RequestNewPos(&new_pos); //jack_transport_locate(netj.client, compensated_tranport_pos); //last_transport_state = JackTransportRolling; netj.sync_state = 0; - jack_info("starting locate to %d", compensated_tranport_pos ); + jack_info("starting locate to %d", compensated_tranport_pos); } break; @@ -340,13 +335,13 @@ int JackNetOneDriver::Read() jack_position_t new_pos = local_trans_pos; new_pos.frame = pkthdr->transport_frame; new_pos.valid = (jack_position_bits_t)0; - fEngineControl->fTransport.RequestNewPos ( &new_pos ); + fEngineControl->fTransport.RequestNewPos(&new_pos); //jack_transport_locate(netj.client, (pkthdr->transport_frame)); jack_info("transport is stopped locate to %d", pkthdr->transport_frame); } if (local_trans_state != JackTransportStopped) //jack_transport_stop(netj.client); - fEngineControl->fTransport.SetCommand ( TransportCommandStop ); + fEngineControl->fTransport.SetCommand(TransportCommandStop); break; case JackTransportRolling: @@ -356,7 +351,7 @@ int JackNetOneDriver::Read() // jack_info("running locate to %d", pkthdr->transport_frame + (pkthdr->latency)*netj.period_size); // } if (local_trans_state != JackTransportRolling) - fEngineControl->fTransport.SetState ( JackTransportRolling ); + fEngineControl->fTransport.SetState(JackTransportRolling); break; case JackTransportLooping: @@ -365,14 +360,14 @@ int JackNetOneDriver::Read() #endif } - render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats ); - packet_cache_release_packet(netj.packcache, netj.expected_framecnt ); + render_payload_to_jack_ports (netj.bitdepth, packet_bufX, netj.net_period_down, netj.capture_ports, netj.capture_srcs, netj.period_size, netj.dont_htonl_floats); + packet_cache_release_packet(netj.packcache, netj.expected_framecnt); return 0; } int JackNetOneDriver::Write() { - int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0 ); + int syncstate = netj.sync_state | ((fEngineControl->fTransport.GetState() == JackTransportNetStarting) ? 1 : 0); uint32_t *packet_buf, *packet_bufX; int packet_size = get_sample_size(netj.bitdepth) * netj.playback_channels * netj.net_period_up + sizeof(jacknet_packet_header); @@ -381,7 +376,7 @@ int JackNetOneDriver::Write() packet_buf = (uint32_t *) alloca(packet_size); pkthdr = (jacknet_packet_header *)packet_buf; - if( netj.running_free ) { + if (netj.running_free) { return 0; } @@ -390,10 +385,10 @@ int JackNetOneDriver::Write() pkthdr->sync_state = syncstate;; pkthdr->latency = netj.time_to_deadline; - //printf( "time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness ); + //printf("time to deadline = %d goodness=%d\n", (int)netj.time_to_deadline, netj.deadline_goodness); pkthdr->framecnt = netj.expected_framecnt; - render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats ); + render_jack_ports_to_payload(netj.bitdepth, netj.playback_ports, netj.playback_srcs, netj.period_size, packet_bufX, netj.net_period_up, netj.dont_htonl_floats); packet_header_hton(pkthdr); if (netj.srcaddress_valid) { @@ -403,7 +398,7 @@ int JackNetOneDriver::Write() if (netj.reply_port) netj.syncsource_address.sin_port = htons(netj.reply_port); - for( r = 0; r < netj.redundancy; r++ ) + for (r = 0; r < netj.redundancy; r++) netjack_sendto(netj.sockfd, (char *)packet_buf, packet_size, flag, (struct sockaddr*) & (netj.syncsource_address), sizeof(struct sockaddr_in), netj.mtu); } @@ -415,66 +410,66 @@ JackNetOneDriver::FreePorts () { JSList *node = netj.capture_ports; - while( node != NULL ) { + while (node != NULL) { JSList *this_node = node; jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); + node = jack_slist_remove_link(node, this_node); + jack_slist_free_1(this_node); fEngine->PortUnRegister(fClientControl.fRefNum, port_index); } netj.capture_ports = NULL; node = netj.playback_ports; - while( node != NULL ) { + while (node != NULL) { JSList *this_node = node; jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); + node = jack_slist_remove_link(node, this_node); + jack_slist_free_1(this_node); fEngine->PortUnRegister(fClientControl.fRefNum, port_index); } netj.playback_ports = NULL; - if( netj.bitdepth == CELT_MODE ) { + if (netj.bitdepth == CELT_MODE) { #if HAVE_CELT node = netj.playback_srcs; - while( node != NULL ) { + while (node != NULL) { JSList *this_node = node; CELTEncoder *enc = (CELTEncoder *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - celt_encoder_destroy( enc ); + node = jack_slist_remove_link(node, this_node); + jack_slist_free_1(this_node); + celt_encoder_destroy(enc); } netj.playback_srcs = NULL; node = netj.capture_srcs; - while( node != NULL ) { + while (node != NULL) { JSList *this_node = node; CELTDecoder *dec = (CELTDecoder *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - celt_decoder_destroy( dec ); + node = jack_slist_remove_link(node, this_node); + jack_slist_free_1(this_node); + celt_decoder_destroy(dec); } netj.capture_srcs = NULL; #endif } else { #if HAVE_SAMPLERATE node = netj.playback_srcs; - while( node != NULL ) { + while (node != NULL) { JSList *this_node = node; SRC_STATE *state = (SRC_STATE *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - src_delete( state ); + node = jack_slist_remove_link(node, this_node); + jack_slist_free_1(this_node); + src_delete(state); } netj.playback_srcs = NULL; node = netj.capture_srcs; - while( node != NULL ) { + while (node != NULL) { JSList *this_node = node; SRC_STATE *state = (SRC_STATE *) node->data; - node = jack_slist_remove_link( node, this_node ); - jack_slist_free_1( this_node ); - src_delete( state ); + node = jack_slist_remove_link(node, this_node); + jack_slist_free_1(this_node); + src_delete(state); } netj.capture_srcs = NULL; #endif @@ -485,7 +480,7 @@ JackNetOneDriver::FreePorts () // render functions for float void -JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) +JackNetOneDriver::render_payload_to_jack_ports_float(void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats) { uint32_t chn = 0; JSList *node = capture_ports; @@ -495,7 +490,7 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac uint32_t *packet_bufX = (uint32_t *)packet_payload; - if( !packet_payload ) + if (!packet_payload) return; while (node != NULL) { @@ -505,7 +500,7 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac SRC_DATA src; #endif jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_index ); + JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); @@ -536,8 +531,8 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac } else #endif { - if( dont_htonl_floats ) { - memcpy( buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t)); + if (dont_htonl_floats) { + memcpy(buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t)); } else { for (i = 0; i < net_period_down; i++) { val.i = packet_bufX[i]; @@ -560,7 +555,7 @@ JackNetOneDriver::render_payload_to_jack_ports_float ( void *packet_payload, jac } void -JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ) +JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats) { uint32_t chn = 0; JSList *node = playback_ports; @@ -577,7 +572,7 @@ JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JS unsigned int i; int_float_t val; jack_port_id_t port_index = (jack_port_id_t)(intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_index ); + JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); @@ -609,8 +604,8 @@ JackNetOneDriver::render_jack_ports_to_payload_float (JSList *playback_ports, JS } else #endif { - if( dont_htonl_floats ) { - memcpy( packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t) ); + if (dont_htonl_floats) { + memcpy(packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t)); } else { for (i = 0; i < net_period_up; i++) { val.f = buf[i]; @@ -644,7 +639,7 @@ JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_ while (node != NULL) { jack_port_id_t port_index = (jack_port_id_t) (intptr_t)node->data; - JackPort *port = fGraphManager->GetPort( port_index ); + JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); @@ -656,15 +651,15 @@ JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_ CELTDecoder *decoder = (CELTDecoder *)src_node->data; #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); + if (!packet_payload) + celt_decode_float(decoder, NULL, net_period_down, buf, nframes); else - celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); + celt_decode_float(decoder, packet_bufX, net_period_down, buf, nframes); #else - if( !packet_payload ) - celt_decode_float( decoder, NULL, net_period_down, buf ); + if (!packet_payload) + celt_decode_float(decoder, NULL, net_period_down, buf); else - celt_decode_float( decoder, packet_bufX, net_period_down, buf ); + celt_decode_float(decoder, packet_bufX, net_period_down, buf); #endif src_node = jack_slist_next (src_node); @@ -673,7 +668,7 @@ JackNetOneDriver::render_payload_to_jack_ports_celt (void *packet_payload, jack_ // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; uint32_t * buffer_uint32 = (uint32_t*) packet_bufX; - if( packet_payload ) + if (packet_payload) decode_midi_buffer (buffer_uint32, buffer_size_uint32, buf); } packet_bufX = (packet_bufX + net_period_down); @@ -693,7 +688,7 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL while (node != NULL) { jack_port_id_t port_index = (jack_port_id_t) (intptr_t) node->data; - JackPort *port = fGraphManager->GetPort( port_index ); + JackPort *port = fGraphManager->GetPort(port_index); jack_default_audio_sample_t* buf = (jack_default_audio_sample_t*)fGraphManager->GetBuffer(port_index, fEngineControl->fBufferSize); @@ -704,17 +699,17 @@ JackNetOneDriver::render_jack_ports_to_payload_celt (JSList *playback_ports, JSL // audio port, encode celt data. int encoded_bytes; - jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes ); - memcpy( floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t) ); + jack_default_audio_sample_t *floatbuf = (jack_default_audio_sample_t *)alloca (sizeof(jack_default_audio_sample_t) * nframes); + memcpy(floatbuf, buf, nframes * sizeof(jack_default_audio_sample_t)); CELTEncoder *encoder = (CELTEncoder *)src_node->data; #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 - encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); + encoded_bytes = celt_encode_float(encoder, floatbuf, nframes, packet_bufX, net_period_up); #else - encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); + encoded_bytes = celt_encode_float(encoder, floatbuf, NULL, packet_bufX, net_period_up); #endif - if( encoded_bytes != (int)net_period_up ) - jack_error( "something in celt changed. netjack needs to be changed to handle this." ); - src_node = jack_slist_next( src_node ); + if (encoded_bytes != (int)net_period_up) + jack_error("something in celt changed. netjack needs to be changed to handle this."); + src_node = jack_slist_next(src_node); } else if (strncmp(portname, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size()) == 0) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) @@ -820,7 +815,7 @@ extern "C" return desc; } - SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize ( Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params ) + SERVER_EXPORT Jack::JackDriverClientInterface* driver_initialize(Jack::JackLockedEngine* engine, Jack::JackSynchro* table, const JSList* params) { jack_nframes_t sample_rate = 48000; jack_nframes_t resample_factor = 1; @@ -845,9 +840,9 @@ extern "C" const JSList * node; const jack_driver_param_t * param; - for ( node = params; node; node = jack_slist_next ( node ) ) { - param = ( const jack_driver_param_t* ) node->data; - switch ( param->character ) { + for (node = params; node; node = jack_slist_next(node)) { + param = (const jack_driver_param_t*) node->data; + switch (param->character) { case 'i': capture_ports = param->value.ui; break; @@ -880,7 +875,7 @@ extern "C" #if HAVE_SAMPLERATE resample_factor = param->value.ui; #else - jack_error( "not built with libsamplerate support" ); + jack_error("not built with libsamplerate support"); return NULL; #endif break; @@ -889,7 +884,7 @@ extern "C" #if HAVE_SAMPLERATE resample_factor_up = param->value.ui; #else - jack_error( "not built with libsamplerate support" ); + jack_error("not built with libsamplerate support"); return NULL; #endif break; @@ -903,7 +898,7 @@ extern "C" bitdepth = CELT_MODE; resample_factor = param->value.ui; #else - jack_error( "not built with celt support" ); + jack_error("not built with celt support"); return NULL; #endif break; @@ -940,21 +935,21 @@ extern "C" try { Jack::JackDriverClientInterface* driver = new Jack::JackWaitThreadedDriver ( - new Jack::JackNetOneDriver ( "system", "net_pcm", engine, table, listen_port, mtu, + new Jack::JackNetOneDriver("system", "net_pcm", engine, table, listen_port, mtu, capture_ports_midi, playback_ports_midi, capture_ports, playback_ports, sample_rate, period_size, resample_factor, "net_pcm", handle_transport_sync, bitdepth, use_autoconfig, latency, redundancy, - dont_htonl_floats, always_deadline, jitter_val ) ); + dont_htonl_floats, always_deadline, jitter_val)); - if ( driver->Open ( period_size, sample_rate, 1, 1, capture_ports, playback_ports, - 0, "from_master_", "to_master_", 0, 0 ) == 0 ) { + if (driver->Open(period_size, sample_rate, 1, 1, capture_ports, playback_ports, + 0, "from_master_", "to_master_", 0, 0) == 0) { return driver; } else { delete driver; return NULL; } - } catch ( ... ) { + } catch (...) { return NULL; } } diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h index ae5fd078..954a7cba 100644 --- a/common/JackNetOneDriver.h +++ b/common/JackNetOneDriver.h @@ -30,7 +30,7 @@ namespace Jack \Brief This class describes the Net Backend */ -class JackNetOneDriver : public JackTimedDriver +class JackNetOneDriver : public JackWaiterDriver { private: @@ -63,8 +63,6 @@ class JackNetOneDriver : public JackTimedDriver int Close(); int Attach(); int Detach(); - - int Process(); int Read(); int Write(); @@ -74,17 +72,17 @@ class JackNetOneDriver : public JackTimedDriver void FreePorts(); // BufferSize can't be changed - bool IsFixedBufferSize() + bool IsFixedBufferSize() { return true; } - int SetBufferSize(jack_nframes_t buffer_size) + int SetBufferSize(jack_nframes_t buffer_size) { return -1; } - int SetSampleRate(jack_nframes_t sample_rate) + int SetSampleRate(jack_nframes_t sample_rate) { return -1; } diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index f2d49189..4077de34 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -24,7 +24,7 @@ namespace Jack { JackResampler::JackResampler() - :fRatio(1),fRingBufferSize(DEFAULT_RB_SIZE) + :fRatio(1), fRingBufferSize(DEFAULT_RB_SIZE) { fRingBuffer = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * fRingBufferSize); jack_ringbuffer_read_advance(fRingBuffer, (sizeof(jack_default_audio_sample_t) * fRingBufferSize) / 2); @@ -32,8 +32,9 @@ JackResampler::JackResampler() JackResampler::~JackResampler() { - if (fRingBuffer) + if (fRingBuffer) { jack_ringbuffer_free(fRingBuffer); + } } void JackResampler::Reset(unsigned int new_size) diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index 9500dadb..a88926f0 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -44,16 +44,16 @@ int JackThreadedDriver::Open() } int JackThreadedDriver::Open(jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool capturing, - bool playing, - int inchannels, - int outchannels, - bool monitor, - const char* capture_driver_name, - const char* playback_driver_name, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency) + jack_nframes_t samplerate, + bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_name, + const char* playback_driver_name, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) { return fDriver->Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); } @@ -245,7 +245,7 @@ void JackThreadedDriver::SetRealTime() set_threaded_log_function(); } } else { - jack_log("JackThreadedDriver::Init non non-realtime "); + jack_log("JackThreadedDriver::Init non-realtime"); } } diff --git a/common/JackTimedDriver.cpp b/common/JackTimedDriver.cpp index 68b98b6f..2a6dec89 100644 --- a/common/JackTimedDriver.cpp +++ b/common/JackTimedDriver.cpp @@ -29,58 +29,61 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -int JackTimedDriver::FirstCycle(jack_time_t cur_time) +int JackTimedDriver::FirstCycle(jack_time_t cur_time_usec) { - fAnchorTime = cur_time; + fAnchorTimeUsec = cur_time_usec; return int((double(fEngineControl->fBufferSize) * 1000000) / double(fEngineControl->fSampleRate)); } - -int JackTimedDriver::CurrentCycle(jack_time_t cur_time) + +int JackTimedDriver::CurrentCycle(jack_time_t cur_time_usec) +{ + return int(((double(fCycleCount) * double(fEngineControl->fBufferSize) * 1000000.) / double(fEngineControl->fSampleRate)) - (cur_time_usec - fAnchorTimeUsec)); +} + +int JackTimedDriver::Start() { - return int((double(fCycleCount) * double(fEngineControl->fBufferSize) * 1000000.) / double(fEngineControl->fSampleRate)) - (cur_time - fAnchorTime); + fCycleCount = 0; + return JackAudioDriver::Start(); } -int JackTimedDriver::ProcessAux() +void JackTimedDriver::ProcessWait() { - jack_time_t cur_time = GetMicroSeconds(); - int wait_time; - + jack_time_t cur_time_usec = GetMicroSeconds(); + int wait_time_usec; + if (fCycleCount++ == 0) { - wait_time = FirstCycle(cur_time); + wait_time_usec = FirstCycle(cur_time_usec); } else { - wait_time = CurrentCycle(cur_time); + wait_time_usec = CurrentCycle(cur_time_usec); } - - if (wait_time < 0) { - NotifyXRun(cur_time, float(cur_time -fBeginDateUst)); + + if (wait_time_usec < 0) { + NotifyXRun(cur_time_usec, float(cur_time_usec - fBeginDateUst)); fCycleCount = 0; - wait_time = 0; + wait_time_usec = 0; + jack_error("JackTimedDriver::Process XRun = %ld usec", (cur_time_usec - fBeginDateUst)); } - - //jack_log("JackTimedDriver::Process wait_time = %d", wait_time); - JackSleep(wait_time); - return 0; -} -int JackTimedDriver::Process() -{ - JackDriver::CycleTakeBeginTime(); - JackAudioDriver::Process(); - - return ProcessAux(); + //jack_log("JackTimedDriver::Process wait_time = %d", wait_time_usec); + JackSleep(wait_time_usec); } -int JackTimedDriver::ProcessNull() +int JackWaiterDriver::ProcessNull() { JackDriver::CycleTakeBeginTime(); - + + // Graph processing without Read/Write if (fEngineControl->fSyncMode) { - ProcessGraphSyncMaster(); + ProcessGraphSync(); } else { - ProcessGraphAsyncMaster(); + ProcessGraphAsync(); } - - return ProcessAux(); + + // Keep end cycle time + JackDriver::CycleTakeEndTime(); + + ProcessWait(); + return 0; } } // end of namespace diff --git a/common/JackTimedDriver.h b/common/JackTimedDriver.h index 987bfab4..e2d26ca1 100644 --- a/common/JackTimedDriver.h +++ b/common/JackTimedDriver.h @@ -32,33 +32,47 @@ namespace Jack class SERVER_EXPORT JackTimedDriver : public JackAudioDriver { - private: + protected: int fCycleCount; - jack_time_t fAnchorTime; - + jack_time_t fAnchorTimeUsec; + int FirstCycle(jack_time_t cur_time); int CurrentCycle(jack_time_t cur_time); - - int ProcessAux(); + + void ProcessWait(); public: JackTimedDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) - : JackAudioDriver(name, alias, engine, table), fCycleCount(0), fAnchorTime(0) + : JackAudioDriver(name, alias, engine, table), fCycleCount(0), fAnchorTimeUsec(0) {} virtual ~JackTimedDriver() {} - virtual int Process(); - virtual int ProcessNull(); - // BufferSize can be changed bool IsFixedBufferSize() { return false; } + int Start(); + +}; + +class SERVER_EXPORT JackWaiterDriver : public JackTimedDriver +{ + + public: + + JackWaiterDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) + : JackTimedDriver(name, alias, engine, table) + {} + virtual ~JackWaiterDriver() + {} + + virtual int ProcessNull(); + }; } // end of namespace diff --git a/common/JackWaitThreadedDriver.cpp b/common/JackWaitThreadedDriver.cpp index dd52a9d9..09c2cae4 100644 --- a/common/JackWaitThreadedDriver.cpp +++ b/common/JackWaitThreadedDriver.cpp @@ -43,9 +43,9 @@ bool JackWaitThreadedDriver::Execute() // Process a null cycle until NetDriver has started while (!fStarter.fRunning && fThread.GetStatus() == JackThread::kRunning) { - // Use the base method - assert(static_cast<JackTimedDriver*>(fDriver)); - static_cast<JackTimedDriver*>(fDriver)->ProcessNull(); + // Use base class method + assert(static_cast<JackWaiterDriver*>(fDriver)); + static_cast<JackWaiterDriver*>(fDriver)->ProcessNull(); } // Switch to keep running even in case of error diff --git a/common/JackWaitThreadedDriver.h b/common/JackWaitThreadedDriver.h index f98a4e4a..6eee399a 100644 --- a/common/JackWaitThreadedDriver.h +++ b/common/JackWaitThreadedDriver.h @@ -39,7 +39,7 @@ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver { private: - struct SERVER_EXPORT JackDriverStarter : public JackRunnableInterface + struct JackDriverStarter : public JackRunnableInterface { JackDriver* fDriver; @@ -47,7 +47,7 @@ class SERVER_EXPORT JackWaitThreadedDriver : public JackThreadedDriver volatile bool fRunning; JackDriverStarter(JackDriver* driver) - :fDriver(driver),fThread(this),fRunning(false) + :fDriver(driver), fThread(this), fRunning(false) {} ~JackDriverStarter() diff --git a/common/jack/session.h b/common/jack/session.h index 1335f3a9..5d2fad98 100644 --- a/common/jack/session.h +++ b/common/jack/session.h @@ -37,7 +37,7 @@ extern "C" { /** * Session event type. * - * if a client cant save templates, i might just do a normal save. + * If a client cant save templates, i might just do a normal save. * * There is no "quit without saving" event because a client might refuse to * quit when it has unsaved data, but other clients may have already quit. @@ -192,15 +192,13 @@ int jack_session_reply (jack_client_t *client, /** * Free memory used by a jack_session_event_t. * - * This also frees the memory used by the command_line pointer. - * if its non NULL. + * This also frees the memory used by the command_line pointer, if its non NULL. */ void jack_session_event_free (jack_session_event_t *event) JACK_WEAK_EXPORT; /** * Get the assigned uuid for client. - * * Safe to call from callback and all other threads. * * The caller is responsible for calling jack_free(3) on any non-NULL diff --git a/common/jack/thread.h b/common/jack/thread.h index 28c8cd10..a4c19cd3 100644 --- a/common/jack/thread.h +++ b/common/jack/thread.h @@ -114,7 +114,7 @@ int jack_drop_real_time_scheduling (jack_native_thread_t thread) JACK_OPTIONAL_W int jack_client_stop_thread(jack_client_t* client, jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; /** - * Cancel the thread then waits for the thread handler to terminate. + * Kill the thread. * * @param thread POSIX thread ID. * diff --git a/example-clients/cpu_load.c b/example-clients/cpu_load.c index 1d5787ac..34e6d7c6 100644 --- a/example-clients/cpu_load.c +++ b/example-clients/cpu_load.c @@ -16,11 +16,11 @@ jack_client_t *client; -static void signal_handler ( int sig ) +static void signal_handler(int sig) { - jack_client_close ( client ); - fprintf ( stderr, "signal received, exiting ...\n" ); - exit ( 0 ); + jack_client_close(client ; + fprintf(stderr, "signal received, exiting ...\n"); + exit(0); } @@ -29,13 +29,13 @@ static void signal_handler ( int sig ) * decides to disconnect the client. */ void -jack_shutdown ( void *arg ) +jack_shutdown(void *arg) { - exit ( 1 ); + exit(1); } int -main ( int argc, char *argv[] ) +main(int argc, char *argv[]) { jack_options_t options = JackNullOption; jack_status_t status; @@ -43,50 +43,46 @@ main ( int argc, char *argv[] ) /* open a client connection to the JACK server */ client = jack_client_open ("jack_cpu_load", options, &status); - if ( client == NULL ) - { - fprintf ( stderr, "jack_client_open() failed, " - "status = 0x%2.0x\n", status ); - if ( status & JackServerFailed ) - { - fprintf ( stderr, "Unable to connect to JACK server\n" ); + if (client == NULL) { + fprintf(stderr, "jack_client_open() failed, " + "status = 0x%2.0x\n", status); + if (status & JackServerFailed) { + fprintf(stderr, "Unable to connect to JACK server\n"); } - exit ( 1 ); + exit(1); } - - jack_on_shutdown ( client, jack_shutdown, 0 ); + + jack_on_shutdown(client, jack_shutdown, 0); /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ - if ( jack_activate ( client ) ) - { - fprintf ( stderr, "cannot activate client" ); - exit ( 1 ); + if (jack_activate(client)) { + fprintf(stderr, "cannot activate client"); + exit(1); } /* install a signal handler to properly quits jack client */ #ifdef WIN32 - signal ( SIGINT, signal_handler ); - signal ( SIGABRT, signal_handler ); - signal ( SIGTERM, signal_handler ); + signal(SIGINT, signal_handler); + signal(SIGABRT, signal_handler); + signal(SIGTERM, signal_handler); #else - signal ( SIGQUIT, signal_handler ); - signal ( SIGTERM, signal_handler ); - signal ( SIGHUP, signal_handler ); - signal ( SIGINT, signal_handler ); + signal(SIGQUIT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); #endif - while (1) - { + while (1) { printf("jack DSP load %f\n", jack_cpu_load(client)); #ifdef WIN32 - Sleep ( 1000 ); + Sleep(1000); #else - sleep ( 1 ); + sleep(1); #endif } - jack_client_close ( client ); - exit ( 0 ); + jack_client_close(client); + exit(0 ); } diff --git a/example-clients/netmaster.c b/example-clients/netmaster.c index c9dd42ae..a7c1ad2e 100644 --- a/example-clients/netmaster.c +++ b/example-clients/netmaster.c @@ -57,9 +57,9 @@ main (int argc, char *argv[]) { int buffer_size = BUFFER_SIZE; int sample_rate = SAMPLE_RATE; - int port = DEFAULT_PORT; + int udp_port = DEFAULT_PORT; char* multicast_ip = DEFAULT_MULTICAST_IP; - const char *options = "b:r:a:p:"; + const char *options = "b:r:a:p:h"; int option_index; int opt; @@ -89,7 +89,7 @@ main (int argc, char *argv[]) break; case 'p': - port = atoi(optarg); + udp_port = atoi(optarg); break; case 'h': @@ -107,7 +107,7 @@ main (int argc, char *argv[]) printf("Waiting for a slave...\n"); - if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_master", &request, &result)) == 0) { + if ((net = jack_net_master_open(multicast_ip, udp_port, "net_master", &request, &result)) == 0) { fprintf(stderr, "NetJack master can not be opened\n"); return 1; } diff --git a/example-clients/netslave.c b/example-clients/netslave.c index 2c136de9..d28d4821 100644 --- a/example-clients/netslave.c +++ b/example-clients/netslave.c @@ -79,9 +79,9 @@ main (int argc, char *argv[]) { int audio_input = 2; int audio_output = 2; - int port = DEFAULT_PORT; + int udp_port = DEFAULT_PORT; char* multicast_ip = DEFAULT_MULTICAST_IP; - const char *options = "C:P:a:p:"; + const char *options = "C:P:a:p:h"; int option_index; int opt; @@ -111,7 +111,7 @@ main (int argc, char *argv[]) break; case 'p': - port = atoi(optarg); + udp_port = atoi(optarg); break; case 'h': @@ -125,7 +125,7 @@ main (int argc, char *argv[]) printf("Waiting for a master...\n"); - if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_slave", &request, &result)) == 0) { + if ((net = jack_net_slave_open(multicast_ip, udp_port, "net_slave", &request, &result)) == 0) { fprintf(stderr, "JACK server not running?\n"); return 1; } diff --git a/example-clients/wait.c b/example-clients/wait.c index 9150bb63..9eb1ec02 100644 --- a/example-clients/wait.c +++ b/example-clients/wait.c @@ -11,22 +11,22 @@ char * my_name; void -show_usage (void) +show_usage(void) { - fprintf (stderr, "\nUsage: %s [options]\n", my_name); - fprintf (stderr, "Check for jack existence, or wait, until it either quits, or gets started\n"); - fprintf (stderr, "options:\n"); - fprintf (stderr, " -s, --server <name> Connect to the jack server named <name>\n"); - fprintf (stderr, " -w, --wait Wait for server to become available\n"); - fprintf (stderr, " -q, --quit Wait until server is quit\n"); - fprintf (stderr, " -c, --check Check wether server is running\n"); - fprintf (stderr, " -t, --timeout Wait timeout in seconds\n"); - fprintf (stderr, " -h, --help Display this help message\n"); - fprintf (stderr, "For more information see http://jackaudio.org/\n"); + fprintf(stderr, "\nUsage: %s [options]\n", my_name); + fprintf(stderr, "Check for jack existence, or wait, until it either quits, or gets started\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -s, --server <name> Connect to the jack server named <name>\n"); + fprintf(stderr, " -w, --wait Wait for server to become available\n"); + fprintf(stderr, " -q, --quit Wait until server is quit\n"); + fprintf(stderr, " -c, --check Check wether server is running\n"); + fprintf(stderr, " -t, --timeout Wait timeout in seconds\n"); + fprintf(stderr, " -h, --help Display this help message\n"); + fprintf(stderr, "For more information see http://jackaudio.org/\n"); } int -main (int argc, char *argv[]) +main(int argc, char *argv[]) { jack_client_t *client; jack_status_t status; @@ -78,11 +78,11 @@ main (int argc, char *argv[]) wait_timeout = atoi(optarg); break; case 'h': - show_usage (); + show_usage(); return 1; break; default: - show_usage (); + show_usage(); return 1; break; } @@ -90,40 +90,40 @@ main (int argc, char *argv[]) /* try to open server in a loop. breaking under certein conditions */ - start_timestamp = time( NULL ); + start_timestamp = time(NULL); - while(1) { + while (1) { client = jack_client_open ("wait", options, &status, server_name); /* check for some real error and bail out */ - if( (client == NULL) && !(status & JackServerFailed) ) { + if ((client == NULL) && !(status & JackServerFailed)) { fprintf (stderr, "jack_client_open() failed, " "status = 0x%2.0x\n", status); return 1; } - if( client == NULL ) { - if( wait_for_quit ) { - fprintf( stdout, "server is gone\n" ); + if (client == NULL) { + if (wait_for_quit) { + fprintf(stdout, "server is gone\n"); break; } - if( just_check ) { - fprintf( stdout, "not running\n" ); + if (just_check) { + fprintf(stdout, "not running\n"); break; } } else { - jack_client_close( client ); - if( wait_for_start ) { - fprintf( stdout, "server is available\n" ); + jack_client_close(client); + if (wait_for_start) { + fprintf(stdout, "server is available\n"); break; } - if( just_check ) { - fprintf( stdout, "running\n" ); + if (just_check) { + fprintf(stdout, "running\n"); break; } } - if( wait_timeout ) { - if( (time( NULL ) - start_timestamp) > wait_timeout ) { - fprintf( stdout, "timeout\n" ); + if (wait_timeout) { + if ((time(NULL) - start_timestamp) > wait_timeout) { + fprintf(stdout, "timeout\n"); break; } } @@ -132,5 +132,5 @@ main (int argc, char *argv[]) sleep(1); } - exit (0); + exit(0); } diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index eb9e1083..a59a7ec3 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -213,8 +213,8 @@ extern "C" jack_driver_descriptor_add_parameter(desc, &filler, "duplex", 'D', JackDriverParamBool, &value, NULL, "Provide both capture and playback ports", NULL); value.i = 0; - jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamInt, &value, NULL, "Number of capture channels (defaults to hardware max)", NULL); - jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamInt, &value, NULL, "Number of playback channels (defaults to hardware max)", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Number of capture channels (defaults to hardware max)", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Number of playback channels (defaults to hardware max)", NULL); value.ui = 0; jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamUInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL); diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index a5661acf..ceaf74d9 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -2656,7 +2656,6 @@ 4BA3873B079479C2008D8992 /* Graph */, 4BA550FA05E241F200569492 /* Ports */, 4BD56D74079687D7006D44F9 /* Client */, - 4BA550FB05E2420000569492 /* Engine */, 4B9B627005E60A9E001E19AA /* Server */, ); name = Source; @@ -3111,6 +3110,7 @@ 4BA550FA05E241F200569492 /* Ports */ = { isa = PBXGroup; children = ( + 4BA550FB05E2420000569492 /* Engine */, 4B80D7E60BA0D17400F035BB /* JackMidiPort.cpp */, 4B80D7E50BA0D17400F035BB /* JackMidiPort.h */, 4BAB95EC0B9E21A500A0C723 /* JackAudioPort.cpp */, @@ -11701,8 +11701,12 @@ INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); OTHER_LDFLAGS = ( "-framework", Jackservermp, @@ -12000,8 +12004,12 @@ INSTALL_PATH = /usr/local/lib; LIBRARY_STYLE = DYNAMIC; MACH_O_TYPE = mh_dylib; - OTHER_CFLAGS = ""; - OTHER_CPLUSPLUSFLAGS = "-DMACH_RPC_MACH_SEMA"; + OTHER_CFLAGS = "-DJACK_32_64"; + OTHER_CPLUSPLUSFLAGS = ( + "-DSERVER_SIDE", + "-DMACH_RPC_MACH_SEMA", + "-DJACK_32_64", + ); OTHER_LDFLAGS = ( "-framework", Jackservermp, diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index 5e70c1ac..0ce5a66c 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -49,15 +49,17 @@ static OSStatus DisplayDeviceNames() CFStringRef UIname; err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); - if (err != noErr) + if (err != noErr) { return err; + } deviceNum = size / sizeof(AudioDeviceID); AudioDeviceID devices[deviceNum]; err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); - if (err != noErr) + if (err != noErr) { return err; + } for (i = 0; i < deviceNum; i++) { char device_name[256]; @@ -74,8 +76,9 @@ static OSStatus DisplayDeviceNames() size = 256; err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name); - if (err != noErr) + if (err != noErr) { return err; + } jack_info("Device name = \'%s\', internal_name = \'%s\' (to be used as -C, -P, or -d parameter)", device_name, internal_name); } @@ -83,8 +86,9 @@ static OSStatus DisplayDeviceNames() return noErr; error: - if (UIname != NULL) + if (UIname != NULL) { CFRelease(UIname); + } return err; } @@ -267,27 +271,31 @@ void JackCoreAudioAdapter::RemoveListeners() } OSStatus JackCoreAudioAdapter::Render(void *inRefCon, - AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList *ioData) + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData) { JackCoreAudioAdapter* adapter = static_cast<JackCoreAudioAdapter*>(inRefCon); - AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); + OSStatus err = AudioUnitRender(adapter->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, adapter->fInputData); - jack_default_audio_sample_t* inputBuffer[adapter->fCaptureChannels]; - jack_default_audio_sample_t* outputBuffer[adapter->fPlaybackChannels]; + if (err == noErr) { + jack_default_audio_sample_t* inputBuffer[adapter->fCaptureChannels]; + jack_default_audio_sample_t* outputBuffer[adapter->fPlaybackChannels]; - for (int i = 0; i < adapter->fCaptureChannels; i++) { - inputBuffer[i] = (jack_default_audio_sample_t*)adapter->fInputData->mBuffers[i].mData; - } - for (int i = 0; i < adapter->fPlaybackChannels; i++) { - outputBuffer[i] = (jack_default_audio_sample_t*)ioData->mBuffers[i].mData; - } + for (int i = 0; i < adapter->fCaptureChannels; i++) { + inputBuffer[i] = (jack_default_audio_sample_t*)adapter->fInputData->mBuffers[i].mData; + } + for (int i = 0; i < adapter->fPlaybackChannels; i++) { + outputBuffer[i] = (jack_default_audio_sample_t*)ioData->mBuffers[i].mData; + } - adapter->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, inNumberFrames); - return noErr; + adapter->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, inNumberFrames); + return noErr; + } else { + return err; + } } JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params) @@ -420,6 +428,9 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra if (AddListeners() < 0) { throw std::bad_alloc(); } + + GetStreamLatencies(fDeviceID, true, fInputLatencies); + GetStreamLatencies(fDeviceID, false, fOutputLatencies); } OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) @@ -429,11 +440,13 @@ OSStatus JackCoreAudioAdapter::GetDefaultDevice(AudioDeviceID* id) AudioDeviceID inDefault; AudioDeviceID outDefault; - if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) + if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) { return res; + } - if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) + if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) { return res; + } jack_log("GetDefaultDevice: input = %ld output = %ld", inDefault, outDefault); @@ -462,8 +475,9 @@ OSStatus JackCoreAudioAdapter::GetTotalChannels(AudioDeviceID device, int& chann AudioBufferList bufferList[outSize]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { - for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) + for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) { channelCount += bufferList->mBuffers[i].mNumberChannels; + } } } @@ -492,11 +506,12 @@ OSStatus JackCoreAudioAdapter::GetDefaultInputDevice(AudioDeviceID* id) UInt32 theSize = sizeof(UInt32); AudioDeviceID inDefault; - if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) + if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &theSize, &inDefault)) != noErr) { return res; + } if (inDefault == 0) { - jack_error("Error : input device is 0, please select a correct one !!"); + jack_error("Error: default input device is 0, please select a correct one !!"); return -1; } jack_log("GetDefaultInputDevice: input = %ld ", inDefault); @@ -510,11 +525,12 @@ OSStatus JackCoreAudioAdapter::GetDefaultOutputDevice(AudioDeviceID* id) UInt32 theSize = sizeof(UInt32); AudioDeviceID outDefault; - if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) + if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &theSize, &outDefault)) != noErr) { return res; + } if (outDefault == 0) { - jack_error("Error : output device is 0, please select a correct one !!"); + jack_error("Error: default output device is 0, please select a correct one !!"); return -1; } jack_log("GetDefaultOutputDevice: output = %ld", outDefault); @@ -528,6 +544,39 @@ OSStatus JackCoreAudioAdapter::GetDeviceNameFromID(AudioDeviceID id, char* name) return AudioDeviceGetProperty(id, 0, false, kAudioDevicePropertyDeviceName, &size, name); } +AudioDeviceID JackCoreAudioAdapter::GetDeviceIDFromName(const char* name) +{ + UInt32 size; + Boolean isWritable; + int i, deviceNum; + + OSStatus err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &isWritable); + if (err != noErr) { + return -1; + } + + deviceNum = size / sizeof(AudioDeviceID); + AudioDeviceID devices[deviceNum]; + + err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &size, devices); + if (err != noErr) { + return err; + } + + for (i = 0; i < deviceNum; i++) { + char device_name[256]; + size = 256; + err = AudioDeviceGetProperty(devices[i], 0, false, kAudioDevicePropertyDeviceName, &size, device_name); + if (err != noErr) { + return -1; + } else if (strcmp(device_name, name) == 0) { + return devices[i]; + } + } + + return -1; +} + // Setup int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, @@ -540,6 +589,7 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, // Duplex if (strcmp(capture_driver_uid, "") != 0 && strcmp(playback_driver_uid, "") != 0) { + jack_log("JackCoreAudioDriver::Open duplex"); // Same device for capture and playback... if (strcmp(capture_driver_uid, playback_driver_uid) == 0) { @@ -577,8 +627,9 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, } } - if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { return -1; + } } // Capture only @@ -616,13 +667,13 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, jack_error("Cannot open default device in duplex mode, so aggregate default input and default output"); // Creates aggregate device - AudioDeviceID captureID, playbackID; + AudioDeviceID captureID = -1, playbackID = -1; if (GetDeviceIDFromUID(capture_driver_uid, &captureID) != noErr) { jack_log("Will take default input"); if (GetDefaultInputDevice(&captureID) != noErr) { jack_error("Cannot open default input device"); - return -1; + goto built_in; } } @@ -630,16 +681,39 @@ int JackCoreAudioAdapter::SetupDevices(const char* capture_driver_uid, jack_log("Will take default output"); if (GetDefaultOutputDevice(&playbackID) != noErr) { jack_error("Cannot open default output device"); - return -1; + goto built_in; } } - if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) - return -1; + if (captureID > 0 && playbackID > 0) { + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { + goto built_in; + } + } else { + jack_error("Cannot use default input/output"); + goto built_in; + } } } return 0; + +built_in: + + // Aggregate built-in input and output + AudioDeviceID captureID = GetDeviceIDFromName("Built-in Input"); + AudioDeviceID playbackID = GetDeviceIDFromName("Built-in Output"); + + if (captureID > 0 && playbackID > 0) { + if (CreateAggregateDevice(captureID, playbackID, samplerate, &fDeviceID) != noErr) { + return -1; + } + } else { + jack_error("Cannot aggregate built-in input and output"); + return -1; + } + + return 0; } int JackCoreAudioAdapter::SetupChannels(bool capturing, @@ -676,14 +750,16 @@ int JackCoreAudioAdapter::SetupChannels(bool capturing, if (inchannels > in_nChannels) { jack_error("This device hasn't required input channels inchannels = %ld in_nChannels = %ld", inchannels, in_nChannels); - if (strict) + if (strict) { return -1; + } } if (outchannels > out_nChannels) { jack_error("This device hasn't required output channels outchannels = %ld out_nChannels = %ld", outchannels, out_nChannels); - if (strict) + if (strict) { return -1; + } } if (inchannels == -1) { @@ -785,8 +861,9 @@ int JackCoreAudioAdapter::SetupBuffers(int inchannels) void JackCoreAudioAdapter::DisposeBuffers() { if (fInputData) { - for (int i = 0; i < fCaptureChannels; i++) + for (int i = 0; i < fCaptureChannels; i++) { free(fInputData->mBuffers[i].mData); + } free(fInputData); fInputData = 0; } @@ -901,7 +978,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, } // Setup channel map - if (capturing && inchannels > 0 && inchannels < in_nChannels) { + if (capturing && inchannels > 0 && inchannels <= in_nChannels) { SInt32 chanArr[in_nChannels]; for (int i = 0; i < in_nChannels; i++) { chanArr[i] = -1; @@ -917,7 +994,7 @@ int JackCoreAudioAdapter::OpenAUHAL(bool capturing, } } - if (playing && outchannels > 0 && outchannels < out_nChannels) { + if (playing && outchannels > 0 && outchannels <= out_nChannels) { SInt32 chanArr[out_nChannels]; for (int i = 0; i < out_nChannels; i++) { chanArr[i] = -1; @@ -1284,8 +1361,9 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca vector<CFStringRef> captureDeviceUID; for (UInt32 i = 0; i < captureDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(captureDeviceID[i]); - if (ref == NULL) + if (ref == NULL) { return -1; + } captureDeviceUID.push_back(ref); // input sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); @@ -1294,8 +1372,9 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca vector<CFStringRef> playbackDeviceUID; for (UInt32 i = 0; i < playbackDeviceID.size(); i++) { CFStringRef ref = GetDeviceName(playbackDeviceID[i]); - if (ref == NULL) + if (ref == NULL) { return -1; + } playbackDeviceUID.push_back(ref); // output sub-devices in this example, so append the sub-device's UID to the CFArray CFArrayAppendValue(subDevicesArray, ref); @@ -1421,8 +1500,9 @@ OSStatus JackCoreAudioAdapter::CreateAggregateDeviceAux(vector<AudioDeviceID> ca CFRelease(aggDeviceDict); CFRelease(subDevicesArray); - if (subDevicesArrayClock) + if (subDevicesArrayClock) { CFRelease(subDevicesArrayClock); + } // release the device UID for (UInt32 i = 0; i < captureDeviceUID.size(); i++) { @@ -1479,23 +1559,112 @@ int JackCoreAudioAdapter::Close() DisposeBuffers(); CloseAUHAL(); RemoveListeners(); - if (fPluginID > 0) + if (fPluginID > 0) { DestroyAggregateDevice(); + } return 0; } -int JackCoreAudioAdapter::SetSampleRate ( jack_nframes_t sample_rate ) { - JackAudioAdapterInterface::SetHostSampleRate ( sample_rate ); +int JackCoreAudioAdapter::SetSampleRate(jack_nframes_t sample_rate) +{ + JackAudioAdapterInterface::SetHostSampleRate(sample_rate); Close(); return Open(); } -int JackCoreAudioAdapter::SetBufferSize ( jack_nframes_t buffer_size ) { - JackAudioAdapterInterface::SetHostBufferSize ( buffer_size ); +int JackCoreAudioAdapter::SetBufferSize(jack_nframes_t buffer_size) +{ + JackAudioAdapterInterface::SetHostBufferSize(buffer_size); Close(); return Open(); } +OSStatus JackCoreAudioAdapter::GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies) +{ + OSStatus err = noErr; + UInt32 outSize1, outSize2, outSize3; + Boolean outWritable; + + err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, &outWritable); + if (err == noErr) { + int stream_count = outSize1 / sizeof(UInt32); + AudioStreamID streamIDs[stream_count]; + AudioBufferList bufferList[stream_count]; + UInt32 streamLatency; + outSize2 = sizeof(UInt32); + + err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, streamIDs); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioDevicePropertyStreams err = %d", err); + return err; + } + + err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, &outWritable); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); + return err; + } + + for (int i = 0; i < stream_count; i++) { + err = AudioStreamGetProperty(streamIDs[i], 0, kAudioStreamPropertyLatency, &outSize2, &streamLatency); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioStreamPropertyLatency err = %d", err); + return err; + } + err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, bufferList); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); + return err; + } + // Push 'channel' time the stream latency + for (uint k = 0; k < bufferList->mBuffers[i].mNumberChannels; k++) { + latencies.push_back(streamLatency); + } + } + } + return err; +} + +int JackCoreAudioAdapter::GetLatency(int port_index, bool input) +{ + UInt32 size = sizeof(UInt32); + UInt32 value1 = 0; + UInt32 value2 = 0; + + OSStatus err = AudioDeviceGetProperty(fDeviceID, 0, input, kAudioDevicePropertyLatency, &size, &value1); + if (err != noErr) { + jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); + } + err = AudioDeviceGetProperty(fDeviceID, 0, input, kAudioDevicePropertySafetyOffset, &size, &value2); + if (err != noErr) { + jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); + } + + // TODO : add stream latency + + return value1 + value2 + fAdaptedBufferSize; +} + +int JackCoreAudioAdapter::GetInputLatency(int port_index) +{ + if (port_index < int(fInputLatencies.size())) { + return GetLatency(port_index, true) + fInputLatencies[port_index]; + } else { + // No stream latency + return GetLatency(port_index, true); + } +} + +int JackCoreAudioAdapter::GetOutputLatency(int port_index) +{ + if (port_index < int(fOutputLatencies.size())) { + return GetLatency(port_index, false) + fOutputLatencies[port_index]; + } else { + // No stream latency + return GetLatency(port_index, false); + } +} + } // namespace #ifdef __cplusplus @@ -1513,8 +1682,8 @@ extern "C" value.i = -1; jack_driver_descriptor_add_parameter(desc, &filler, "channels", 'c', JackDriverParamInt, &value, NULL, "Maximum number of channels", "Maximum number of channels. If -1, max possible number of channels will be used"); - jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used"); - jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used"); + jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", "Maximum number of input channels. If -1, max possible number of input channels will be used"); + jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", "Maximum number of output channels. If -1, max possible number of output channels will be used"); value.str[0] = 0; jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Input CoreAudio device name", NULL); diff --git a/macosx/coreaudio/JackCoreAudioAdapter.h b/macosx/coreaudio/JackCoreAudioAdapter.h index f002933f..a276ea39 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.h +++ b/macosx/coreaudio/JackCoreAudioAdapter.h @@ -41,7 +41,7 @@ typedef UInt8 CAAudioHardwareDeviceSectionID; #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) #define WAIT_COUNTER 60 - + /*! \brief Audio adapter using CoreAudio API. */ @@ -53,16 +53,19 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface AudioUnit fAUHAL; AudioBufferList* fInputData; - + char fCaptureUID[256]; char fPlaybackUID[256]; - + bool fCapturing; bool fPlaying; AudioDeviceID fDeviceID; // Used "duplex" device AudioObjectID fPluginID; // Used for aggregate device + vector<int> fInputLatencies; + vector<int> fOutputLatencies; + bool fState; AudioUnitRenderActionFlags* fActionFags; @@ -93,13 +96,14 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface OSStatus GetDefaultInputDevice(AudioDeviceID* id); OSStatus GetDefaultOutputDevice(AudioDeviceID* id); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); + AudioDeviceID GetDeviceIDFromName(const char* name); // Setup OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); OSStatus DestroyAggregateDevice(); bool IsAggregateDevice(AudioDeviceID device); - + int SetupDevices(const char* capture_driver_uid, const char* playback_driver_uid, char* capture_driver_name, @@ -126,14 +130,17 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface int SetupBufferSize(jack_nframes_t buffer_size); int SetupSampleRate(jack_nframes_t samplerate); int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); - + int SetupBuffers(int inchannels); void DisposeBuffers(); void CloseAUHAL(); - + int AddListeners(); void RemoveListeners(); + int GetLatency(int port_index, bool input); + OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies); + public: JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); @@ -146,8 +153,12 @@ class JackCoreAudioAdapter : public JackAudioAdapterInterface virtual int SetSampleRate(jack_nframes_t sample_rate); virtual int SetBufferSize(jack_nframes_t buffer_size); + virtual int GetInputLatency(int port_index); + virtual int GetOutputLatency(int port_index); }; -} + + +} // end of namepace #ifdef __cplusplus extern "C" diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 1f7de3b4..e98dc078 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -203,16 +203,16 @@ static void ParseChannelList(const string& list, vector<int>& result) } } -OSStatus JackCoreAudioDriver::Render(void *inRefCon, - AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, +OSStatus JackCoreAudioDriver::Render(void* inRefCon, + AudioUnitRenderActionFlags* ioActionFlags, + const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, - AudioBufferList *ioData) + AudioBufferList* ioData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inRefCon; driver->fActionFags = ioActionFlags; - driver->fCurrentTime = (AudioTimeStamp *)inTimeStamp; + driver->fCurrentTime = inTimeStamp; driver->fDriverOutputData = ioData; // Setup threaded based log function et get RT thread parameters once... @@ -475,7 +475,7 @@ OSStatus JackCoreAudioDriver::GetDefaultInputDevice(AudioDeviceID* id) } if (inDefault == 0) { - jack_error("Error : input device is 0, please select a correct one !!"); + jack_error("Error: default input device is 0, please select a correct one !!"); return -1; } jack_log("GetDefaultInputDevice: input = %ld ", inDefault); @@ -494,7 +494,7 @@ OSStatus JackCoreAudioDriver::GetDefaultOutputDevice(AudioDeviceID* id) } if (outDefault == 0) { - jack_error("Error : output device is 0, please select a correct one !!"); + jack_error("Error: default output device is 0, please select a correct one !!"); return -1; } jack_log("GetDefaultOutputDevice: output = %ld", outDefault); @@ -511,17 +511,65 @@ OSStatus JackCoreAudioDriver::GetDeviceNameFromID(AudioDeviceID id, char* name) OSStatus JackCoreAudioDriver::GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput) { OSStatus err = noErr; - UInt32 outSize; + UInt32 outSize; Boolean outWritable; channelCount = 0; err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, &outWritable); if (err == noErr) { - AudioBufferList bufferList[outSize]; + int stream_count = outSize / sizeof(AudioBufferList); + AudioBufferList bufferList[stream_count]; err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize, bufferList); if (err == noErr) { - for (unsigned int i = 0; i < bufferList->mNumberBuffers; i++) { + for (uint i = 0; i < bufferList->mNumberBuffers; i++) { channelCount += bufferList->mBuffers[i].mNumberChannels; + //jack_info("GetTotalChannels stream = %d channels = %d", i, bufferList->mBuffers[i].mNumberChannels); + } + } + } + return err; +} + +OSStatus JackCoreAudioDriver::GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies) +{ + OSStatus err = noErr; + UInt32 outSize1, outSize2, outSize3; + Boolean outWritable; + + err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, &outWritable); + if (err == noErr) { + int stream_count = outSize1 / sizeof(UInt32); + AudioStreamID streamIDs[stream_count]; + AudioBufferList bufferList[stream_count]; + UInt32 streamLatency; + outSize2 = sizeof(UInt32); + + err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreams, &outSize1, streamIDs); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioDevicePropertyStreams err = %d", err); + return err; + } + + err = AudioDeviceGetPropertyInfo(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, &outWritable); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); + return err; + } + + for (int i = 0; i < stream_count; i++) { + err = AudioStreamGetProperty(streamIDs[i], 0, kAudioStreamPropertyLatency, &outSize2, &streamLatency); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioStreamPropertyLatency err = %d", err); + return err; + } + err = AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyStreamConfiguration, &outSize3, bufferList); + if (err != noErr) { + jack_error("GetStreamLatencies kAudioDevicePropertyStreamConfiguration err = %d", err); + return err; + } + // Push 'channel' time the stream latency + for (uint k = 0; k < bufferList->mBuffers[i].mNumberChannels; k++) { + latencies.push_back(streamLatency); } } } @@ -1787,49 +1835,69 @@ void JackCoreAudioDriver::UpdateLatencies() { UInt32 size; OSStatus err; - jack_latency_range_t range; - range.max = fEngineControl->fBufferSize; - range.min = fEngineControl->fBufferSize; + jack_latency_range_t input_range; + jack_latency_range_t output_range; + jack_latency_range_t monitor_range; + + // Get Input latency + size = sizeof(UInt32); + UInt32 value1 = 0; + UInt32 value2 = 0; + err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); + if (err != noErr) { + jack_error("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); + } + err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); + if (err != noErr) { + jack_error("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); + } + + input_range.min = input_range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; + + // Get input stream latencies + vector<int> input_latencies; + err = GetStreamLatencies(fDeviceID, true, input_latencies); for (int i = 0; i < fCaptureChannels; i++) { - size = sizeof(UInt32); - UInt32 value1 = 0; - UInt32 value2 = 0; - err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertyLatency, &size, &value1); if (err != noErr) { - jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); - } - err = AudioDeviceGetProperty(fDeviceID, 0, true, kAudioDevicePropertySafetyOffset, &size, &value2); - if (err != noErr) { - jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); + input_range.min += input_latencies[i]; + input_range.max += input_latencies[i]; } + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); + } - range.min = range.max = fEngineControl->fBufferSize + value1 + value2 + fCaptureLatency; - fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range); + // Get Output latency + size = sizeof(UInt32); + value1 = 0; + value2 = 0; + err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); + if (err != noErr) { + jack_error("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); + } + err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); + if (err != noErr) { + jack_error("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); } + // Get output stream latencies + vector<int> output_latencies; + err = GetStreamLatencies(fDeviceID, false, output_latencies); + + // Add more latency if "async" mode is used... + output_range.min = output_range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) + ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency; + for (int i = 0; i < fPlaybackChannels; i++) { - size = sizeof(UInt32); - UInt32 value1 = 0; - UInt32 value2 = 0; - err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyLatency, &size, &value1); if (err != noErr) { - jack_log("AudioDeviceGetProperty kAudioDevicePropertyLatency error"); + output_range.min += output_latencies[i]; + output_range.max += output_latencies[i]; } - err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertySafetyOffset, &size, &value2); - if (err != noErr) { - jack_log("AudioDeviceGetProperty kAudioDevicePropertySafetyOffset error"); - } - - // Add more latency if "async" mode is used... - range.min = range.max - = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize * fIOUsage) + value1 + value2 + fPlaybackLatency; - fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range); + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); // Monitor port if (fWithMonitorPorts) { - range.min = range.max = fEngineControl->fBufferSize; - fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range); + monitor_range.min = monitor_range.max = fEngineControl->fBufferSize; + fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); } } } diff --git a/macosx/coreaudio/JackCoreAudioDriver.h b/macosx/coreaudio/JackCoreAudioDriver.h index 71b27a6e..0964dea4 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.h +++ b/macosx/coreaudio/JackCoreAudioDriver.h @@ -64,7 +64,7 @@ class JackCoreAudioDriver : public JackAudioDriver AudioObjectID fPluginID; // Used for aggregate device AudioUnitRenderActionFlags* fActionFags; - AudioTimeStamp* fCurrentTime; + const AudioTimeStamp* fCurrentTime; bool fState; bool fHogged; @@ -107,6 +107,7 @@ class JackCoreAudioDriver : public JackAudioDriver OSStatus GetDefaultOutputDevice(AudioDeviceID* id); OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); + OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies); // Setup OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); diff --git a/posix/JackNetUnixSocket.cpp b/posix/JackNetUnixSocket.cpp index 0512903e..52fe30f1 100644 --- a/posix/JackNetUnixSocket.cpp +++ b/posix/JackNetUnixSocket.cpp @@ -24,12 +24,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { //utility ********************************************************************************************************* - int GetHostName ( char * name, int size ) + int GetHostName(char * name, int size) { - if ( gethostname ( name, size ) == SOCKET_ERROR ) - { - jack_error ( "Can't get 'hostname' : %s", strerror ( NET_ERROR_CODE ) ); - strcpy ( name, "default" ); + if (gethostname(name, size) == SOCKET_ERROR) { + jack_error("Can't get 'hostname' : %s", strerror(NET_ERROR_CODE)); + strcpy(name, "default"); return SOCKET_ERROR; } return 0; @@ -42,29 +41,29 @@ namespace Jack fPort = 0; fTimeOut = 0; fSendAddr.sin_family = AF_INET; - fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); - memset ( &fSendAddr.sin_zero, 0, 8 ); + fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); + memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; - fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); - memset ( &fRecvAddr.sin_zero, 0, 8 ); + fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); + memset(&fRecvAddr.sin_zero, 0, 8); } - JackNetUnixSocket::JackNetUnixSocket ( const char* ip, int port ) + JackNetUnixSocket::JackNetUnixSocket(const char* ip, int port) { fSockfd = 0; fPort = port; fTimeOut = 0; fSendAddr.sin_family = AF_INET; - fSendAddr.sin_port = htons ( port ); - inet_aton ( ip, &fSendAddr.sin_addr ); - memset ( &fSendAddr.sin_zero, 0, 8 ); + fSendAddr.sin_port = htons(port); + inet_aton(ip, &fSendAddr.sin_addr); + memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; - fRecvAddr.sin_port = htons ( port ); - fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); - memset ( &fRecvAddr.sin_zero, 0, 8 ); + fRecvAddr.sin_port = htons(port); + fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); + memset(&fRecvAddr.sin_zero, 0, 8); } - JackNetUnixSocket::JackNetUnixSocket ( const JackNetUnixSocket& socket ) + JackNetUnixSocket::JackNetUnixSocket(const JackNetUnixSocket& socket) { fSockfd = 0; fTimeOut = 0; @@ -78,10 +77,9 @@ namespace Jack Close(); } - JackNetUnixSocket& JackNetUnixSocket::operator= ( const JackNetUnixSocket& socket ) + JackNetUnixSocket& JackNetUnixSocket::operator=(const JackNetUnixSocket& socket) { - if ( this != &socket ) - { + if (this != &socket) { fSockfd = 0; fPort = socket.fPort; fSendAddr = socket.fSendAddr; @@ -93,84 +91,106 @@ namespace Jack //socket*********************************************************************************************************** int JackNetUnixSocket::NewSocket() { - if ( fSockfd ) - { + if (fSockfd) { Close(); Reset(); } - fSockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); + fSockfd = socket(AF_INET, SOCK_DGRAM, 0); /* Enable address reuse */ int res, on = 1; - if ((res = setsockopt( fSockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) { + if ((res = setsockopt(fSockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0) { StrError(NET_ERROR_CODE); } - return fSockfd; } + bool JackNetUnixSocket::IsLocal(char* ip) + { + if (strcmp(ip, "127.0.0.1") == 0) { + return true; + } + + char host_name[32]; + gethostname(host_name, sizeof(host_name)); + + struct hostent* host = gethostbyname(host_name); + if (host) { + for (int i = 0; host->h_addr_list[i] != 0; ++i) { + struct in_addr addr; + memcpy(&addr, host->h_addr_list[i], sizeof(struct in_addr)); + if (strcmp(inet_ntoa(addr), ip) == 0) { + return true; + } + } + return false; + } else { + return false; + } + } + int JackNetUnixSocket::Bind() { - return bind ( fSockfd, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), sizeof ( socket_address_t ) ); + return bind(fSockfd, reinterpret_cast<socket_address_t*>(&fRecvAddr), sizeof(socket_address_t)); } - int JackNetUnixSocket::BindWith ( const char* ip ) + int JackNetUnixSocket::BindWith(const char* ip) { - int addr_conv = inet_aton ( ip, &fRecvAddr.sin_addr ); - if ( addr_conv < 0 ) + int addr_conv = inet_aton(ip, &fRecvAddr.sin_addr); + if (addr_conv < 0) return addr_conv; return Bind(); } - int JackNetUnixSocket::BindWith ( int port ) + int JackNetUnixSocket::BindWith(int port) { - fRecvAddr.sin_port = htons ( port ); + fRecvAddr.sin_port = htons(port); return Bind(); } int JackNetUnixSocket::Connect() { - return connect ( fSockfd, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) ); + return connect(fSockfd, reinterpret_cast<socket_address_t*>(&fSendAddr), sizeof(socket_address_t)); } - int JackNetUnixSocket::ConnectTo ( const char* ip ) + int JackNetUnixSocket::ConnectTo(const char* ip) { - int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); - if ( addr_conv < 0 ) + int addr_conv = inet_aton(ip, &fSendAddr.sin_addr); + if (addr_conv < 0) return addr_conv; return Connect(); } void JackNetUnixSocket::Close() { - if ( fSockfd ) - close ( fSockfd ); + if (fSockfd) + close(fSockfd); fSockfd = 0; } void JackNetUnixSocket::Reset() { fSendAddr.sin_family = AF_INET; - fSendAddr.sin_port = htons ( fPort ); - fSendAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); - memset ( &fSendAddr.sin_zero, 0, 8 ); + fSendAddr.sin_port = htons(fPort); + fSendAddr.sin_addr.s_addr = htonl(INADDR_ANY); + memset(&fSendAddr.sin_zero, 0, 8); fRecvAddr.sin_family = AF_INET; - fRecvAddr.sin_port = htons ( fPort ); - fRecvAddr.sin_addr.s_addr = htonl ( INADDR_ANY ); - memset ( &fRecvAddr.sin_zero, 0, 8 ); + fRecvAddr.sin_port = htons(fPort); + fRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); + memset(&fRecvAddr.sin_zero, 0, 8); } bool JackNetUnixSocket::IsSocket() { - return ( fSockfd ) ? true : false; + return(fSockfd) ? true : false; } //IP/PORT*********************************************************************************************************** - void JackNetUnixSocket::SetPort ( int port ) + void JackNetUnixSocket::SetPort(int port) { fPort = port; - fSendAddr.sin_port = htons ( port ); - fRecvAddr.sin_port = htons ( port ); + fSendAddr.sin_port = htons(port); + fRecvAddr.sin_port = htons(port); } int JackNetUnixSocket::GetPort() @@ -179,54 +199,54 @@ namespace Jack } //address*********************************************************************************************************** - int JackNetUnixSocket::SetAddress ( const char* ip, int port ) + int JackNetUnixSocket::SetAddress(const char* ip, int port) { - int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); - if ( addr_conv < 0 ) + int addr_conv = inet_aton(ip, &fSendAddr.sin_addr); + if (addr_conv < 0) return addr_conv; - fSendAddr.sin_port = htons ( port ); + fSendAddr.sin_port = htons(port); return 0; } char* JackNetUnixSocket::GetSendIP() { - return inet_ntoa ( fSendAddr.sin_addr ); + return inet_ntoa(fSendAddr.sin_addr); } char* JackNetUnixSocket::GetRecvIP() { - return inet_ntoa ( fRecvAddr.sin_addr ); + return inet_ntoa(fRecvAddr.sin_addr); } //utility************************************************************************************************************ - int JackNetUnixSocket::GetName ( char* name ) + int JackNetUnixSocket::GetName(char* name) { - return gethostname ( name, 255 ); + return gethostname(name, 255); } - int JackNetUnixSocket::JoinMCastGroup ( const char* ip ) + int JackNetUnixSocket::JoinMCastGroup(const char* ip) { struct ip_mreq multicast_req; - inet_aton ( ip, &multicast_req.imr_multiaddr ); - multicast_req.imr_interface.s_addr = htonl ( INADDR_ANY ); - return SetOption ( IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof ( multicast_req ) ); + inet_aton(ip, &multicast_req.imr_multiaddr); + multicast_req.imr_interface.s_addr = htonl(INADDR_ANY); + return SetOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, &multicast_req, sizeof(multicast_req)); } //options************************************************************************************************************ - int JackNetUnixSocket::SetOption ( int level, int optname, const void* optval, socklen_t optlen ) + int JackNetUnixSocket::SetOption(int level, int optname, const void* optval, socklen_t optlen) { - return setsockopt ( fSockfd, level, optname, optval, optlen ); + return setsockopt(fSockfd, level, optname, optval, optlen); } - int JackNetUnixSocket::GetOption ( int level, int optname, void* optval, socklen_t* optlen ) + int JackNetUnixSocket::GetOption(int level, int optname, void* optval, socklen_t* optlen) { - return getsockopt ( fSockfd, level, optname, optval, optlen ); + return getsockopt(fSockfd, level, optname, optval, optlen); } //timeout************************************************************************************************************ #if defined(__sun__) || defined(sun) - int JackNetUnixSocket::SetTimeOut ( int us ) + int JackNetUnixSocket::SetTimeOut(int us) { int flags; fTimeOut = us; @@ -261,7 +281,7 @@ namespace Jack do { res = select(fSockfd + 1, &fdset, NULL, NULL, &tv); - } while (res < 0 && errno == EINTR); + } while(res < 0 && errno == EINTR); if (res < 0) { return res; @@ -290,7 +310,7 @@ namespace Jack do { res = select(fSockfd + 1, NULL, &fdset, NULL, &tv); - } while (res < 0 && errno == EINTR); + } while(res < 0 && errno == EINTR); if (res < 0) { return res; @@ -304,30 +324,27 @@ namespace Jack } #else - int JackNetUnixSocket::SetTimeOut ( int us ) + int JackNetUnixSocket::SetTimeOut(int us) { - jack_log ( "JackNetUnixSocket::SetTimeout %d usecs", us ); + jack_log("JackNetUnixSocket::SetTimeout %d usecs", us); //negative timeout, or exceding 10s, return - if ( ( us < 0 ) || ( us > 10000000 ) ) + if ((us < 0) ||(us > 10000000)) return SOCKET_ERROR; struct timeval timeout; //less than 1sec - if ( us < 1000000 ) - { + if (us < 1000000) { timeout.tv_sec = 0; timeout.tv_usec = us; - } + } else { //more than 1sec - else - { - float sec = static_cast<float> ( us ) / 1000000.f; - timeout.tv_sec = ( int ) sec; - float usec = ( sec - static_cast<float> ( timeout.tv_sec ) ) * 1000000; - timeout.tv_usec = ( int ) usec; + float sec = static_cast<float>(us) / 1000000.f; + timeout.tv_sec =(int) sec; + float usec = (sec - static_cast<float>(timeout.tv_sec)) * 1000000; + timeout.tv_usec =(int) usec; } - return SetOption ( SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof ( timeout ) ); + return SetOption(SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); } #endif @@ -335,72 +352,72 @@ namespace Jack int JackNetUnixSocket::SetLocalLoop() { char disable = 0; - return SetOption ( IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof ( disable ) ); + return SetOption(IPPROTO_IP, IP_MULTICAST_LOOP, &disable, sizeof(disable)); } //network operations************************************************************************************************** - int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags ) + int JackNetUnixSocket::SendTo(const void* buffer, size_t nbytes, int flags) { #if defined(__sun__) || defined(sun) if (WaitWrite() < 0) return -1; #endif - return sendto ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), sizeof ( socket_address_t ) ); + return sendto(fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*>(&fSendAddr), sizeof(socket_address_t)); } - int JackNetUnixSocket::SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ) + int JackNetUnixSocket::SendTo(const void* buffer, size_t nbytes, int flags, const char* ip) { - int addr_conv = inet_aton ( ip, &fSendAddr.sin_addr ); - if ( addr_conv < 1 ) + int addr_conv = inet_aton(ip, &fSendAddr.sin_addr); + if (addr_conv < 1) return addr_conv; #if defined(__sun__) || defined(sun) if (WaitWrite() < 0) return -1; #endif - return SendTo ( buffer, nbytes, flags ); + return SendTo(buffer, nbytes, flags); } - int JackNetUnixSocket::Send ( const void* buffer, size_t nbytes, int flags ) + int JackNetUnixSocket::Send(const void* buffer, size_t nbytes, int flags) { #if defined(__sun__) || defined(sun) if (WaitWrite() < 0) return -1; #endif - return send ( fSockfd, buffer, nbytes, flags ); + return send(fSockfd, buffer, nbytes, flags); } - int JackNetUnixSocket::RecvFrom ( void* buffer, size_t nbytes, int flags ) + int JackNetUnixSocket::RecvFrom(void* buffer, size_t nbytes, int flags) { - socklen_t addr_len = sizeof ( socket_address_t ); + socklen_t addr_len = sizeof(socket_address_t); #if defined(__sun__) || defined(sun) if (WaitRead() < 0) return -1; #endif - return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fRecvAddr ), &addr_len ); + return recvfrom(fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*>(&fRecvAddr), &addr_len); } - int JackNetUnixSocket::Recv ( void* buffer, size_t nbytes, int flags ) + int JackNetUnixSocket::Recv(void* buffer, size_t nbytes, int flags) { #if defined(__sun__) || defined(sun) if (WaitRead() < 0) return -1; #endif - return recv ( fSockfd, buffer, nbytes, flags ); + return recv(fSockfd, buffer, nbytes, flags); } - int JackNetUnixSocket::CatchHost ( void* buffer, size_t nbytes, int flags ) + int JackNetUnixSocket::CatchHost(void* buffer, size_t nbytes, int flags) { - socklen_t addr_len = sizeof ( socket_address_t ); + socklen_t addr_len = sizeof(socket_address_t); #if defined(__sun__) || defined(sun) if (WaitRead() < 0) return -1; #endif - return recvfrom ( fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*> ( &fSendAddr ), &addr_len ); + return recvfrom(fSockfd, buffer, nbytes, flags, reinterpret_cast<socket_address_t*>(&fSendAddr), &addr_len); } net_error_t JackNetUnixSocket::GetError() { - switch ( errno ) + switch(errno) { case EAGAIN: case ETIMEDOUT: diff --git a/posix/JackNetUnixSocket.h b/posix/JackNetUnixSocket.h index a1be3b02..6476e216 100644 --- a/posix/JackNetUnixSocket.h +++ b/posix/JackNetUnixSocket.h @@ -55,53 +55,55 @@ namespace Jack public: JackNetUnixSocket(); - JackNetUnixSocket ( const char* ip, int port ); - JackNetUnixSocket ( const JackNetUnixSocket& ); + JackNetUnixSocket(const char* ip, int port); + JackNetUnixSocket(const JackNetUnixSocket&); ~JackNetUnixSocket(); - JackNetUnixSocket& operator= ( const JackNetUnixSocket& socket ); + JackNetUnixSocket& operator=(const JackNetUnixSocket& socket); //socket management int NewSocket(); int Bind(); - int BindWith ( const char* ip ); - int BindWith ( int port ); + int BindWith(const char* ip); + int BindWith(int port); int Connect(); - int ConnectTo ( const char* ip ); + int ConnectTo(const char* ip); void Close(); void Reset(); bool IsSocket(); //IP/PORT management - void SetPort ( int port ); + void SetPort(int port); int GetPort(); //address management - int SetAddress ( const char* ip, int port ); + int SetAddress(const char* ip, int port); char* GetSendIP(); char* GetRecvIP(); //utility - int GetName ( char* name ); - int JoinMCastGroup ( const char* mcast_ip ); + int GetName(char* name); + int JoinMCastGroup(const char* mcast_ip); //options management - int SetOption ( int level, int optname, const void* optval, socklen_t optlen ); - int GetOption ( int level, int optname, void* optval, socklen_t* optlen ); + int SetOption(int level, int optname, const void* optval, socklen_t optlen); + int GetOption(int level, int optname, void* optval, socklen_t* optlen); //timeout - int SetTimeOut ( int us ); + int SetTimeOut(int us); //disable local loop int SetLocalLoop(); + bool IsLocal(char* ip); + //network operations - int SendTo ( const void* buffer, size_t nbytes, int flags ); - int SendTo ( const void* buffer, size_t nbytes, int flags, const char* ip ); - int Send ( const void* buffer, size_t nbytes, int flags ); - int RecvFrom ( void* buffer, size_t nbytes, int flags ); - int Recv ( void* buffer, size_t nbytes, int flags ); - int CatchHost ( void* buffer, size_t nbytes, int flags ); + int SendTo(const void* buffer, size_t nbytes, int flags); + int SendTo(const void* buffer, size_t nbytes, int flags, const char* ip); + int Send(const void* buffer, size_t nbytes, int flags); + int RecvFrom(void* buffer, size_t nbytes, int flags); + int Recv(void* buffer, size_t nbytes, int flags); + int CatchHost(void* buffer, size_t nbytes, int flags); //error management net_error_t GetError(); diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index 4e500fbd..8418068d 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -652,10 +652,10 @@ extern "C" jack_driver_descriptor_add_parameter(desc, &filler, "wordlength", 'w', JackDriverParamInt, &value, NULL, "Word length", NULL); value.ui = OSS_DRIVER_DEF_INS; - jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamUInt, &value, NULL, "Capture channels", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamUInt, &value, NULL, "Capture channels", NULL); value.ui = OSS_DRIVER_DEF_OUTS; - jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamUInt, &value, NULL, "Playback channels", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamUInt, &value, NULL, "Playback channels", NULL); value.i = false; jack_driver_descriptor_add_parameter(desc, &filler, "excl", 'e', JackDriverParamBool, &value, NULL, "Exclusif (O_EXCL) access mode", NULL); diff --git a/tests/iodelay.cpp b/tests/iodelay.cpp index e6237741..66026fcb 100644 --- a/tests/iodelay.cpp +++ b/tests/iodelay.cpp @@ -76,9 +76,9 @@ MTDM::MTDM (void) : _cnt (0), _inv (0) for (i = 0, F = _freq; i < 5; i++, F++) { - F->p = 128; - F->xa = F->ya = 0.0f; - F->xf = F->yf = 0.0f; + F->p = 128; + F->xa = F->ya = 0.0f; + F->xf = F->yf = 0.0f; } } @@ -91,28 +91,28 @@ int MTDM::process (size_t len, float *ip, float *op) while (len--) { vop = 0.0f; - vip = *ip++; - for (i = 0, F = _freq; i < 5; i++, F++) - { - a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; - F->p += F->f; - c = cosf (a); - s = -sinf (a); - vop += F->a * s; - F->xa += s * vip; - F->ya += c * vip; - } - *op++ = vop; - if (++_cnt == 16) - { - for (i = 0, F = _freq; i < 5; i++, F++) - { - F->xf += 1e-3f * (F->xa - F->xf + 1e-20); - F->yf += 1e-3f * (F->ya - F->yf + 1e-20); - F->xa = F->ya = 0.0f; - } + vip = *ip++; + for (i = 0, F = _freq; i < 5; i++, F++) + { + a = 2 * (float) M_PI * (F->p & 65535) / 65536.0; + F->p += F->f; + c = cosf (a); + s = -sinf (a); + vop += F->a * s; + F->xa += s * vip; + F->ya += c * vip; + } + *op++ = vop; + if (++_cnt == 16) + { + for (i = 0, F = _freq; i < 5; i++, F++) + { + F->xf += 1e-3f * (F->xa - F->xf + 1e-20); + F->yf += 1e-3f * (F->ya - F->yf + 1e-20); + F->xa = F->ya = 0.0f; + } _cnt = 0; - } + } } return 0; @@ -133,17 +133,17 @@ int MTDM::resolve (void) _err = 0.0; for (i = 0; i < 4; i++) { - F++; - p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0; + F++; + p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0; if (_inv) p += 0.5f; - p -= floor (p); - p *= 8; - k = (int)(floor (p + 0.5)); - e = fabs (p - k); + p -= floor (p); + p *= 8; + k = (int)(floor (p + 0.5)); + e = fabs (p - k); if (e > _err) _err = e; if (e > 0.4) return 1; - d += m * (k & 7); - m *= 8; + d += m * (k & 7); + m *= 8; } _del = 16 * d; @@ -246,7 +246,7 @@ int main (int ac, char *av []) , mtdm._del, mtdm._del * t, systemic_latency, systemic_latency/2); if (mtdm._err > 0.2) printf (" ??"); - if (mtdm._inv) printf (" Inv"); + if (mtdm._inv) printf (" Inv"); printf ("\n"); } } diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index d4b8b870..83c7fbd9 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -221,8 +221,8 @@ extern "C" desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler); value.ui = 0; - jack_driver_descriptor_add_parameter(desc, &filler, "inchannels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", NULL); - jack_driver_descriptor_add_parameter(desc, &filler, "outchannels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", NULL); + jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", NULL); strcpy(value.str, "default input device"); jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set PortAudio device name", NULL); diff --git a/windows/portaudio/JackPortAudioDevices.cpp b/windows/portaudio/JackPortAudioDevices.cpp index 364cbabe..042186d2 100644 --- a/windows/portaudio/JackPortAudioDevices.cpp +++ b/windows/portaudio/JackPortAudioDevices.cpp @@ -28,15 +28,17 @@ PortAudioDevices::PortAudioDevices() PaError err; PaDeviceIndex id; jack_log("Initializing PortAudio..."); - if ((err = Pa_Initialize() ) == paNoError) { + if ((err = Pa_Initialize()) == paNoError) { fNumHostApi = Pa_GetHostApiCount(); fNumDevice = Pa_GetDeviceCount(); fDeviceInfo = new PaDeviceInfo*[fNumDevice]; - for (id = 0; id < fNumDevice; id++) + for (id = 0; id < fNumDevice; id++) { fDeviceInfo[id] = const_cast<PaDeviceInfo*>(Pa_GetDeviceInfo(id)); + } fHostName = new string[fNumHostApi]; - for (id = 0; id < fNumHostApi; id++) - fHostName[id] = string ( Pa_GetHostApiInfo(id)->name ); + for (id = 0; id < fNumHostApi; id++) { + fHostName[id] = string (Pa_GetHostApiInfo(id)->name); + } } else { jack_error("JackPortAudioDriver::Pa_Initialize error = %s", Pa_GetErrorText(err)); } @@ -56,70 +58,73 @@ PaDeviceIndex PortAudioDevices::GetNumDevice() return fNumDevice; } -PaDeviceInfo* PortAudioDevices::GetDeviceInfo ( PaDeviceIndex id ) +PaDeviceInfo* PortAudioDevices::GetDeviceInfo(PaDeviceIndex id) { return fDeviceInfo[id]; } -string PortAudioDevices::GetDeviceName ( PaDeviceIndex id ) +string PortAudioDevices::GetDeviceName(PaDeviceIndex id) { - return string ( fDeviceInfo[id]->name ); + return string(fDeviceInfo[id]->name); } -string PortAudioDevices::GetHostFromDevice ( PaDeviceInfo* device ) +string PortAudioDevices::GetHostFromDevice(PaDeviceInfo* device) { return fHostName[device->hostApi]; } -string PortAudioDevices::GetHostFromDevice ( PaDeviceIndex id ) +string PortAudioDevices::GetHostFromDevice(PaDeviceIndex id) { return fHostName[fDeviceInfo[id]->hostApi]; } -string PortAudioDevices::GetFullName ( PaDeviceIndex id ) +string PortAudioDevices::GetFullName(PaDeviceIndex id) { - string hostname = GetHostFromDevice ( id ); - string devicename = GetDeviceName ( id ); + string hostname = GetHostFromDevice(id); + string devicename = GetDeviceName(id); //some hostname are quite long...use shortcuts - if ( hostname.compare ( "Windows DirectSound" ) == 0 ) - hostname = string ( "DirectSound" ); - return ( hostname + "::" + devicename ); + if (hostname.compare("Windows DirectSound") == 0) { + hostname = string("DirectSound"); + } + return (hostname + "::" + devicename); } -string PortAudioDevices::GetFullName ( std::string hostname, std::string devicename ) +string PortAudioDevices::GetFullName(std::string hostname, std::string devicename) { //some hostname are quite long...use shortcuts - if ( hostname.compare ( "Windows DirectSound" ) == 0 ) - hostname = string ( "DirectSound" ); - return ( hostname + "::" + devicename ); + if (hostname.compare("Windows DirectSound") == 0) { + hostname = string("DirectSound"); + } + return (hostname + "::" + devicename); } -PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName ( string fullname, PaDeviceIndex& id, bool isInput ) +PaDeviceInfo* PortAudioDevices::GetDeviceFromFullName (string fullname, PaDeviceIndex& id, bool isInput) { PaDeviceInfo* ret = NULL; //no driver to find - if ( fullname.size() == 0 ) + if (fullname.size() == 0) { return NULL; + } //first get host and device names from fullname - string::size_type separator = fullname.find ( "::", 0 ); - if ( separator == 0 ) + string::size_type separator = fullname.find ("::", 0); + if (separator == 0) { return NULL; + } char* hostname = (char*)malloc(separator + 9); - fill_n ( hostname, separator + 9, 0 ); - fullname.copy ( hostname, separator ); + fill_n (hostname, separator + 9, 0); + fullname.copy (hostname, separator); //we need the entire hostname, replace shortcuts - if ( strcmp ( hostname, "DirectSound" ) == 0 ) - strcpy ( hostname, "Windows DirectSound" ); - string devicename = fullname.substr ( separator + 2 ); + if (strcmp (hostname, "DirectSound") == 0) { + strcpy (hostname, "Windows DirectSound"); + } + string devicename = fullname.substr (separator + 2); //then find the corresponding device - for ( PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++ ) - { + for (PaDeviceIndex dev_id = 0; dev_id < fNumDevice; dev_id++) { bool flag = (isInput) ? (fDeviceInfo[dev_id]->maxInputChannels > 0) : (fDeviceInfo[dev_id]->maxOutputChannels > 0); - if ( ( GetHostFromDevice(dev_id).compare(hostname) == 0 ) - && ( GetDeviceName(dev_id).compare(devicename) == 0 ) - && flag ) - { + if ((GetHostFromDevice(dev_id).compare(hostname) == 0) + && (GetDeviceName(dev_id).compare(devicename) == 0) + && flag) { id = dev_id; ret = fDeviceInfo[dev_id]; } @@ -139,23 +144,16 @@ void PortAudioDevices::PrintSupportedStandardSampleRates(const PaStreamParameter PaError err; printCount = 0; - for (i = 0; standardSampleRates[i] > 0; i++) - { + for (i = 0; standardSampleRates[i] > 0; i++) { err = Pa_IsFormatSupported(inputParameters, outputParameters, standardSampleRates[i]); - if (err == paFormatIsSupported) - { - if (printCount == 0) - { + if (err == paFormatIsSupported) { + if (printCount == 0) { jack_info("\t%8.2f", standardSampleRates[i]); printCount = 1; - } - else if (printCount == 4) - { + } else if (printCount == 4) { jack_info(",\n\t%8.2f", standardSampleRates[i]); printCount = 1; - } - else - { + } else { jack_info(", %8.2f", standardSampleRates[i]); ++printCount; } @@ -170,17 +168,18 @@ void PortAudioDevices::PrintSupportedStandardSampleRates(const PaStreamParameter int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_input) { - string fullname = string ( devicename ); - PaDeviceInfo* device = GetDeviceFromFullName ( fullname, id, true ); - if ( device ) + string fullname = string (devicename); + PaDeviceInfo* device = GetDeviceFromFullName (fullname, id, true); + if (device) { max_input = device->maxInputChannels; - else - { + } else { id = Pa_GetDefaultInputDevice(); - if ( fullname.size() ) + if (fullname.size()) { jack_error("Can't open %s, PortAudio will use default input device.", devicename); - if ( id == paNoDevice ) + } + if (id == paNoDevice) { return -1; + } max_input = GetDeviceInfo(id)->maxInputChannels; } return id; @@ -188,17 +187,18 @@ int PortAudioDevices::GetInputDeviceFromName(const char* devicename, PaDeviceInd int PortAudioDevices::GetOutputDeviceFromName(const char* devicename, PaDeviceIndex& id, int& max_output) { - string fullname = string ( devicename ); - PaDeviceInfo* device = GetDeviceFromFullName ( fullname, id, false ); - if ( device ) + string fullname = string (devicename); + PaDeviceInfo* device = GetDeviceFromFullName (fullname, id, false); + if (device) { max_output = device->maxOutputChannels; - else - { + } else { id = Pa_GetDefaultOutputDevice(); - if ( fullname.size() ) + if (fullname.size()) { jack_error("Can't open %s, PortAudio will use default output device.", devicename); - if ( id == paNoDevice ) + } + if (id == paNoDevice) { return -1; + } max_output = GetDeviceInfo(id)->maxOutputChannels; } return id; @@ -208,57 +208,50 @@ void PortAudioDevices::DisplayDevicesNames() { PaDeviceIndex id; PaStreamParameters inputParameters, outputParameters; - jack_info ( "********************** Devices list, %d detected **********************", fNumDevice ); + jack_info ("********************** Devices list, %d detected **********************", fNumDevice); - for ( id = 0; id < fNumDevice; id++ ) - { - jack_info ( "-------- device #%d ------------------------------------------------", id ); + for (id = 0; id < fNumDevice; id++) { + jack_info ("-------- device #%d ------------------------------------------------", id); - if ( id == Pa_GetDefaultInputDevice() ) - { + if (id == Pa_GetDefaultInputDevice()) { jack_info("[ Default Input ]"); - } - else if ( id == Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi)->defaultInputDevice ) - { - const PaHostApiInfo *host_info = Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi ); - jack_info ( "[ Default %s Input ]", host_info->name ); + } else if (id == Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi)->defaultInputDevice) { + const PaHostApiInfo *host_info = Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi); + jack_info("[ Default %s Input ]", host_info->name); } - if ( id == Pa_GetDefaultOutputDevice() ) - { - jack_info ( "[ Default Output ]" ); - } - else if ( id == Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi )->defaultOutputDevice ) - { - const PaHostApiInfo *host_info = Pa_GetHostApiInfo ( fDeviceInfo[id]->hostApi ); - jack_info ( "[ Default %s Output ]", host_info->name ); + if (id == Pa_GetDefaultOutputDevice()) { + jack_info ("[ Default Output ]"); + } else if (id == Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi)->defaultOutputDevice) { + const PaHostApiInfo *host_info = Pa_GetHostApiInfo (fDeviceInfo[id]->hostApi); + jack_info("[ Default %s Output ]", host_info->name); } /* print device info fields */ - jack_info ( "Name = %s", GetFullName ( id ).c_str() ); - jack_info ( "Max inputs = %d", fDeviceInfo[id]->maxInputChannels ); - jack_info ( "Max outputs = %d", fDeviceInfo[id]->maxOutputChannels ); + jack_info ("Name = %s", GetFullName (id).c_str()); + jack_info ("Max inputs = %d", fDeviceInfo[id]->maxInputChannels); + jack_info ("Max outputs = %d", fDeviceInfo[id]->maxOutputChannels); #ifdef WIN32 /* ASIO specific latency information */ - if ( Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO ) - { + if (Pa_GetHostApiInfo(fDeviceInfo[id]->hostApi)->type == paASIO) { long minLatency, maxLatency, preferredLatency, granularity; - PaAsio_GetAvailableLatencyValues ( id, &minLatency, &maxLatency, &preferredLatency, &granularity ); + PaAsio_GetAvailableLatencyValues (id, &minLatency, &maxLatency, &preferredLatency, &granularity); - jack_info ( "ASIO minimum buffer size = %ld", minLatency ); - jack_info ( "ASIO maximum buffer size = %ld", maxLatency ); - jack_info ( "ASIO preferred buffer size = %ld", preferredLatency ); + jack_info ("ASIO minimum buffer size = %ld", minLatency); + jack_info ("ASIO maximum buffer size = %ld", maxLatency); + jack_info ("ASIO preferred buffer size = %ld", preferredLatency); - if ( granularity == -1 ) - jack_info ( "ASIO buffer granularity = power of 2" ); - else - jack_info ( "ASIO buffer granularity = %ld", granularity ); + if (granularity == -1) { + jack_info ("ASIO buffer granularity = power of 2"); + } else { + jack_info ("ASIO buffer granularity = %ld", granularity); + } } #endif - jack_info ( "Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate ); + jack_info ("Default sample rate = %8.2f", fDeviceInfo[id]->defaultSampleRate); /* poll for standard sample rates */ inputParameters.device = id; @@ -273,20 +266,24 @@ void PortAudioDevices::DisplayDevicesNames() outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ outputParameters.hostApiSpecificStreamInfo = NULL; } - jack_info ( "**************************** End of list ****************************" ); + jack_info("**************************** End of list ****************************"); } -bool PortAudioDevices::IsDuplex ( PaDeviceIndex id ) +bool PortAudioDevices::IsDuplex (PaDeviceIndex id) { //does the device has in and out facilities - if ( fDeviceInfo[id]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels ) + if (fDeviceInfo[id]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels) { return true; + } //else is another complementary device ? (search in devices with the same name) - for ( PaDeviceIndex i = 0; i < fNumDevice; i++ ) - if ( ( i != id ) && ( GetDeviceName ( i ) == GetDeviceName ( id ) ) ) - if ( ( fDeviceInfo[i]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels ) - || ( fDeviceInfo[i]->maxOutputChannels && fDeviceInfo[id]->maxInputChannels ) ) + for (PaDeviceIndex i = 0; i < fNumDevice; i++) { + if ((i != id) && (GetDeviceName (i) == GetDeviceName (id))) { + if ((fDeviceInfo[i]->maxInputChannels && fDeviceInfo[id]->maxOutputChannels) { + || (fDeviceInfo[i]->maxOutputChannels && fDeviceInfo[id]->maxInputChannels)) return true; + } + } + } //then the device isn't full duplex return false; } diff --git a/windows/portaudio/JackPortAudioDevices.h b/windows/portaudio/JackPortAudioDevices.h index a11d8b45..61b280d4 100644 --- a/windows/portaudio/JackPortAudioDevices.h +++ b/windows/portaudio/JackPortAudioDevices.h @@ -33,11 +33,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class PortAudioDevices { private: + PaHostApiIndex fNumHostApi; //number of hosts PaDeviceIndex fNumDevice; //number of devices PaDeviceInfo** fDeviceInfo; //array of device info std::string* fHostName; //array of host names (matched with host id's) + public: + PortAudioDevices(); ~PortAudioDevices(); @@ -48,12 +51,13 @@ class PortAudioDevices std::string GetHostFromDevice(PaDeviceIndex id); std::string GetFullName(PaDeviceIndex id); std::string GetFullName(std::string hostname, std::string devicename); - PaDeviceInfo* GetDeviceFromFullName(std::string fullname, PaDeviceIndex& id, bool isInput ); + PaDeviceInfo* GetDeviceFromFullName(std::string fullname, PaDeviceIndex& id, bool isInput); void PrintSupportedStandardSampleRates(const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters); int GetInputDeviceFromName(const char* name, PaDeviceIndex& device, int& in_max); int GetOutputDeviceFromName(const char* name, PaDeviceIndex& device, int& out_max); void DisplayDevicesNames(); - bool IsDuplex ( PaDeviceIndex id ); + bool IsDuplex(PaDeviceIndex id); + }; #endif diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 38cfc4a8..e5fe884c 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -31,225 +31,263 @@ using namespace std; namespace Jack { - int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, - unsigned long framesPerBuffer, - const PaStreamCallbackTimeInfo* timeInfo, - PaStreamCallbackFlags statusFlags, - void* userData) - { - JackPortAudioDriver* driver = (JackPortAudioDriver*)userData; - driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; - driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; - - MMCSSAcquireRealTime(GetCurrentThread()); - - if (statusFlags) { - if (statusFlags & paOutputUnderflow) - jack_error("JackPortAudioDriver::Render paOutputUnderflow"); - if (statusFlags & paInputUnderflow) - jack_error("JackPortAudioDriver::Render paInputUnderflow"); - if (statusFlags & paOutputOverflow) - jack_error("JackPortAudioDriver::Render paOutputOverflow"); - if (statusFlags & paInputOverflow) - jack_error("JackPortAudioDriver::Render paInputOverflow"); - if (statusFlags & paPrimingOutput) - jack_error("JackPortAudioDriver::Render paOutputUnderflow"); - - if (statusFlags != paPrimingOutput) { - jack_time_t cur_time = GetMicroSeconds(); - driver->NotifyXRun(cur_time, float(cur_time - driver->fBeginDateUst)); // Better this value than nothing... - } - } - // Setup threadded based log function - set_threaded_log_function(); - driver->CycleTakeBeginTime(); - return (driver->Process() == 0) ? paContinue : paAbort; +int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, + unsigned long framesPerBuffer, + const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags, + void* userData) +{ + JackPortAudioDriver* driver = (JackPortAudioDriver*)userData; + driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; + driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; + + MMCSSAcquireRealTime(GetCurrentThread()); + + if (statusFlags) { + if (statusFlags & paOutputUnderflow) + jack_error("JackPortAudioDriver::Render paOutputUnderflow"); + if (statusFlags & paInputUnderflow) + jack_error("JackPortAudioDriver::Render paInputUnderflow"); + if (statusFlags & paOutputOverflow) + jack_error("JackPortAudioDriver::Render paOutputOverflow"); + if (statusFlags & paInputOverflow) + jack_error("JackPortAudioDriver::Render paInputOverflow"); + if (statusFlags & paPrimingOutput) + jack_error("JackPortAudioDriver::Render paOutputUnderflow"); + + if (statusFlags != paPrimingOutput) { + jack_time_t cur_time = GetMicroSeconds(); + driver->NotifyXRun(cur_time, float(cur_time - driver->fBeginDateUst)); // Better this value than nothing... + } } - int JackPortAudioDriver::Read() - { - for (int i = 0; i < fCaptureChannels; i++) - memcpy(GetInputBuffer(i), fInputBuffer[i], sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); - return 0; - } + // Setup threadded based log function + set_threaded_log_function(); + driver->CycleTakeBeginTime(); + return (driver->Process() == 0) ? paContinue : paAbort; +} - int JackPortAudioDriver::Write() - { - for (int i = 0; i < fPlaybackChannels; i++) - memcpy(fOutputBuffer[i], GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); - return 0; +int JackPortAudioDriver::Read() +{ + for (int i = 0; i < fCaptureChannels; i++) { + memcpy(GetInputBuffer(i), fInputBuffer[i], sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } + return 0; +} - PaError JackPortAudioDriver::OpenStream(jack_nframes_t buffer_size) - { - PaStreamParameters inputParameters; - PaStreamParameters outputParameters; - - // Update parameters - inputParameters.device = fInputDevice; - inputParameters.channelCount = fCaptureChannels; - inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output - inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO - ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency - : 0; - inputParameters.hostApiSpecificStreamInfo = NULL; - - outputParameters.device = fOutputDevice; - outputParameters.channelCount = fPlaybackChannels; - outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output - outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO - ? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency - : 0; - outputParameters.hostApiSpecificStreamInfo = NULL; - - return Pa_OpenStream(&fStream, - (fInputDevice == paNoDevice) ? 0 : &inputParameters, - (fOutputDevice == paNoDevice) ? 0 : &outputParameters, - fEngineControl->fSampleRate, - buffer_size, - paNoFlag, // Clipping is on... - Render, - this); +int JackPortAudioDriver::Write() +{ + for (int i = 0; i < fPlaybackChannels; i++) { + memcpy(fOutputBuffer[i], GetOutputBuffer(i), sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize); } + return 0; +} - int JackPortAudioDriver::Open(jack_nframes_t buffer_size, - jack_nframes_t samplerate, - bool capturing, - bool playing, - int inchannels, - int outchannels, - bool monitor, - const char* capture_driver_uid, - const char* playback_driver_uid, - jack_nframes_t capture_latency, - jack_nframes_t playback_latency) - { - int in_max = 0; - int out_max = 0; - PaError err = paNoError; +PaError JackPortAudioDriver::OpenStream(jack_nframes_t buffer_size) +{ + PaStreamParameters inputParameters; + PaStreamParameters outputParameters; + + // Update parameters + inputParameters.device = fInputDevice; + inputParameters.channelCount = fCaptureChannels; + inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output + inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO + ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency + : 0; + inputParameters.hostApiSpecificStreamInfo = NULL; + + outputParameters.device = fOutputDevice; + outputParameters.channelCount = fPlaybackChannels; + outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output + outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO + ? Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency + : 0; + outputParameters.hostApiSpecificStreamInfo = NULL; + + return Pa_OpenStream(&fStream, + (fInputDevice == paNoDevice) ? 0 : &inputParameters, + (fOutputDevice == paNoDevice) ? 0 : &outputParameters, + fEngineControl->fSampleRate, + buffer_size, + paNoFlag, // Clipping is on... + Render, + this); +} - jack_log("JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld", - buffer_size, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate); +void JackPortAudioDriver::UpdateLatencies() +{ + jack_latency_range_t input_range; + jack_latency_range_t output_range; + jack_latency_range_t monitor_range; + + const PaStreamInfo* info = Pa_GetStreamInfo(fStream); + assert(info); - // Generic JackAudioDriver Open - if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) - return -1; + for (int i = 0; i < fCaptureChannels; i++) { + input_range.max = input_range.min = fEngineControl->fBufferSize + (info->inputLatency * fEngineControl->fSampleRate) + fCaptureLatency; + fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); + } - //get devices - if (capturing) { - if (fPaDevices->GetInputDeviceFromName(capture_driver_uid, fInputDevice, in_max) < 0) - goto error; + for (int i = 0; i < fPlaybackChannels; i++) { + output_range.max = output_range.min = (info->outputLatency * fEngineControl->fSampleRate) + fPlaybackLatency; + if (fEngineControl->fSyncMode) { + output_range.max = output_range.min += fEngineControl->fBufferSizey; + } else { + output_range.max = output_range.min += fEngineControl->fBufferSize * 2; } - if (playing) { - if (fPaDevices->GetOutputDeviceFromName(playback_driver_uid, fOutputDevice, out_max) < 0) - goto error; + fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); + if (fWithMonitorPorts) { + monitor_range.min = monitor_range.max = fEngineControl->fBufferSize; + fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); } + } +} - jack_log("JackPortAudioDriver::Open fInputDevice = %d, fOutputDevice %d", fInputDevice, fOutputDevice); +int JackPortAudioDriver::Open(jack_nframes_t buffer_size, + jack_nframes_t samplerate, + bool capturing, + bool playing, + int inchannels, + int outchannels, + bool monitor, + const char* capture_driver_uid, + const char* playback_driver_uid, + jack_nframes_t capture_latency, + jack_nframes_t playback_latency) +{ + int in_max = 0; + int out_max = 0; + PaError err = paNoError; - //default channels number required - if (inchannels == 0) { - jack_log("JackPortAudioDriver::Open setup max in channels = %ld", in_max); - inchannels = in_max; - } - if (outchannels == 0) { - jack_log("JackPortAudioDriver::Open setup max out channels = %ld", out_max); - outchannels = out_max; - } + fCaptureLatency = capture_latency; + fPlaybackLatency = playback_latency; - //too many channels required, take max available - if (inchannels > in_max) { - jack_error("This device has only %d available input channels.", in_max); - inchannels = in_max; - } - if (outchannels > out_max) { - jack_error("This device has only %d available output channels.", out_max); - outchannels = out_max; - } + jack_log("JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld", + buffer_size, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate); - // Core driver may have changed the in/out values - fCaptureChannels = inchannels; - fPlaybackChannels = outchannels; + // Generic JackAudioDriver Open + if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, + capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) { + return -1; + } - err = OpenStream(buffer_size); - if (err != paNoError) { - jack_error("Pa_OpenStream error %d = %s", err, Pa_GetErrorText(err)); + //get devices + if (capturing) { + if (fPaDevices->GetInputDeviceFromName(capture_driver_uid, fInputDevice, in_max) < 0) { goto error; } + } + if (playing) { + if (fPaDevices->GetOutputDeviceFromName(playback_driver_uid, fOutputDevice, out_max) < 0) { + goto error; + } + } + + jack_log("JackPortAudioDriver::Open fInputDevice = %d, fOutputDevice %d", fInputDevice, fOutputDevice); + + //default channels number required + if (inchannels == 0) { + jack_log("JackPortAudioDriver::Open setup max in channels = %ld", in_max); + inchannels = in_max; + } + if (outchannels == 0) { + jack_log("JackPortAudioDriver::Open setup max out channels = %ld", out_max); + outchannels = out_max; + } + + //too many channels required, take max available + if (inchannels > in_max) { + jack_error("This device has only %d available input channels.", in_max); + inchannels = in_max; + } + if (outchannels > out_max) { + jack_error("This device has only %d available output channels.", out_max); + outchannels = out_max; + } + + // Core driver may have changed the in/out values + fCaptureChannels = inchannels; + fPlaybackChannels = outchannels; + + err = OpenStream(buffer_size); + if (err != paNoError) { + jack_error("Pa_OpenStream error %d = %s", err, Pa_GetErrorText(err)); + goto error; + } #ifdef __APPLE__ - fEngineControl->fPeriod = fEngineControl->fPeriodUsecs * 1000; - fEngineControl->fComputation = 500 * 1000; - fEngineControl->fConstraint = fEngineControl->fPeriodUsecs * 1000; + fEngineControl->fPeriod = fEngineControl->fPeriodUsecs * 1000; + fEngineControl->fComputation = 500 * 1000; + fEngineControl->fConstraint = fEngineControl->fPeriodUsecs * 1000; #endif - assert(strlen(capture_driver_uid) < JACK_CLIENT_NAME_SIZE); - assert(strlen(playback_driver_uid) < JACK_CLIENT_NAME_SIZE); + assert(strlen(capture_driver_uid) < JACK_CLIENT_NAME_SIZE); + assert(strlen(playback_driver_uid) < JACK_CLIENT_NAME_SIZE); - strcpy(fCaptureDriverName, capture_driver_uid); - strcpy(fPlaybackDriverName, playback_driver_uid); + strcpy(fCaptureDriverName, capture_driver_uid); + strcpy(fPlaybackDriverName, playback_driver_uid); - return 0; + return 0; error: - JackAudioDriver::Close(); - jack_error("Can't open default PortAudio device"); - return -1; - } - - int JackPortAudioDriver::Close() - { - // Generic audio driver close - int res = JackAudioDriver::Close(); + JackAudioDriver::Close(); + jack_error("Can't open default PortAudio device"); + return -1; +} - jack_log("JackPortAudioDriver::Close"); - Pa_CloseStream(fStream); - return res; - } +int JackPortAudioDriver::Close() +{ + // Generic audio driver close + int res = JackAudioDriver::Close(); + jack_log("JackPortAudioDriver::Close"); + Pa_CloseStream(fStream); + return res; +} - int JackPortAudioDriver::Start() - { - jack_log("JackPortAudioDriver::Start"); - if (JackAudioDriver::Start() >= 0) { - PaError err = Pa_StartStream(fStream); - if (err == paNoError) { - return 0; - } - JackAudioDriver::Stop(); +int JackPortAudioDriver::Start() +{ + jack_log("JackPortAudioDriver::Start"); + if (JackAudioDriver::Start() >= 0) { + PaError err = Pa_StartStream(fStream); + if (err == paNoError) { + return 0; } - return -1; + JackAudioDriver::Stop(); } + return -1; +} - int JackPortAudioDriver::Stop() - { - jack_log("JackPortAudioDriver::Stop"); - PaError err = Pa_StopStream(fStream); - int res = (err == paNoError) ? 0 : -1; - if (JackAudioDriver::Stop() < 0) { - res = -1; - } - return res; +int JackPortAudioDriver::Stop() +{ + jack_log("JackPortAudioDriver::Stop"); + PaError err = Pa_StopStream(fStream); + int res = (err == paNoError) ? 0 : -1; + if (JackAudioDriver::Stop() < 0) { + res = -1; } + return res; +} - int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size) - { - PaError err; +int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size) +{ + PaError err; - if ((err = Pa_CloseStream(fStream)) != paNoError) { - jack_error("Pa_CloseStream error = %s", Pa_GetErrorText(err)); - return -1; - } + if ((err = Pa_CloseStream(fStream)) != paNoError) { + jack_error("Pa_CloseStream error = %s", Pa_GetErrorText(err)); + return -1; + } - err = OpenStream(buffer_size); - if (err != paNoError) { - jack_error("Pa_OpenStream error %d = %s", err, Pa_GetErrorText(err)); - return -1; - } else { - JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails - return 0; - } + err = OpenStream(buffer_size); + if (err != paNoError) { + jack_error("Pa_OpenStream error %d = %s", err, Pa_GetErrorText(err)); + return -1; + } else { + JackAudioDriver::SetBufferSize(buffer_size); // Generic change, never fails + return 0; } +} } // end of namespace diff --git a/windows/portaudio/JackPortAudioDriver.h b/windows/portaudio/JackPortAudioDriver.h index 894dbbbe..c40810d6 100644 --- a/windows/portaudio/JackPortAudioDriver.h +++ b/windows/portaudio/JackPortAudioDriver.h @@ -49,8 +49,8 @@ class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver PaStreamCallbackFlags statusFlags, void* userData); - void UpdateLatencies(); PaError OpenStream(jack_nframes_t buffer_size); + void UpdateLatencies(); public: |