| @@ -313,6 +313,26 @@ int JackAudioDriver::ProcessGraphSync() | |||||
| return res; | 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() | void JackAudioDriver::WaitUntilNextCycle() | ||||
| { | { | ||||
| int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f)); | 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 Attach(); | ||||
| virtual int Detach(); | virtual int Detach(); | ||||
| virtual int Start(); | |||||
| virtual int Stop(); | |||||
| virtual int Write(); | virtual int Write(); | ||||
| virtual int SetBufferSize(jack_nframes_t buffer_size); | 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) | EXPORT bool jackctl_server_stop(jackctl_server *server_ptr) | ||||
| { | { | ||||
| server_ptr->engine->Stop(); | server_ptr->engine->Stop(); | ||||
| return true; | |||||
| } | |||||
| EXPORT bool jackctl_server_close(jackctl_server *server_ptr) | |||||
| { | |||||
| server_ptr->engine->Close(); | server_ptr->engine->Close(); | ||||
| delete server_ptr->engine; | delete server_ptr->engine; | ||||
| @@ -853,7 +858,7 @@ EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr) | |||||
| } | } | ||||
| EXPORT bool | EXPORT bool | ||||
| jackctl_server_start( | |||||
| jackctl_server_open( | |||||
| jackctl_server *server_ptr, | jackctl_server *server_ptr, | ||||
| jackctl_driver *driver_ptr) | jackctl_driver *driver_ptr) | ||||
| { | { | ||||
| @@ -913,18 +918,8 @@ jackctl_server_start( | |||||
| goto fail_delete; | goto fail_delete; | ||||
| } | } | ||||
| rc = server_ptr->engine->Start(); | |||||
| if (rc < 0) | |||||
| { | |||||
| jack_error("JackServer::Start() failed with %d", rc); | |||||
| goto fail_close; | |||||
| } | |||||
| return true; | return true; | ||||
| fail_close: | |||||
| server_ptr->engine->Close(); | |||||
| fail_delete: | fail_delete: | ||||
| delete server_ptr->engine; | delete server_ptr->engine; | ||||
| server_ptr->engine = NULL; | server_ptr->engine = NULL; | ||||
| @@ -946,6 +941,19 @@ fail: | |||||
| return false; | 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) | EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr) | ||||
| { | { | ||||
| return driver_ptr->desc_ptr->name; | return driver_ptr->desc_ptr->name; | ||||
| @@ -101,13 +101,21 @@ jackctl_server_get_drivers_list( | |||||
| jackctl_server_t * server); | jackctl_server_t * server); | ||||
| EXPORT bool | EXPORT bool | ||||
| jackctl_server_start( | |||||
| jackctl_server_open( | |||||
| jackctl_server_t * server, | jackctl_server_t * server, | ||||
| jackctl_driver_t * driver); | jackctl_driver_t * driver); | ||||
| EXPORT bool | |||||
| jackctl_server_start( | |||||
| jackctl_server_t * server); | |||||
| EXPORT bool | EXPORT bool | ||||
| jackctl_server_stop( | jackctl_server_stop( | ||||
| jackctl_server_t * server); | |||||
| jackctl_server_t * server); | |||||
| EXPORT bool | |||||
| jackctl_server_close( | |||||
| jackctl_server_t * server); | |||||
| EXPORT const JSList * | EXPORT const JSList * | ||||
| jackctl_server_get_parameters( | jackctl_server_get_parameters( | ||||
| @@ -328,11 +328,41 @@ int JackDriver::Start() | |||||
| return 0; | 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() | int JackDriver::Stop() | ||||
| { | { | ||||
| return 0; | 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() | bool JackDriver::IsFixedBufferSize() | ||||
| { | { | ||||
| return true; | return true; | ||||
| @@ -198,7 +198,9 @@ class SERVER_EXPORT JackDriver : public JackDriverClientInterface | |||||
| virtual int Write(); | virtual int Write(); | ||||
| virtual int Start(); | virtual int Start(); | ||||
| virtual int StartSlaves(); | |||||
| virtual int Stop(); | virtual int Stop(); | ||||
| virtual int StopSlaves(); | |||||
| virtual bool IsFixedBufferSize(); | virtual bool IsFixedBufferSize(); | ||||
| virtual int SetBufferSize(jack_nframes_t buffer_size); | virtual int SetBufferSize(jack_nframes_t buffer_size); | ||||
| @@ -87,26 +87,18 @@ int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) | |||||
| goto fail_close3; | goto fail_close3; | ||||
| } | } | ||||
| if (fFreewheelDriver->Open() < 0) { // before engine open | |||||
| jack_error("Cannot open driver"); | |||||
| goto fail_close4; | |||||
| } | |||||
| if (fAudioDriver->Attach() < 0) { | if (fAudioDriver->Attach() < 0) { | ||||
| jack_error("Cannot attach audio driver"); | jack_error("Cannot attach audio driver"); | ||||
| goto fail_close5; | |||||
| goto fail_close4; | |||||
| } | } | ||||
| fFreewheelDriver->SetMaster(false); | fFreewheelDriver->SetMaster(false); | ||||
| fAudioDriver->SetMaster(true); | fAudioDriver->SetMaster(true); | ||||
| fAudioDriver->AddSlave(fFreewheelDriver); // After ??? | |||||
| //fAudioDriver->AddSlave(fFreewheelDriver); | |||||
| InitTime(); | InitTime(); | ||||
| SetClockSource(fEngineControl->fClockSource); | SetClockSource(fEngineControl->fClockSource); | ||||
| return 0; | return 0; | ||||
| fail_close5: | |||||
| fFreewheelDriver->Close(); | |||||
| fail_close4: | fail_close4: | ||||
| fEngine->Close(); | fEngine->Close(); | ||||
| @@ -128,7 +120,9 @@ int JackServer::Close() | |||||
| fChannel.Close(); | fChannel.Close(); | ||||
| fAudioDriver->Detach(); | fAudioDriver->Detach(); | ||||
| fAudioDriver->Close(); | fAudioDriver->Close(); | ||||
| fFreewheelDriver->Close(); | |||||
| if (fFreewheel) { | |||||
| fFreewheelDriver->Close(); | |||||
| } | |||||
| fEngine->Close(); | fEngine->Close(); | ||||
| // TODO: move that in reworked JackServerGlobals::Destroy() | // TODO: move that in reworked JackServerGlobals::Destroy() | ||||
| JackMessageBuffer::Destroy(); | JackMessageBuffer::Destroy(); | ||||
| @@ -238,6 +232,7 @@ int JackServer::SetFreewheel(bool onoff) | |||||
| } else { | } else { | ||||
| fFreewheel = false; | fFreewheel = false; | ||||
| fFreewheelDriver->Stop(); | fFreewheelDriver->Stop(); | ||||
| fFreewheelDriver->Close(); | |||||
| fGraphManager->Restore(&fConnectionState); // Restore previous connection state | fGraphManager->Restore(&fConnectionState); // Restore previous connection state | ||||
| fEngine->NotifyFreewheel(onoff); | fEngine->NotifyFreewheel(onoff); | ||||
| fFreewheelDriver->SetMaster(false); | fFreewheelDriver->SetMaster(false); | ||||
| @@ -250,6 +245,10 @@ int JackServer::SetFreewheel(bool onoff) | |||||
| fGraphManager->Save(&fConnectionState); // Save connection state | fGraphManager->Save(&fConnectionState); // Save connection state | ||||
| fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); | fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum); | ||||
| fEngine->NotifyFreewheel(onoff); | fEngine->NotifyFreewheel(onoff); | ||||
| if (fFreewheelDriver->Open() < 0) { | |||||
| jack_error("Cannot open freewheel driver"); | |||||
| return -1; | |||||
| } | |||||
| fFreewheelDriver->SetMaster(true); | fFreewheelDriver->SetMaster(true); | ||||
| return fFreewheelDriver->Start(); | return fFreewheelDriver->Start(); | ||||
| } else { | } else { | ||||
| @@ -296,11 +295,11 @@ JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* dr | |||||
| if (slave == NULL) { | if (slave == NULL) { | ||||
| delete info; | delete info; | ||||
| return NULL; | 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) | 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(); | JackDriverInfo* info = new JackDriverInfo(); | ||||
| JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); | JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params); | ||||
| if (master == NULL || info == NULL) { | |||||
| if (master == NULL) { | |||||
| delete info; | delete info; | ||||
| delete master; | |||||
| return -1; | 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(); | |||||
| } | } | ||||
| //---------------------- | //---------------------- | ||||
| @@ -244,6 +244,10 @@ int main(int argc, char* argv[]) | |||||
| std::list<char*> slaves_list; | std::list<char*> slaves_list; | ||||
| std::list<char*>::iterator it; | std::list<char*>::iterator it; | ||||
| // Assume that we fail. | |||||
| int return_value = -1; | |||||
| bool notify_sent = false; | |||||
| copyright(stdout); | copyright(stdout); | ||||
| #if defined(JACK_DBUS) && defined(__linux__) | #if defined(JACK_DBUS) && defined(__linux__) | ||||
| server_ctl = jackctl_server_create(audio_acquire, audio_release); | 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); | jackctl_parameter_set_value(param, &value); | ||||
| } else { | } else { | ||||
| usage(stdout); | usage(stdout); | ||||
| goto fail_free1; | |||||
| goto destroy_server; | |||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| @@ -402,7 +406,7 @@ int main(int argc, char* argv[]) | |||||
| case 'h': | case 'h': | ||||
| usage(stdout); | usage(stdout); | ||||
| goto fail_free1; | |||||
| goto destroy_server; | |||||
| } | } | ||||
| } | } | ||||
| @@ -423,14 +427,14 @@ int main(int argc, char* argv[]) | |||||
| if (!master_driver_name) { | if (!master_driver_name) { | ||||
| usage(stderr); | usage(stderr); | ||||
| goto fail_free1; | |||||
| goto destroy_server; | |||||
| } | } | ||||
| // Master driver | // Master driver | ||||
| master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name); | master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name); | ||||
| if (master_driver_ctl == NULL) { | if (master_driver_ctl == NULL) { | ||||
| fprintf(stderr, "Unknown driver \"%s\"\n", master_driver_name); | fprintf(stderr, "Unknown driver \"%s\"\n", master_driver_name); | ||||
| goto fail_free1; | |||||
| goto destroy_server; | |||||
| } | } | ||||
| if (optind < argc) { | if (optind < argc) { | ||||
| @@ -442,7 +446,7 @@ int main(int argc, char* argv[]) | |||||
| if (master_driver_nargs == 0) { | if (master_driver_nargs == 0) { | ||||
| fprintf(stderr, "No driver specified ... hmm. JACK won't do" | fprintf(stderr, "No driver specified ... hmm. JACK won't do" | ||||
| " anything when run like this.\n"); | " anything when run like this.\n"); | ||||
| goto fail_free1; | |||||
| goto destroy_server; | |||||
| } | } | ||||
| master_driver_args = (char **) malloc(sizeof(char *) * master_driver_nargs); | 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)) { | 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); | 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 | // 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); | jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it); | ||||
| if (slave_driver_ctl == NULL) { | if (slave_driver_ctl == NULL) { | ||||
| fprintf(stderr, "Unknown driver \"%s\"\n", *it); | fprintf(stderr, "Unknown driver \"%s\"\n", *it); | ||||
| goto fail_free2; | |||||
| goto close_server; | |||||
| } | } | ||||
| jackctl_server_add_slave(server_ctl, slave_driver_ctl); | jackctl_server_add_slave(server_ctl, slave_driver_ctl); | ||||
| } | } | ||||
| @@ -477,6 +482,8 @@ int main(int argc, char* argv[]) | |||||
| // Loopback driver | // Loopback driver | ||||
| if (loopback > 0) { | if (loopback > 0) { | ||||
| loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); | loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback"); | ||||
| // XX: What if this fails? | |||||
| if (loopback_driver_ctl != NULL) { | if (loopback_driver_ctl != NULL) { | ||||
| const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl); | const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl); | ||||
| param = jackctl_get_parameter(loopback_parameters, "channels"); | 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); | 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 | // 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); | jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); | ||||
| if (internal_driver_ctl == NULL) { | if (internal_driver_ctl == NULL) { | ||||
| fprintf(stderr, "Unknown internal \"%s\"\n", *it); | fprintf(stderr, "Unknown internal \"%s\"\n", *it); | ||||
| goto fail_free2; | |||||
| goto stop_server; | |||||
| } | } | ||||
| jackctl_server_load_internal(server_ctl, internal_driver_ctl); | jackctl_server_load_internal(server_ctl, internal_driver_ctl); | ||||
| } | } | ||||
| notify_server_start(server_name); | notify_server_start(server_name); | ||||
| notify_sent = true; | |||||
| return_value = 0; | |||||
| // Waits for signal | // Waits for signal | ||||
| jackctl_wait_signals(signals); | jackctl_wait_signals(signals); | ||||
| if (!jackctl_server_stop(server_ctl)) | |||||
| stop_server: | |||||
| if (! jackctl_server_stop(server_ctl)) { | |||||
| fprintf(stderr, "Cannot stop server...\n"); | 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); | jackctl_server_destroy(server_ctl); | ||||
| notify_server_stop(server_name); | |||||
| return -1; | |||||
| return return_value; | |||||
| } | } | ||||
| @@ -133,7 +133,7 @@ jackctl_server_destroy( | |||||
| jackctl_server_t * server); | jackctl_server_t * server); | ||||
| /** | /** | ||||
| * Call this function to start JACK server | |||||
| * Call this function to open JACK server | |||||
| * | * | ||||
| * @param server server object handle | * @param server server object handle | ||||
| * @param driver driver to use | * @param driver driver to use | ||||
| @@ -141,10 +141,21 @@ jackctl_server_destroy( | |||||
| * @return success status: true - success, false - fail | * @return success status: true - success, false - fail | ||||
| */ | */ | ||||
| bool | bool | ||||
| jackctl_server_start( | |||||
| jackctl_server_open( | |||||
| jackctl_server_t * server, | jackctl_server_t * server, | ||||
| jackctl_driver_t * driver); | 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 | * Call this function to stop JACK server | ||||
| * | * | ||||
| @@ -156,6 +167,17 @@ bool | |||||
| jackctl_server_stop( | jackctl_server_stop( | ||||
| jackctl_server_t * server); | 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 | * Call this function to get list of available drivers. List node data | ||||
| * pointers is a driver object handle (::jackctl_driver_t). | * pointers is a driver object handle (::jackctl_driver_t). | ||||
| @@ -153,14 +153,21 @@ jack_controller_start_server( | |||||
| controller_ptr->xruns = 0; | controller_ptr->xruns = 0; | ||||
| if (!jackctl_server_start( | |||||
| if (!jackctl_server_open( | |||||
| controller_ptr->server, | controller_ptr->server, | ||||
| controller_ptr->driver)) | 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; | 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( | controller_ptr->client = jack_client_open( | ||||
| "dbusapi", | "dbusapi", | ||||
| JackNoStartServer, | JackNoStartServer, | ||||
| @@ -213,6 +220,12 @@ fail_stop_server: | |||||
| jack_error("failed to stop jack 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: | fail: | ||||
| return FALSE; | return FALSE; | ||||
| } | } | ||||
| @@ -250,6 +263,12 @@ jack_controller_stop_server( | |||||
| return FALSE; | 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; | controller_ptr->started = false; | ||||
| return TRUE; | return TRUE; | ||||
| @@ -207,8 +207,9 @@ int main(int argc, char *argv[]) | |||||
| print_internal((jackctl_internal_t *)node_ptr->data); | print_internal((jackctl_internal_t *)node_ptr->data); | ||||
| node_ptr = jack_slist_next(node_ptr); | 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)); | jackctl_server_load_internal(server, jackctl_server_get_internal(server, client_name)); | ||||
| /* | /* | ||||
| @@ -340,13 +340,23 @@ int JackAlsaDriver::Close() | |||||
| int JackAlsaDriver::Start() | 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() | 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() | int JackAlsaDriver::Read() | ||||
| @@ -526,7 +526,7 @@ int JackFFADODriver::Attach() | |||||
| port = fGraphManager->GetPort(port_index); | port = fGraphManager->GetPort(port_index); | ||||
| // Add one buffer more latency if "async" mode is used... | // 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); | port->SetLatencyRange(JackPlaybackLatency, &range); | ||||
| // playback port aliases (jackd1 style port names) | // playback port aliases (jackd1 style port names) | ||||
| snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); | snprintf(buf, sizeof(buf) - 1, "%s:playback_%i", fClientControl.fName, (int) chn + 1); | ||||
| @@ -653,13 +653,23 @@ int JackFFADODriver::Close() | |||||
| int JackFFADODriver::Start() | 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() | 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() | int JackFFADODriver::Read() | ||||
| @@ -841,13 +841,23 @@ int JackFreebobDriver::Close() | |||||
| int JackFreebobDriver::Start() | 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() | 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() | int JackFreebobDriver::Read() | ||||
| @@ -1680,33 +1680,38 @@ int JackCoreAudioDriver::Attach() | |||||
| int JackCoreAudioDriver::Start() | int JackCoreAudioDriver::Start() | ||||
| { | { | ||||
| jack_log("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() | int JackCoreAudioDriver::Stop() | ||||
| { | { | ||||
| jack_log("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) | int JackCoreAudioDriver::SetBufferSize(jack_nframes_t buffer_size) | ||||
| @@ -191,16 +191,25 @@ error: | |||||
| int JackPortAudioDriver::Start() | int JackPortAudioDriver::Start() | ||||
| { | { | ||||
| jack_log("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() | int JackPortAudioDriver::Stop() | ||||
| { | { | ||||
| jack_log("JackPortAudioDriver::Stop"); | jack_log("JackPortAudioDriver::Stop"); | ||||
| PaError err = Pa_StopStream(fStream); | 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) | int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size) | ||||