From db132e1974650a220a66a4b7053c4cbc78cc2208 Mon Sep 17 00:00:00 2001 From: Devin Anderson Date: Sun, 20 Mar 2011 22:39:31 -0700 Subject: [PATCH] Update server control API with jackctl_server_open and jackctl_server_close (see http://trac.jackaudio.org/ticket/219 for rationale). Update drivers to support Start/Stop of slave drivers. Update dbus to use new jackctl_server_* functions. Freewheel driver is no longer an implicit slave of the master audio driver. Haven't tested freewheeling, and didn't update Solaris OSS driver. Tested slave addition by adding loopback driver, but don't have a slave driver in this branch on Linux platform to test with. --- common/JackAudioDriver.cpp | 20 +++++++ common/JackAudioDriver.h | 3 + common/JackControlAPI.cpp | 30 ++++++---- common/JackControlAPI.h | 12 +++- common/JackDriver.cpp | 30 ++++++++++ common/JackDriver.h | 2 + common/JackServer.cpp | 67 +++++++++++------------ common/Jackdmp.cpp | 64 +++++++++++++--------- common/jack/control.h | 26 ++++++++- dbus/controller.c | 23 +++++++- example-clients/server_control.cpp | 5 +- linux/alsa/JackAlsaDriver.cpp | 16 +++++- linux/firewire/JackFFADODriver.cpp | 18 ++++-- linux/freebob/JackFreebobDriver.cpp | 16 +++++- macosx/coreaudio/JackCoreAudioDriver.cpp | 41 ++++++++------ windows/portaudio/JackPortAudioDriver.cpp | 17 ++++-- 16 files changed, 278 insertions(+), 112 deletions(-) diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 19741d0f..de7616b3 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -313,6 +313,26 @@ int JackAudioDriver::ProcessGraphSync() return res; } +int JackAudioDriver::Start() +{ + int res = JackDriver::Start(); + if ((res >= 0) && fIsMaster) { + res = StartSlaves(); + } + return res; +} + +int JackAudioDriver::Stop() +{ + int res = JackDriver::Stop(); + if (fIsMaster) { + if (StopSlaves() < 0) { + res = -1; + } + } + return res; +} + void JackAudioDriver::WaitUntilNextCycle() { int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f)); diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 3127f4c1..8eaca692 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -92,6 +92,9 @@ class SERVER_EXPORT JackAudioDriver : public JackDriver virtual int Attach(); virtual int Detach(); + virtual int Start(); + virtual int Stop(); + virtual int Write(); virtual int SetBufferSize(jack_nframes_t buffer_size); diff --git a/common/JackControlAPI.cpp b/common/JackControlAPI.cpp index a87d1963..a3546a2a 100644 --- a/common/JackControlAPI.cpp +++ b/common/JackControlAPI.cpp @@ -826,6 +826,11 @@ EXPORT const JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr EXPORT bool jackctl_server_stop(jackctl_server *server_ptr) { server_ptr->engine->Stop(); + return true; +} + +EXPORT bool jackctl_server_close(jackctl_server *server_ptr) +{ server_ptr->engine->Close(); delete server_ptr->engine; @@ -853,7 +858,7 @@ EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr) } EXPORT bool -jackctl_server_start( +jackctl_server_open( jackctl_server *server_ptr, jackctl_driver *driver_ptr) { @@ -913,18 +918,8 @@ jackctl_server_start( goto fail_delete; } - rc = server_ptr->engine->Start(); - if (rc < 0) - { - jack_error("JackServer::Start() failed with %d", rc); - goto fail_close; - } - return true; -fail_close: - server_ptr->engine->Close(); - fail_delete: delete server_ptr->engine; server_ptr->engine = NULL; @@ -946,6 +941,19 @@ fail: return false; } +EXPORT bool +jackctl_server_start( + jackctl_server *server_ptr) +{ + int rc = server_ptr->engine->Start(); + bool result = rc >= 0; + if (! result) + { + jack_error("JackServer::Start() failed with %d", rc); + } + return result; +} + EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr) { return driver_ptr->desc_ptr->name; diff --git a/common/JackControlAPI.h b/common/JackControlAPI.h index d0b0cbc1..8e87d513 100644 --- a/common/JackControlAPI.h +++ b/common/JackControlAPI.h @@ -101,13 +101,21 @@ jackctl_server_get_drivers_list( jackctl_server_t * server); EXPORT bool -jackctl_server_start( +jackctl_server_open( jackctl_server_t * server, jackctl_driver_t * driver); +EXPORT bool +jackctl_server_start( + jackctl_server_t * server); + EXPORT bool jackctl_server_stop( - jackctl_server_t * server); + jackctl_server_t * server); + +EXPORT bool +jackctl_server_close( + jackctl_server_t * server); EXPORT const JSList * jackctl_server_get_parameters( diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index a2c6ccd6..b3aa0713 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -328,11 +328,41 @@ int JackDriver::Start() return 0; } +int JackDriver::StartSlaves() +{ + int res = 0; + list::const_iterator it; + for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { + 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; + } + } + return res; +} + int JackDriver::Stop() { return 0; } +int JackDriver::StopSlaves() +{ + int res = 0; + list::const_iterator it; + for (it = fSlaveList.begin(); it != fSlaveList.end(); it++) { + JackDriverInterface* slave = *it; + if (slave->Stop() < 0) + res = -1; + } + return res; +} + bool JackDriver::IsFixedBufferSize() { return true; diff --git a/common/JackDriver.h b/common/JackDriver.h index 6f230831..3fd7b860 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -198,7 +198,9 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface virtual int Write(); virtual int Start(); + virtual int StartSlaves(); virtual int Stop(); + virtual int StopSlaves(); virtual bool IsFixedBufferSize(); virtual int SetBufferSize(jack_nframes_t buffer_size); diff --git a/common/JackServer.cpp b/common/JackServer.cpp index a35cff62..e165badc 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -87,26 +87,18 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) goto fail_close3; } - if (fFreewheelDriver->Open() < 0) { // before engine open - jack_error("Cannot open driver"); - goto fail_close4; - } - if (fAudioDriver->Attach() < 0) { jack_error("Cannot attach audio driver"); - goto fail_close5; + goto fail_close4; } fFreewheelDriver->SetMaster(false); fAudioDriver->SetMaster(true); - fAudioDriver->AddSlave(fFreewheelDriver); // After ??? + //fAudioDriver->AddSlave(fFreewheelDriver); InitTime(); SetClockSource(fEngineControl->fClockSource); return 0; -fail_close5: - fFreewheelDriver->Close(); - fail_close4: fEngine->Close(); @@ -128,7 +120,9 @@ int JackServer::Close() fChannel.Close(); fAudioDriver->Detach(); fAudioDriver->Close(); - fFreewheelDriver->Close(); + if (fFreewheel) { + fFreewheelDriver->Close(); + } fEngine->Close(); // TODO: move that in reworked JackServerGlobals::Destroy() JackMessageBuffer::Destroy(); @@ -238,6 +232,7 @@ int JackServer::SetFreewheel(bool onoff) } else { fFreewheel = false; fFreewheelDriver->Stop(); + fFreewheelDriver->Close(); fGraphManager->Restore(&fConnectionState); // Restore previous connection state fEngine->NotifyFreewheel(onoff); fFreewheelDriver->SetMaster(false); @@ -250,6 +245,10 @@ int JackServer::SetFreewheel(bool onoff) fGraphManager->Save(&fConnectionState); // Save connection state fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); fEngine->NotifyFreewheel(onoff); + if (fFreewheelDriver->Open() < 0) { + jack_error("Cannot open freewheel driver"); + return -1; + } fFreewheelDriver->SetMaster(true); return fFreewheelDriver->Start(); } else { @@ -296,11 +295,11 @@ JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* dr if (slave == NULL) { delete info; return NULL; - } else { - slave->Attach(); - fAudioDriver->AddSlave(slave); - return info; } + slave->Attach(); + slave->SetMaster(false); + fAudioDriver->AddSlave(slave); + return info; } void JackServer::RemoveSlave(JackDriverInfo* info) @@ -322,32 +321,30 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par JackDriverInfo* info = new JackDriverInfo(); JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); - if (master == NULL || info == NULL) { + if (master == NULL) { delete info; - delete master; return -1; - } else { + } - // Get slaves list - std::list slave_list = fAudioDriver->GetSlaves(); - std::list::const_iterator it; + // Get slaves list + std::list slave_list = fAudioDriver->GetSlaves(); + std::list::const_iterator it; - // Move slaves in new master - for (it = slave_list.begin(); it != slave_list.end(); it++) { - JackDriverInterface* slave = *it; - master->AddSlave(slave); - } + // Move slaves in new master + for (it = slave_list.begin(); it != slave_list.end(); it++) { + JackDriverInterface* slave = *it; + master->AddSlave(slave); + } - // Delete old master - delete fDriverInfo; + // Delete old master + delete fDriverInfo; - // Activate master - fAudioDriver = master; - fDriverInfo = info; - fAudioDriver->Attach(); - fAudioDriver->SetMaster(true); - return fAudioDriver->Start(); - } + // Activate master + fAudioDriver = master; + fDriverInfo = info; + fAudioDriver->Attach(); + fAudioDriver->SetMaster(true); + return fAudioDriver->Start(); } //---------------------- diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index 2e8a78e7..602aca31 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -244,6 +244,10 @@ int main(int argc, char* argv[]) std::list slaves_list; std::list::iterator it; + // Assume that we fail. + int return_value = -1; + bool notify_sent = false; + copyright(stdout); #if defined(JACK_DBUS) && defined(__linux__) server_ctl = jackctl_server_create(audio_acquire, audio_release); @@ -285,7 +289,7 @@ int main(int argc, char* argv[]) jackctl_parameter_set_value(param, &value); } else { usage(stdout); - goto fail_free1; + goto destroy_server; } } break; @@ -402,7 +406,7 @@ int main(int argc, char* argv[]) case 'h': usage(stdout); - goto fail_free1; + goto destroy_server; } } @@ -423,14 +427,14 @@ int main(int argc, char* argv[]) if (!master_driver_name) { usage(stderr); - goto fail_free1; + goto destroy_server; } // Master driver master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name); if (master_driver_ctl == NULL) { fprintf(stderr, "Unknown driver \"%s\"\n", master_driver_name); - goto fail_free1; + goto destroy_server; } if (optind < argc) { @@ -442,7 +446,7 @@ int main(int argc, char* argv[]) if (master_driver_nargs == 0) { fprintf(stderr, "No driver specified ... hmm. JACK won't do" " anything when run like this.\n"); - goto fail_free1; + goto destroy_server; } master_driver_args = (char **) malloc(sizeof(char *) * master_driver_nargs); @@ -453,15 +457,16 @@ int main(int argc, char* argv[]) } if (jackctl_parse_driver_params(master_driver_ctl, master_driver_nargs, master_driver_args)) { - goto fail_free1; + goto destroy_server; } - // Setup signals then start server + // Setup signals signals = jackctl_setup_signals(0); - if (!jackctl_server_start(server_ctl, master_driver_ctl)) { - fprintf(stderr, "Failed to start server\n"); - goto fail_free1; + // Open server + if (! jackctl_server_open(server_ctl, master_driver_ctl)) { + fprintf(stderr, "Failed to open server\n"); + goto destroy_server; } // Slave drivers @@ -469,7 +474,7 @@ int main(int argc, char* argv[]) jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it); if (slave_driver_ctl == NULL) { fprintf(stderr, "Unknown driver \"%s\"\n", *it); - goto fail_free2; + goto close_server; } jackctl_server_add_slave(server_ctl, slave_driver_ctl); } @@ -477,6 +482,8 @@ int main(int argc, char* argv[]) // Loopback driver if (loopback > 0) { loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); + + // XX: What if this fails? if (loopback_driver_ctl != NULL) { const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl); param = jackctl_get_parameter(loopback_parameters, "channels"); @@ -486,6 +493,13 @@ int main(int argc, char* argv[]) } jackctl_server_add_slave(server_ctl, loopback_driver_ctl); } + + } + + // Start the server + if (!jackctl_server_start(server_ctl)) { + fprintf(stderr, "Failed to start server\n"); + goto close_server; } // Internal clients @@ -493,30 +507,28 @@ int main(int argc, char* argv[]) jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); if (internal_driver_ctl == NULL) { fprintf(stderr, "Unknown internal \"%s\"\n", *it); - goto fail_free2; + goto stop_server; } jackctl_server_load_internal(server_ctl, internal_driver_ctl); } notify_server_start(server_name); + notify_sent = true; + return_value = 0; // Waits for signal jackctl_wait_signals(signals); - if (!jackctl_server_stop(server_ctl)) + stop_server: + if (! jackctl_server_stop(server_ctl)) { fprintf(stderr, "Cannot stop server...\n"); - - jackctl_server_destroy(server_ctl); - notify_server_stop(server_name); - return 0; - -fail_free1: - jackctl_server_destroy(server_ctl); - return -1; - -fail_free2: - jackctl_server_stop(server_ctl); + } + if (notify_sent) { + notify_server_stop(server_name); + } + close_server: + jackctl_server_close(server_ctl); + destroy_server: jackctl_server_destroy(server_ctl); - notify_server_stop(server_name); - return -1; + return return_value; } diff --git a/common/jack/control.h b/common/jack/control.h index caeb931d..7ec5c521 100644 --- a/common/jack/control.h +++ b/common/jack/control.h @@ -133,7 +133,7 @@ jackctl_server_destroy( jackctl_server_t * server); /** - * Call this function to start JACK server + * Call this function to open JACK server * * @param server server object handle * @param driver driver to use @@ -141,10 +141,21 @@ jackctl_server_destroy( * @return success status: true - success, false - fail */ bool -jackctl_server_start( +jackctl_server_open( jackctl_server_t * server, jackctl_driver_t * driver); +/** + * Call this function to start JACK server + * + * @param server server object handle + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_start( + jackctl_server_t * server); + /** * Call this function to stop JACK server * @@ -156,6 +167,17 @@ bool jackctl_server_stop( jackctl_server_t * server); +/** + * Call this function to close JACK server + * + * @param server server object handle + * + * @return success status: true - success, false - fail + */ +bool +jackctl_server_close( + jackctl_server_t * server); + /** * Call this function to get list of available drivers. List node data * pointers is a driver object handle (::jackctl_driver_t). diff --git a/dbus/controller.c b/dbus/controller.c index 9c2bf3a5..77acef39 100644 --- a/dbus/controller.c +++ b/dbus/controller.c @@ -153,14 +153,21 @@ jack_controller_start_server( controller_ptr->xruns = 0; - if (!jackctl_server_start( + if (!jackctl_server_open( controller_ptr->server, controller_ptr->driver)) { - jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server"); + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to open server"); goto fail; } + if (!jackctl_server_start( + controller_ptr->server)) + { + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to start server"); + goto fail_close_server; + } + controller_ptr->client = jack_client_open( "dbusapi", JackNoStartServer, @@ -213,6 +220,12 @@ fail_stop_server: jack_error("failed to stop jack server"); } +fail_close_server: + if (!jackctl_server_close(controller_ptr->server)) + { + jack_error("failed to close jack server"); + } + fail: return FALSE; } @@ -250,6 +263,12 @@ jack_controller_stop_server( return FALSE; } + if (!jackctl_server_close(controller_ptr->server)) + { + jack_dbus_error(dbus_call_context_ptr, JACK_DBUS_ERROR_GENERIC, "Failed to close server"); + return FALSE; + } + controller_ptr->started = false; return TRUE; diff --git a/example-clients/server_control.cpp b/example-clients/server_control.cpp index 64ec977c..44040954 100644 --- a/example-clients/server_control.cpp +++ b/example-clients/server_control.cpp @@ -207,8 +207,9 @@ int main(int argc, char *argv[]) print_internal((jackctl_internal_t *)node_ptr->data); node_ptr = jack_slist_next(node_ptr); } - - jackctl_server_start(server, jackctl_server_get_driver(server, driver_name)); + + jackctl_server_open(server, jackctl_server_get_driver(server, driver_name)); + jackctl_server_start(server); jackctl_server_load_internal(server, jackctl_server_get_internal(server, client_name)); /* diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 914766ec..3d39e432 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -340,13 +340,23 @@ int JackAlsaDriver::Close() int JackAlsaDriver::Start() { - JackAudioDriver::Start(); - return alsa_driver_start((alsa_driver_t *)fDriver); + int res = JackAudioDriver::Start(); + if (res >= 0) { + res = alsa_driver_start((alsa_driver_t *)fDriver); + if (res < 0) { + JackAudioDriver::Stop(); + } + } + return res; } int JackAlsaDriver::Stop() { - return alsa_driver_stop((alsa_driver_t *)fDriver); + int res = alsa_driver_stop((alsa_driver_t *)fDriver); + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackAlsaDriver::Read() diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index 0966b1da..2f855f37 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -526,7 +526,7 @@ int JackFFADODriver::Attach() port = fGraphManager->GetPort(port_index); // Add one buffer more latency if "async" mode is used... - range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency + range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency; port->SetLatencyRange(JackPlaybackLatency, &range); // playback port aliases (jackd1 style port names) snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); @@ -653,13 +653,23 @@ int JackFFADODriver::Close() int JackFFADODriver::Start() { - JackAudioDriver::Start(); - return ffado_driver_start((ffado_driver_t *)fDriver); + int res = JackAudioDriver::Start(); + if (res >= 0) { + res = ffado_driver_start((ffado_driver_t *)fDriver); + if (res < 0) { + JackAudioDriver::Stop(); + } + } + return res; } int JackFFADODriver::Stop() { - return ffado_driver_stop((ffado_driver_t *)fDriver); + int res = ffado_driver_stop((ffado_driver_t *)fDriver); + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackFFADODriver::Read() diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index 96131d0b..03a26893 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -841,13 +841,23 @@ int JackFreebobDriver::Close() int JackFreebobDriver::Start() { - JackAudioDriver::Start(); - return freebob_driver_start((freebob_driver_t *)fDriver); + int res = JackAudioDriver::Start(); + if (res >= 0) { + res = freebob_driver_start((freebob_driver_t *)fDriver); + if (res < 0) { + JackAudioDriver::Stop(); + } + } + return res; } int JackFreebobDriver::Stop() { - return freebob_driver_stop((freebob_driver_t *)fDriver); + int res = freebob_driver_stop((freebob_driver_t *)fDriver); + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackFreebobDriver::Read() diff --git a/macosx/coreaudio/JackCoreAudioDriver.cpp b/macosx/coreaudio/JackCoreAudioDriver.cpp index 0acad8a7..5cd63676 100644 --- a/macosx/coreaudio/JackCoreAudioDriver.cpp +++ b/macosx/coreaudio/JackCoreAudioDriver.cpp @@ -1680,33 +1680,38 @@ int JackCoreAudioDriver::Attach() int JackCoreAudioDriver::Start() { jack_log("JackCoreAudioDriver::Start"); - JackAudioDriver::Start(); + if (JackAudioDriver::Start() >= 0) { + OSStatus err = AudioOutputUnitStart(fAUHAL); + if (err == noErr) { - OSStatus err = AudioOutputUnitStart(fAUHAL); - if (err != noErr) - return -1; + // Waiting for Measure callback to be called (= driver has started) + fState = false; + int count = 0; + while (!fState && count++ < WAIT_COUNTER) { + usleep(100000); + jack_log("JackCoreAudioDriver::Start wait count = %d", count); + } - // Waiting for Measure callback to be called (= driver has started) - fState = false; - int count = 0; - while (!fState && count++ < WAIT_COUNTER) { - usleep(100000); - jack_log("JackCoreAudioDriver::Start wait count = %d", count); - } + if (count < WAIT_COUNTER) { + jack_info("CoreAudio driver is running..."); + return 0; + } - if (count < WAIT_COUNTER) { - jack_info("CoreAudio driver is running..."); - return 0; - } else { - jack_error("CoreAudio driver cannot start..."); - return -1; + jack_error("CoreAudio driver cannot start..."); + } + JackAudioDriver::Stop(); } + return -1; } int JackCoreAudioDriver::Stop() { jack_log("JackCoreAudioDriver::Stop"); - return (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1; + int res = (AudioOutputUnitStop(fAUHAL) == noErr) ? 0 : -1; + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 1732102f..41a3deb2 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -191,16 +191,25 @@ error: int JackPortAudioDriver::Start() { jack_log("JackPortAudioDriver::Start"); - JackAudioDriver::Start(); - PaError err = Pa_StartStream(fStream); - return (err == paNoError) ? 0 : -1; + if (JackAudioDriver::Start() >= 0) { + PaError err = Pa_StartStream(fStream); + if (err == paNoError) { + return 0; + } + JackAudioDriver::Stop(); + } + return -1; } int JackPortAudioDriver::Stop() { jack_log("JackPortAudioDriver::Stop"); PaError err = Pa_StopStream(fStream); - return (err == paNoError) ? 0 : -1; + int res = (err == paNoError) ? 0 : -1; + if (JackAudioDriver::Stop() < 0) { + res = -1; + } + return res; } int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size)