git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4219 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.7
| @@ -312,6 +312,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)); | |||
| @@ -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); | |||
| @@ -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; | |||
| @@ -1202,8 +1210,13 @@ EXPORT bool jackctl_server_unload_internal( | |||
| EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) | |||
| { | |||
| if (server_ptr->engine != NULL) { | |||
| driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); | |||
| return (driver_ptr->info != 0); | |||
| if (server_ptr->engine->IsRunning()) { | |||
| jack_error("cannot add a slave in a running server"); | |||
| return false; | |||
| } else { | |||
| driver_ptr->info = server_ptr->engine->AddSlave(driver_ptr->desc_ptr, driver_ptr->set_parameters); | |||
| return (driver_ptr->info != 0); | |||
| } | |||
| } else { | |||
| return false; | |||
| } | |||
| @@ -1212,9 +1225,14 @@ EXPORT bool jackctl_server_add_slave(jackctl_server * server_ptr, jackctl_driver | |||
| EXPORT bool jackctl_server_remove_slave(jackctl_server * server_ptr, jackctl_driver * driver_ptr) | |||
| { | |||
| if (server_ptr->engine != NULL) { | |||
| server_ptr->engine->RemoveSlave(driver_ptr->info); | |||
| delete driver_ptr->info; | |||
| return true; | |||
| if (server_ptr->engine->IsRunning()) { | |||
| jack_error("cannot remove a slave from a running server"); | |||
| return false; | |||
| } else { | |||
| server_ptr->engine->RemoveSlave(driver_ptr->info); | |||
| delete driver_ptr->info; | |||
| return true; | |||
| } | |||
| } else { | |||
| return false; | |||
| } | |||
| @@ -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( | |||
| @@ -47,6 +47,7 @@ JackDriver::JackDriver(const char* name, const char* alias, JackLockedEngine* en | |||
| fBeginDateUst = 0; | |||
| fDelayedUsecs = 0.f; | |||
| fIsMaster = true; | |||
| fIsRunning = false; | |||
| } | |||
| JackDriver::JackDriver() | |||
| @@ -56,6 +57,7 @@ JackDriver::JackDriver() | |||
| fGraphManager = NULL; | |||
| fBeginDateUst = 0; | |||
| fIsMaster = true; | |||
| fIsRunning = false; | |||
| } | |||
| JackDriver::~JackDriver() | |||
| @@ -288,6 +290,7 @@ int JackDriver::ProcessSlaves() | |||
| JackDriverInterface* slave = *it; | |||
| if (slave->Process() < 0) | |||
| res = -1; | |||
| } | |||
| return res; | |||
| } | |||
| @@ -324,15 +327,49 @@ int JackDriver::Write() | |||
| int JackDriver::Start() | |||
| { | |||
| fEngineControl->InitFrameTime(); | |||
| if (fIsMaster) { | |||
| fEngineControl->InitFrameTime(); | |||
| } | |||
| fIsRunning = true; | |||
| return 0; | |||
| } | |||
| int JackDriver::StartSlaves() | |||
| { | |||
| int res = 0; | |||
| list<JackDriverInterface*>::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() | |||
| { | |||
| fIsRunning = false; | |||
| return 0; | |||
| } | |||
| int JackDriver::StopSlaves() | |||
| { | |||
| int res = 0; | |||
| list<JackDriverInterface*>::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; | |||
| @@ -97,6 +97,7 @@ class SERVER_EXPORT JackDriverInterface | |||
| virtual int ProcessSlaves() = 0; | |||
| virtual bool IsRealTime() const = 0; | |||
| virtual bool IsRunning() const = 0; | |||
| }; | |||
| /*! | |||
| @@ -134,6 +135,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||
| JackClientControl fClientControl; | |||
| std::list<JackDriverInterface*> fSlaveList; | |||
| bool fIsMaster; | |||
| bool fIsRunning; | |||
| void CycleIncTime(); | |||
| void CycleTakeBeginTime(); | |||
| @@ -198,7 +200,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); | |||
| @@ -208,6 +212,7 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||
| virtual JackClientControl* GetClientControl() const; | |||
| virtual bool IsRealTime() const; | |||
| virtual bool IsRunning() const { return fIsRunning; } | |||
| virtual bool Initialize(); // To be called by the wrapping thread Init method when the driver is a "blocking" one | |||
| }; | |||
| @@ -49,7 +49,16 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio | |||
| fGraphManager = JackGraphManager::Allocate(port_max); | |||
| fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); | |||
| fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); | |||
| fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver(fEngine, GetSynchroTable())); | |||
| // A distinction is made between the threaded freewheel driver and the | |||
| // regular freewheel driver because the freewheel driver needs to run in | |||
| // threaded mode when freewheel mode is active and needs to run as a slave | |||
| // when freewheel mode isn't active. | |||
| JackFreewheelDriver *freewheelDriver = | |||
| new JackFreewheelDriver(fEngine, GetSynchroTable()); | |||
| fThreadedFreewheelDriver = new JackThreadedDriver(freewheelDriver); | |||
| fFreewheelDriver = freewheelDriver; | |||
| fDriverInfo = new JackDriverInfo(); | |||
| fAudioDriver = NULL; | |||
| fFreewheel = false; | |||
| @@ -62,7 +71,7 @@ JackServer::~JackServer() | |||
| { | |||
| JackGraphManager::Destroy(fGraphManager); | |||
| delete fDriverInfo; | |||
| delete fFreewheelDriver; | |||
| delete fThreadedFreewheelDriver; | |||
| delete fEngine; | |||
| delete fEngineControl; | |||
| } | |||
| @@ -87,8 +96,8 @@ 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"); | |||
| if (fFreewheelDriver->Open() < 0) { | |||
| jack_error("Cannot open freewheel driver"); | |||
| goto fail_close4; | |||
| } | |||
| @@ -99,7 +108,7 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) | |||
| fFreewheelDriver->SetMaster(false); | |||
| fAudioDriver->SetMaster(true); | |||
| fAudioDriver->AddSlave(fFreewheelDriver); // After ??? | |||
| fAudioDriver->AddSlave(fFreewheelDriver); | |||
| InitTime(); | |||
| SetClockSource(fEngineControl->fClockSource); | |||
| return 0; | |||
| @@ -179,7 +188,18 @@ int JackServer::Start() | |||
| int JackServer::Stop() | |||
| { | |||
| jack_log("JackServer::Stop"); | |||
| return fAudioDriver->Stop(); | |||
| if (fFreewheel) { | |||
| return fThreadedFreewheelDriver->Stop(); | |||
| } else { | |||
| return fAudioDriver->Stop(); | |||
| } | |||
| } | |||
| bool JackServer::IsRunning() | |||
| { | |||
| jack_log("JackServer::IsRunning"); | |||
| assert(fAudioDriver); | |||
| return fAudioDriver->IsRunning(); | |||
| } | |||
| int JackServer::SetBufferSize(jack_nframes_t buffer_size) | |||
| @@ -237,10 +257,11 @@ int JackServer::SetFreewheel(bool onoff) | |||
| return -1; | |||
| } else { | |||
| fFreewheel = false; | |||
| fFreewheelDriver->Stop(); | |||
| fThreadedFreewheelDriver->Stop(); | |||
| fGraphManager->Restore(&fConnectionState); // Restore previous connection state | |||
| fEngine->NotifyFreewheel(onoff); | |||
| fFreewheelDriver->SetMaster(false); | |||
| fAudioDriver->SetMaster(true); | |||
| return fAudioDriver->Start(); | |||
| } | |||
| } else { | |||
| @@ -250,8 +271,9 @@ int JackServer::SetFreewheel(bool onoff) | |||
| fGraphManager->Save(&fConnectionState); // Save connection state | |||
| fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); | |||
| fEngine->NotifyFreewheel(onoff); | |||
| fAudioDriver->SetMaster(false); | |||
| fFreewheelDriver->SetMaster(true); | |||
| return fFreewheelDriver->Start(); | |||
| return fThreadedFreewheelDriver->Start(); | |||
| } else { | |||
| return -1; | |||
| } | |||
| @@ -270,7 +292,6 @@ void JackServer::Notify(int refnum, int notify, int value) | |||
| case kXRunCallback: | |||
| fEngine->NotifyXRun(refnum); | |||
| break; | |||
| } | |||
| } | |||
| @@ -296,11 +317,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) | |||
| @@ -325,28 +346,27 @@ int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_par | |||
| if (master == NULL) { | |||
| delete info; | |||
| return -1; | |||
| } else { | |||
| } | |||
| // Get slaves list | |||
| std::list<JackDriverInterface*> slave_list = fAudioDriver->GetSlaves(); | |||
| std::list<JackDriverInterface*>::const_iterator it; | |||
| // Get slaves list | |||
| std::list<JackDriverInterface*> slave_list = fAudioDriver->GetSlaves(); | |||
| std::list<JackDriverInterface*>::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(); | |||
| } | |||
| //---------------------- | |||
| @@ -50,6 +50,7 @@ class SERVER_EXPORT JackServer | |||
| JackDriverInfo* fDriverInfo; | |||
| JackDriverClientInterface* fAudioDriver; | |||
| JackDriverClientInterface* fFreewheelDriver; | |||
| JackDriverClientInterface* fThreadedFreewheelDriver; | |||
| JackLockedEngine* fEngine; | |||
| JackEngineControl* fEngineControl; | |||
| JackGraphManager* fGraphManager; | |||
| @@ -70,6 +71,7 @@ class SERVER_EXPORT JackServer | |||
| int Start(); | |||
| int Stop(); | |||
| bool IsRunning(); | |||
| // RT thread | |||
| void Notify(int refnum, int notify, int value); | |||
| @@ -152,6 +152,11 @@ bool JackThreadedDriver::IsRealTime() const | |||
| return fDriver->IsRealTime(); | |||
| } | |||
| bool JackThreadedDriver::IsRunning() const | |||
| { | |||
| return fDriver->IsRunning(); | |||
| } | |||
| int JackThreadedDriver::Start() | |||
| { | |||
| jack_log("JackThreadedDriver::Start"); | |||
| @@ -171,9 +176,9 @@ int JackThreadedDriver::Start() | |||
| int JackThreadedDriver::Stop() | |||
| { | |||
| jack_log("JackThreadedDriver::Stop"); | |||
| switch (fThread.GetStatus()) { | |||
| // Kill the thread in Init phase | |||
| case JackThread::kStarting: | |||
| case JackThread::kIniting: | |||
| @@ -182,15 +187,15 @@ int JackThreadedDriver::Stop() | |||
| return -1; | |||
| } | |||
| break; | |||
| // Stop when the thread cycle is finished | |||
| case JackThread::kRunning: | |||
| if (fThread.Stop() < 0) { | |||
| jack_error("Cannot stop thread"); | |||
| jack_error("Cannot stop thread"); | |||
| return -1; | |||
| } | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| @@ -218,7 +223,7 @@ bool JackThreadedDriver::Init() | |||
| if (fThread.AcquireSelfRealTime(GetEngineControl()->fServerPriority) < 0) { | |||
| jack_error("AcquireSelfRealTime error"); | |||
| } else { | |||
| set_threaded_log_function(); | |||
| set_threaded_log_function(); | |||
| } | |||
| } | |||
| return true; | |||
| @@ -38,14 +38,14 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi | |||
| JackThread fThread; | |||
| JackDriver* fDriver; | |||
| public: | |||
| JackThreadedDriver(JackDriver* driver); | |||
| virtual ~JackThreadedDriver(); | |||
| virtual int Open(); | |||
| virtual int Open (bool capturing, | |||
| bool playing, | |||
| int inchannels, | |||
| @@ -54,7 +54,7 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi | |||
| const char* capture_driver_name, | |||
| const char* playback_driver_name, | |||
| jack_nframes_t capture_latency, | |||
| jack_nframes_t playback_latency) | |||
| jack_nframes_t playback_latency) | |||
| { | |||
| return -1; | |||
| } | |||
| @@ -70,34 +70,35 @@ class SERVER_EXPORT JackThreadedDriver : public JackDriverClientInterface, publi | |||
| jack_nframes_t capture_latency, | |||
| jack_nframes_t playback_latency); | |||
| virtual int Close(); | |||
| virtual int Process(); | |||
| virtual int ProcessNull(); | |||
| virtual int Attach(); | |||
| virtual int Detach(); | |||
| virtual int Read(); | |||
| virtual int Write(); | |||
| virtual int Start(); | |||
| virtual int Stop(); | |||
| virtual bool IsFixedBufferSize(); | |||
| virtual int SetBufferSize(jack_nframes_t buffer_size); | |||
| virtual int SetSampleRate(jack_nframes_t sample_rate); | |||
| virtual void SetMaster(bool onoff); | |||
| virtual bool GetMaster(); | |||
| virtual void AddSlave(JackDriverInterface* slave); | |||
| virtual void RemoveSlave(JackDriverInterface* slave); | |||
| virtual std::list<JackDriverInterface*> GetSlaves(); | |||
| virtual int ProcessSlaves(); | |||
| virtual int ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2); | |||
| virtual JackClientControl* GetClientControl() const; | |||
| virtual bool IsRealTime() const; | |||
| virtual bool IsRunning() const; | |||
| // JackRunnableInterface interface | |||
| virtual bool Execute(); | |||
| virtual bool Init(); | |||
| @@ -244,6 +244,10 @@ int main(int argc, char* argv[]) | |||
| std::list<char*> slaves_list; | |||
| std::list<char*>::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; | |||
| } | |||
| @@ -4,7 +4,7 @@ | |||
| Copyright (C) 2008 Nedko Arnaudov | |||
| Copyright (C) 2008 GRAME | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; version 2 of the License. | |||
| @@ -86,10 +86,10 @@ extern "C" { | |||
| * @{ | |||
| */ | |||
| /** | |||
| /** | |||
| * Call this function to setup process signal handling. As a general | |||
| * rule, it is required for proper operation for the server object. | |||
| * | |||
| * | |||
| * @param flags signals setup flags, use 0 for none. Currently no | |||
| * flags are defined | |||
| * | |||
| @@ -99,9 +99,9 @@ sigset_t | |||
| jackctl_setup_signals( | |||
| unsigned int flags); | |||
| /** | |||
| /** | |||
| * Call this function to wait on a signal set. | |||
| * | |||
| * | |||
| * @param signals signals set to wait on | |||
| */ | |||
| void | |||
| @@ -123,43 +123,65 @@ jackctl_server_create( | |||
| bool (* on_device_acquire)(const char * device_name), | |||
| void (* on_device_release)(const char * device_name)); | |||
| /** | |||
| /** | |||
| * Call this function to destroy server object. | |||
| * | |||
| * | |||
| * @param server server object handle to destroy | |||
| */ | |||
| void | |||
| 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 | |||
| * | |||
| * | |||
| * @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 | |||
| * | |||
| * | |||
| * @param server server object handle | |||
| * | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| 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). | |||
| * | |||
| * | |||
| * @param server server object handle to get drivers for | |||
| * | |||
| * @return Single linked list of driver object handles. Must not be | |||
| @@ -169,10 +191,10 @@ const JSList * | |||
| jackctl_server_get_drivers_list( | |||
| jackctl_server_t * server); | |||
| /** | |||
| /** | |||
| * Call this function to get list of server parameters. List node data | |||
| * pointers is a parameter object handle (::jackctl_parameter_t). | |||
| * | |||
| * | |||
| * @param server server object handle to get parameters for | |||
| * | |||
| * @return Single linked list of parameter object handles. Must not be | |||
| @@ -182,10 +204,10 @@ const JSList * | |||
| jackctl_server_get_parameters( | |||
| jackctl_server_t * server); | |||
| /** | |||
| /** | |||
| * Call this function to get list of available internal clients. List node data | |||
| * pointers is a internal client object handle (::jackctl_internal_t). | |||
| * | |||
| * | |||
| * @param server server object handle to get internal clients for | |||
| * | |||
| * @return Single linked list of internal client object handles. Must not be | |||
| @@ -195,12 +217,13 @@ const JSList * | |||
| jackctl_server_get_internals_list( | |||
| jackctl_server_t * server); | |||
| /** | |||
| /** | |||
| * Call this function to load one internal client. | |||
| * | |||
| * (can be used when the server is running) | |||
| * | |||
| * @param server server object handle | |||
| * @param internal internal to use | |||
| * | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| @@ -208,12 +231,13 @@ jackctl_server_load_internal( | |||
| jackctl_server_t * server, | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| /** | |||
| * Call this function to unload one internal client. | |||
| * | |||
| * (can be used when the server is running) | |||
| * | |||
| * @param server server object handle | |||
| * @param internal internal to unload | |||
| * | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| @@ -221,46 +245,50 @@ jackctl_server_unload_internal( | |||
| jackctl_server_t * server, | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| /** | |||
| * Call this function to add a slave in the driver slave list. | |||
| * | |||
| * (cannot be used when the server is running that is between | |||
| * jackctl_server_start and jackctl_server_stop) | |||
| * | |||
| * @param server server object handle | |||
| * @param driver driver to add in the driver slave list. | |||
| * | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| */ | |||
| bool | |||
| jackctl_server_add_slave(jackctl_server_t * server, | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| /** | |||
| * Call this function to remove a slave from the driver slave list. | |||
| * | |||
| * (cannot be used when the server is running that is between | |||
| * jackctl_server_start and jackctl_server_stop) | |||
| * | |||
| * @param server server object handle | |||
| * @param driver driver to remove from the driver slave list. | |||
| * | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| */ | |||
| bool | |||
| jackctl_server_remove_slave(jackctl_server_t * server, | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| /** | |||
| * Call this function to switch master driver. | |||
| * | |||
| * | |||
| * @param server server object handle | |||
| * @param driver driver to switch to | |||
| * | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| */ | |||
| bool | |||
| jackctl_server_switch_master(jackctl_server_t * server, | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| /** | |||
| * Call this function to get name of driver. | |||
| * | |||
| * | |||
| * @param driver driver object handle to get name of | |||
| * | |||
| * @return driver name. Must not be modified. Always same for same | |||
| @@ -270,10 +298,10 @@ const char * | |||
| jackctl_driver_get_name( | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| /** | |||
| * Call this function to get list of driver parameters. List node data | |||
| * pointers is a parameter object handle (::jackctl_parameter_t). | |||
| * | |||
| * | |||
| * @param driver driver object handle to get parameters for | |||
| * | |||
| * @return Single linked list of parameter object handles. Must not be | |||
| @@ -283,9 +311,9 @@ const JSList * | |||
| jackctl_driver_get_parameters( | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| /** | |||
| * Call this function to get name of internal client. | |||
| * | |||
| * | |||
| * @param internal internal object handle to get name of | |||
| * | |||
| * @return internal name. Must not be modified. Always same for same | |||
| @@ -295,10 +323,10 @@ const char * | |||
| jackctl_internal_get_name( | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| /** | |||
| * Call this function to get list of internal parameters. List node data | |||
| * pointers is a parameter object handle (::jackctl_parameter_t). | |||
| * | |||
| * | |||
| * @param internal internal object handle to get parameters for | |||
| * | |||
| * @return Single linked list of parameter object handles. Must not be | |||
| @@ -308,9 +336,9 @@ const JSList * | |||
| jackctl_internal_get_parameters( | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter name. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get name of | |||
| * | |||
| * @return parameter name. Must not be modified. Always same for same | |||
| @@ -320,9 +348,9 @@ const char * | |||
| jackctl_parameter_get_name( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter short description. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get short description of | |||
| * | |||
| * @return parameter short description. Must not be modified. Always | |||
| @@ -332,9 +360,9 @@ const char * | |||
| jackctl_parameter_get_short_description( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter long description. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get long description of | |||
| * | |||
| * @return parameter long description. Must not be modified. Always | |||
| @@ -344,9 +372,9 @@ const char * | |||
| jackctl_parameter_get_long_description( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter type. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get type of | |||
| * | |||
| * @return parameter type. Always same for same parameter object. | |||
| @@ -355,21 +383,21 @@ jackctl_param_type_t | |||
| jackctl_parameter_get_type( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter character. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get character of | |||
| * | |||
| * @return character. | |||
| * @return character. | |||
| */ | |||
| char | |||
| jackctl_parameter_get_id( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to check whether parameter has been set, or its | |||
| * default value is being used. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to check | |||
| * | |||
| * @return true - parameter is set, false - parameter is using default | |||
| @@ -379,9 +407,9 @@ bool | |||
| jackctl_parameter_is_set( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to reset parameter to its default value. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to reset value of | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| @@ -390,9 +418,9 @@ bool | |||
| jackctl_parameter_reset( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter value. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get value of | |||
| * | |||
| * @return parameter value. | |||
| @@ -401,9 +429,9 @@ union jackctl_parameter_value | |||
| jackctl_parameter_get_value( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to set parameter value. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get value of | |||
| * @param value_ptr pointer to variable containing parameter value | |||
| * | |||
| @@ -414,9 +442,9 @@ jackctl_parameter_set_value( | |||
| jackctl_parameter_t * parameter, | |||
| const union jackctl_parameter_value * value_ptr); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter default value. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to get default value of | |||
| * | |||
| * @return parameter default value. | |||
| @@ -424,10 +452,10 @@ jackctl_parameter_set_value( | |||
| union jackctl_parameter_value | |||
| jackctl_parameter_get_default_value( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function check whether parameter has range constraint. | |||
| * | |||
| * | |||
| * @param parameter object handle of parameter to check | |||
| * | |||
| * @return whether parameter has range constraint. | |||
| @@ -436,9 +464,9 @@ bool | |||
| jackctl_parameter_has_range_constraint( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function check whether parameter has enumeration constraint. | |||
| * | |||
| * | |||
| * @param parameter object handle of parameter to check | |||
| * | |||
| * @return whether parameter has enumeration constraint. | |||
| @@ -447,9 +475,9 @@ bool | |||
| jackctl_parameter_has_enum_constraint( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function get how many enumeration values parameter has. | |||
| * | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * | |||
| * @return number of enumeration values | |||
| @@ -458,9 +486,9 @@ uint32_t | |||
| jackctl_parameter_get_enum_constraints_count( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter enumeration value. | |||
| * | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * @param index index of parameter enumeration value | |||
| * | |||
| @@ -471,9 +499,9 @@ jackctl_parameter_get_enum_constraint_value( | |||
| jackctl_parameter_t * parameter, | |||
| uint32_t index); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter enumeration value description. | |||
| * | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * @param index index of parameter enumeration value | |||
| * | |||
| @@ -484,9 +512,9 @@ jackctl_parameter_get_enum_constraint_description( | |||
| jackctl_parameter_t * parameter, | |||
| uint32_t index); | |||
| /** | |||
| /** | |||
| * Call this function to get parameter range. | |||
| * | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * @param min_ptr pointer to variable receiving parameter minimum value | |||
| * @param max_ptr pointer to variable receiving parameter maximum value | |||
| @@ -497,10 +525,10 @@ jackctl_parameter_get_range_constraint( | |||
| union jackctl_parameter_value * min_ptr, | |||
| union jackctl_parameter_value * max_ptr); | |||
| /** | |||
| /** | |||
| * Call this function to check whether parameter constraint is strict, | |||
| * i.e. whether supplying non-matching value will not work for sure. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to check | |||
| * | |||
| * @return whether parameter constraint is strict. | |||
| @@ -509,11 +537,11 @@ bool | |||
| jackctl_parameter_constraint_is_strict( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to check whether parameter has fake values, | |||
| * i.e. values have no user meaningful meaning and only value | |||
| * description is meaningful to user. | |||
| * | |||
| * | |||
| * @param parameter parameter object handle to check | |||
| * | |||
| * @return whether parameter constraint is strict. | |||
| @@ -522,9 +550,9 @@ bool | |||
| jackctl_parameter_constraint_is_fake_value( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| /** | |||
| * Call this function to log an error message. | |||
| * | |||
| * | |||
| * @param format string | |||
| */ | |||
| void | |||
| @@ -532,9 +560,9 @@ jack_error( | |||
| const char *format, | |||
| ...); | |||
| /** | |||
| /** | |||
| * Call this function to log an information message. | |||
| * | |||
| * | |||
| * @param format string | |||
| */ | |||
| void | |||
| @@ -542,10 +570,10 @@ jack_info( | |||
| const char *format, | |||
| ...); | |||
| /** | |||
| /** | |||
| * Call this function to log an information message but only when | |||
| * verbose mode is enabled. | |||
| * | |||
| * | |||
| * @param format string | |||
| */ | |||
| void | |||
| @@ -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; | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| Copyright (C) 2008 Grame | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 of the License, or | |||
| @@ -74,23 +74,23 @@ jackctl_get_parameter( | |||
| static void print_value(union jackctl_parameter_value value, jackctl_param_type_t type) | |||
| { | |||
| switch (type) { | |||
| case JackParamInt: | |||
| printf("parameter value = %d\n", value.i); | |||
| break; | |||
| case JackParamUInt: | |||
| printf("parameter value = %u\n", value.ui); | |||
| break; | |||
| case JackParamChar: | |||
| printf("parameter value = %c\n", value.c); | |||
| break; | |||
| case JackParamString: | |||
| printf("parameter value = %s\n", value.str); | |||
| break; | |||
| case JackParamBool: | |||
| printf("parameter value = %d\n", value.b); | |||
| break; | |||
| @@ -115,7 +115,7 @@ static void print_driver(jackctl_driver_t * driver) | |||
| printf("\n--------------------------\n"); | |||
| printf("driver = %s\n", jackctl_driver_get_name(driver)); | |||
| printf("-------------------------- \n"); | |||
| print_parameters(jackctl_driver_get_parameters(driver)); | |||
| print_parameters(jackctl_driver_get_parameters(driver)); | |||
| } | |||
| static void print_internal(jackctl_internal_t * internal) | |||
| @@ -152,7 +152,7 @@ int main(int argc, char *argv[]) | |||
| {"driver", 1, 0, 'd'}, | |||
| {"client", 1, 0, 'c'}, | |||
| }; | |||
| while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { | |||
| switch (opt) { | |||
| case 'd': | |||
| @@ -166,10 +166,10 @@ int main(int argc, char *argv[]) | |||
| exit(0); | |||
| } | |||
| } | |||
| server = jackctl_server_create(NULL, NULL); | |||
| parameters = jackctl_server_get_parameters(server); | |||
| /* | |||
| jackctl_parameter_t* param; | |||
| union jackctl_parameter_value value; | |||
| @@ -179,58 +179,63 @@ int main(int argc, char *argv[]) | |||
| jackctl_parameter_set_value(param, &value); | |||
| } | |||
| */ | |||
| printf("\n========================== \n"); | |||
| printf("List of server parameters \n"); | |||
| printf("========================== \n"); | |||
| print_parameters(parameters); | |||
| printf("\n========================== \n"); | |||
| printf("List of drivers \n"); | |||
| printf("========================== \n"); | |||
| drivers = jackctl_server_get_drivers_list(server); | |||
| node_ptr = drivers; | |||
| while (node_ptr != NULL) { | |||
| print_driver((jackctl_driver_t *)node_ptr->data); | |||
| node_ptr = jack_slist_next(node_ptr); | |||
| } | |||
| printf("\n========================== \n"); | |||
| printf("List of internal clients \n"); | |||
| printf("========================== \n"); | |||
| internals = jackctl_server_get_internals_list(server); | |||
| node_ptr = internals; | |||
| while (node_ptr != NULL) { | |||
| 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)); | |||
| // No error checking in this simple example... | |||
| 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)); | |||
| /* | |||
| // Switch master test | |||
| jackctl_driver_t* master; | |||
| usleep(5000000); | |||
| printf("jackctl_server_load_master\n"); | |||
| master = jackctl_server_get_driver(server, "coreaudio"); | |||
| jackctl_server_switch_master(server, master); | |||
| usleep(5000000); | |||
| printf("jackctl_server_load_master\n"); | |||
| master = jackctl_server_get_driver(server, "dummy"); | |||
| jackctl_server_switch_master(server, master); | |||
| */ | |||
| signals = jackctl_setup_signals(0); | |||
| jackctl_wait_signals(signals); | |||
| jackctl_server_stop(server); | |||
| jackctl_server_close(server); | |||
| jackctl_server_destroy(server); | |||
| return 0; | |||
| } | |||
| @@ -332,13 +332,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() | |||
| @@ -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() | |||
| @@ -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() | |||
| @@ -1678,33 +1678,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) | |||
| @@ -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) | |||