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"
40 JackServer::JackServer(
bool sync,
bool temporary,
int timeout,
bool rt,
int priority,
int port_max,
bool verbose, jack_timer_type_t clock,
const char* server_name)
43 jack_info(
"JACK server starting in realtime mode with priority %ld", priority);
45 jack_info(
"JACK server starting in non-realtime mode");
48 fGraphManager = JackGraphManager::Allocate(port_max);
49 fEngineControl =
new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name);
50 fEngine =
new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl);
56 JackFreewheelDriver *freewheelDriver =
57 new JackFreewheelDriver(fEngine, GetSynchroTable());
58 fThreadedFreewheelDriver =
new JackThreadedDriver(freewheelDriver);
60 fFreewheelDriver = freewheelDriver;
64 JackServerGlobals::fInstance =
this;
65 JackServerGlobals::fUserCount = 1;
66 JackGlobals::fVerbose = verbose;
69 JackServer::~JackServer()
71 JackGraphManager::Destroy(fGraphManager);
73 delete fThreadedFreewheelDriver;
75 delete fEngineControl;
81 JackMessageBuffer::Create();
83 if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) {
88 if (fChannel.Open(fEngineControl->fServerName,
this) < 0) {
93 if (fEngine->Open() < 0) {
98 if (fFreewheelDriver->Open() < 0) {
103 if (fAudioDriver->Attach() < 0) {
108 fFreewheelDriver->SetMaster(
false);
109 fAudioDriver->SetMaster(
true);
110 fAudioDriver->AddSlave(fFreewheelDriver);
112 SetClockSource(fEngineControl->fClockSource);
116 fFreewheelDriver->Close();
125 fAudioDriver->Close();
128 JackMessageBuffer::Destroy();
132 int JackServer::Close()
135 fEngine->NotifyQuit();
137 fAudioDriver->Detach();
138 fAudioDriver->Close();
139 fFreewheelDriver->Close();
142 JackMessageBuffer::Destroy();
146 int JackServer::InternalClientLoad1(
const char* client_name,
const char* so_name,
const char* objet_data,
int options,
int* int_ref,
int uuid,
int* status)
148 JackLoadableInternalClient* client =
new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data);
150 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
153 int JackServer::InternalClientLoad2(
const char* client_name,
const char* so_name,
const JSList * parameters,
int options,
int* int_ref,
int uuid,
int* status)
155 JackLoadableInternalClient* client =
new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters);
157 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
160 int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client,
const char* so_name,
const char* client_name,
int options,
int* int_ref,
int uuid,
int* status)
166 if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) {
168 int my_status1 = *status | JackFailure;
169 *status = (jack_status_t)my_status1;
173 *int_ref = client->GetClientControl()->fRefNum;
178 int JackServer::Start()
181 if (fAudioDriver->Start() < 0) {
184 return fChannel.Start();
187 int JackServer::Stop()
193 return fThreadedFreewheelDriver->Stop();
195 return fAudioDriver->Stop();
199 bool JackServer::IsRunning()
202 assert(fAudioDriver);
203 return fAudioDriver->IsRunning();
206 int JackServer::SetBufferSize(jack_nframes_t buffer_size)
208 jack_log(
"JackServer::SetBufferSize nframes = %ld", buffer_size);
209 jack_nframes_t current_buffer_size = fEngineControl->fBufferSize;
211 if (current_buffer_size == buffer_size) {
212 jack_log(
"SetBufferSize: requirement for new buffer size equals current value");
216 if (fAudioDriver->IsFixedBufferSize()) {
217 jack_log(
"SetBufferSize: driver only supports a fixed buffer size");
221 if (fAudioDriver->Stop() != 0) {
226 if (fAudioDriver->SetBufferSize(buffer_size) == 0) {
227 fEngine->NotifyBufferSize(buffer_size);
228 return fAudioDriver->Start();
230 jack_error(
"Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size);
231 fAudioDriver->SetBufferSize(current_buffer_size);
232 fAudioDriver->Start();
250 int JackServer::SetFreewheel(
bool onoff)
252 jack_log(
"JackServer::SetFreewheel is = %ld want = %ld", fFreewheel, onoff);
259 fThreadedFreewheelDriver->Stop();
260 fGraphManager->Restore(&fConnectionState);
261 fEngine->NotifyFreewheel(onoff);
262 fFreewheelDriver->SetMaster(
false);
263 fAudioDriver->SetMaster(
true);
264 return fAudioDriver->Start();
269 fAudioDriver->Stop();
270 fGraphManager->Save(&fConnectionState);
271 fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum);
272 fEngine->NotifyFreewheel(onoff);
273 fAudioDriver->SetMaster(
false);
274 fFreewheelDriver->SetMaster(
true);
275 return fThreadedFreewheelDriver->Start();
283 void JackServer::Notify(
int refnum,
int notify,
int value)
287 case kGraphOrderCallback:
288 fEngine->NotifyGraphReorder();
292 fEngine->NotifyXRun(refnum);
297 void JackServer::ClientKill(
int refnum)
299 jack_log(
"JackServer::ClientKill ref = %ld", refnum);
300 if (fEngine->ClientDeactivate(refnum) < 0) {
301 jack_error(
"JackServer::ClientKill ref = %ld cannot be removed from the graph !!", refnum);
303 if (fEngine->ClientExternalClose(refnum) < 0) {
304 jack_error(
"JackServer::ClientKill ref = %ld cannot be closed", refnum);
315 JackDriverClientInterface* slave = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
321 slave->SetMaster(
false);
322 fAudioDriver->AddSlave(slave);
328 JackDriverClientInterface* slave = info->GetBackend();
329 fAudioDriver->RemoveSlave(slave);
337 fAudioDriver->Stop();
338 fAudioDriver->Detach();
339 fAudioDriver->Close();
345 if (master == NULL) {
351 std::list<JackDriverInterface*> slave_list = fAudioDriver->GetSlaves();
352 std::list<JackDriverInterface*>::const_iterator it;
355 for (it = slave_list.begin(); it != slave_list.end(); it++) {
357 master->AddSlave(slave);
364 fAudioDriver = master;
366 fAudioDriver->Attach();
367 fAudioDriver->SetMaster(
true);
368 return fAudioDriver->Start();
375 int JackServer::ReleaseTimebase(
int refnum)
377 return fEngineControl->fTransport.ResetTimebase(refnum);
380 int JackServer::SetTimebaseCallback(
int refnum,
int conditional)
382 return fEngineControl->fTransport.SetTimebaseMaster(refnum, conditional);
385 JackLockedEngine* JackServer::GetEngine()
390 JackSynchro* JackServer::GetSynchroTable()
392 return fSynchroTable;
395 JackEngineControl* JackServer::GetEngineControl()
397 return fEngineControl;
400 JackGraphManager* JackServer::GetGraphManager()
402 return fGraphManager;