21 #include "JackSystemDeps.h" 22 #include "JackServerGlobals.h" 24 #include "JackFreewheelDriver.h" 25 #include "JackThreadedDriver.h" 26 #include "JackGlobals.h" 27 #include "JackLockedEngine.h" 28 #include "JackAudioDriver.h" 29 #include "JackChannel.h" 30 #include "JackClientControl.h" 31 #include "JackEngineControl.h" 32 #include "JackGraphManager.h" 33 #include "JackInternalClient.h" 34 #include "JackError.h" 35 #include "JackMessageBuffer.h" 37 const char * jack_get_self_connect_mode_description(
char mode);
45 JackServer::JackServer(
bool sync,
bool temporary,
int timeout,
bool rt,
int priority,
int port_max,
bool verbose, jack_timer_type_t clock,
char self_connect_mode,
const char* server_name)
48 jack_info(
"JACK server starting in realtime mode with priority %ld", priority);
50 jack_info(
"JACK server starting in non-realtime mode");
53 jack_info(
"self-connect-mode is \"%s\"", jack_get_self_connect_mode_description(self_connect_mode));
55 fGraphManager = JackGraphManager::Allocate(port_max);
56 fEngineControl =
new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name);
57 fEngine =
new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl, self_connect_mode);
63 JackFreewheelDriver* freewheelDriver =
new JackFreewheelDriver(fEngine, GetSynchroTable());
64 fThreadedFreewheelDriver =
new JackThreadedDriver(freewheelDriver);
66 fFreewheelDriver = freewheelDriver;
70 JackServerGlobals::fInstance =
this;
71 JackServerGlobals::fUserCount = 1;
72 JackGlobals::fVerbose = verbose;
75 JackServer::~JackServer()
77 JackGraphManager::Destroy(fGraphManager);
79 delete fThreadedFreewheelDriver;
81 delete fEngineControl;
87 if (!JackMessageBuffer::Create()) {
91 if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) {
96 if (fRequestChannel.Open(fEngineControl->fServerName,
this) < 0) {
101 if (fEngine->Open() < 0) {
106 if (fFreewheelDriver->Open() < 0) {
111 if (fAudioDriver->Attach() < 0) {
116 fFreewheelDriver->SetMaster(
false);
117 fAudioDriver->SetMaster(
true);
118 fAudioDriver->AddSlave(fFreewheelDriver);
120 SetClockSource(fEngineControl->fClockSource);
124 fFreewheelDriver->Close();
130 fRequestChannel.Close();
133 fAudioDriver->Close();
136 JackMessageBuffer::Destroy();
140 int JackServer::Close()
143 fRequestChannel.Close();
144 fAudioDriver->Detach();
145 fAudioDriver->Close();
146 fFreewheelDriver->Close();
149 JackMessageBuffer::Destroy();
154 int JackServer::Start()
157 if (fAudioDriver->Start() < 0) {
160 return fRequestChannel.Start();
163 int JackServer::Stop()
169 if (fThreadedFreewheelDriver) {
170 res = fThreadedFreewheelDriver->Stop();
174 res = fAudioDriver->Stop();
178 fEngine->NotifyQuit();
179 fRequestChannel.Stop();
180 fEngine->NotifyFailure(JackFailure | JackServerError, JACK_SERVER_FAILURE);
185 bool JackServer::IsRunning()
188 assert(fAudioDriver);
189 return fAudioDriver->IsRunning();
196 int JackServer::InternalClientLoad1(
const char* client_name,
const char* so_name,
const char* objet_data,
int options,
int* int_ref,
int uuid,
int* status)
198 JackLoadableInternalClient* client =
new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data);
200 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
203 int JackServer::InternalClientLoad2(
const char* client_name,
const char* so_name,
const JSList * parameters,
int options,
int* int_ref,
int uuid,
int* status)
205 JackLoadableInternalClient* client =
new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters);
207 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
210 int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client,
const char* so_name,
const char* client_name,
int options,
int* int_ref,
int uuid,
int* status)
216 if ((client->Init(so_name) < 0) || (client->Open(JackTools::DefaultServerName(), client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) {
218 int my_status1 = *status | JackFailure;
219 *status = (jack_status_t)my_status1;
223 *int_ref = client->GetClientControl()->fRefNum;
232 int JackServer::SetBufferSize(jack_nframes_t buffer_size)
234 jack_log(
"JackServer::SetBufferSize nframes = %ld", buffer_size);
235 jack_nframes_t current_buffer_size = fEngineControl->fBufferSize;
237 if (current_buffer_size == buffer_size) {
238 jack_log(
"SetBufferSize: requirement for new buffer size equals current value");
242 if (fAudioDriver->IsFixedBufferSize()) {
243 jack_log(
"SetBufferSize: driver only supports a fixed buffer size");
247 if (fAudioDriver->Stop() != 0) {
252 if (fAudioDriver->SetBufferSize(buffer_size) == 0) {
253 fEngine->NotifyBufferSize(buffer_size);
254 return fAudioDriver->Start();
256 jack_error(
"Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size);
257 fAudioDriver->SetBufferSize(current_buffer_size);
258 fAudioDriver->Start();
276 int JackServer::SetFreewheel(
bool onoff)
278 jack_log(
"JackServer::SetFreewheel is = %ld want = %ld", fFreewheel, onoff);
285 fThreadedFreewheelDriver->Stop();
286 fGraphManager->Restore(&fConnectionState);
287 fEngine->NotifyFreewheel(onoff);
288 fFreewheelDriver->SetMaster(
false);
289 fAudioDriver->SetMaster(
true);
290 return fAudioDriver->Start();
295 fAudioDriver->Stop();
296 fGraphManager->Save(&fConnectionState);
298 std::list<JackDriverInterface*> slave_list = fAudioDriver->GetSlaves();
299 std::list<JackDriverInterface*>::const_iterator it;
300 for (it = slave_list.begin(); it != slave_list.end(); it++) {
301 JackDriver* slave =
dynamic_cast<JackDriver*
>(*it);
303 fGraphManager->DisconnectAllPorts(slave->GetClientControl()->fRefNum);
306 fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum);
307 fEngine->NotifyFreewheel(onoff);
308 fAudioDriver->SetMaster(
false);
309 fFreewheelDriver->SetMaster(
true);
310 return fThreadedFreewheelDriver->Start();
321 void JackServer::Notify(
int refnum,
int notify,
int value)
325 case kGraphOrderCallback:
326 fEngine->NotifyGraphReorder();
330 fEngine->NotifyClientXRun(refnum);
342 JackDriverClientInterface* slave = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
347 if (slave->Attach() < 0) {
351 slave->SetMaster(
false);
352 fAudioDriver->AddSlave(slave);
365 JackDriverClientInterface* slave = info->GetBackend();
366 fAudioDriver->RemoveSlave(slave);
373 std::list<JackDriverInterface*> slave_list;
374 std::list<JackDriverInterface*>::const_iterator it;
377 fAudioDriver->Stop();
378 fAudioDriver->Detach();
379 fAudioDriver->Close();
383 JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
390 slave_list = fAudioDriver->GetSlaves();
393 for (it = slave_list.begin(); it != slave_list.end(); it++) {
394 JackDriverInterface* slave = *it;
395 master->AddSlave(slave);
402 fAudioDriver = master;
405 if (fAudioDriver->Attach() < 0) {
410 fEngine->NotifyBufferSize(fEngineControl->fBufferSize);
411 fEngine->NotifySampleRate(fEngineControl->fSampleRate);
414 fAudioDriver->SetMaster(
true);
415 return fAudioDriver->Start();
426 int JackServer::ReleaseTimebase(
int refnum)
428 return fEngineControl->fTransport.ResetTimebase(refnum);
431 int JackServer::SetTimebaseCallback(
int refnum,
int conditional)
433 return fEngineControl->fTransport.SetTimebaseMaster(refnum, conditional);
436 JackLockedEngine* JackServer::GetEngine()
441 JackSynchro* JackServer::GetSynchroTable()
443 return fSynchroTable;
446 JackEngineControl* JackServer::GetEngineControl()
448 return fEngineControl;
451 JackGraphManager* JackServer::GetGraphManager()
453 return fGraphManager;
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
SERVER_EXPORT void jack_log(const char *fmt,...)