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 if (!JackMessageBuffer::Create()) {
85 if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) {
90 if (fChannel.Open(fEngineControl->fServerName,
this) < 0) {
95 if (fEngine->Open() < 0) {
100 if (fFreewheelDriver->Open() < 0) {
105 if (fAudioDriver->Attach() < 0) {
110 fFreewheelDriver->SetMaster(
false);
111 fAudioDriver->SetMaster(
true);
112 fAudioDriver->AddSlave(fFreewheelDriver);
114 SetClockSource(fEngineControl->fClockSource);
118 fFreewheelDriver->Close();
127 fAudioDriver->Close();
130 JackMessageBuffer::Destroy();
134 int JackServer::Close()
138 fAudioDriver->Detach();
139 fAudioDriver->Close();
140 fFreewheelDriver->Close();
143 JackMessageBuffer::Destroy();
148 int JackServer::InternalClientLoad1(
const char* client_name,
const char* so_name,
const char* objet_data,
int options,
int* int_ref,
int uuid,
int* status)
150 JackLoadableInternalClient* client =
new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data);
152 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
155 int JackServer::InternalClientLoad2(
const char* client_name,
const char* so_name,
const JSList * parameters,
int options,
int* int_ref,
int uuid,
int* status)
157 JackLoadableInternalClient* client =
new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters);
159 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
162 int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client,
const char* so_name,
const char* client_name,
int options,
int* int_ref,
int uuid,
int* status)
168 if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) {
170 int my_status1 = *status | JackFailure;
171 *status = (jack_status_t)my_status1;
175 *int_ref = client->GetClientControl()->fRefNum;
180 int JackServer::Start()
183 if (fAudioDriver->Start() < 0) {
186 return fChannel.Start();
189 int JackServer::Stop()
192 fEngine->NotifyQuit();
198 return fThreadedFreewheelDriver->Stop();
200 return fAudioDriver->Stop();
204 bool JackServer::IsRunning()
207 assert(fAudioDriver);
208 return fAudioDriver->IsRunning();
211 int JackServer::SetBufferSize(jack_nframes_t buffer_size)
213 jack_log(
"JackServer::SetBufferSize nframes = %ld", buffer_size);
214 jack_nframes_t current_buffer_size = fEngineControl->fBufferSize;
216 if (current_buffer_size == buffer_size) {
217 jack_log(
"SetBufferSize: requirement for new buffer size equals current value");
221 if (fAudioDriver->IsFixedBufferSize()) {
222 jack_log(
"SetBufferSize: driver only supports a fixed buffer size");
226 if (fAudioDriver->Stop() != 0) {
231 if (fAudioDriver->SetBufferSize(buffer_size) == 0) {
232 fEngine->NotifyBufferSize(buffer_size);
233 return fAudioDriver->Start();
235 jack_error(
"Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size);
236 fAudioDriver->SetBufferSize(current_buffer_size);
237 fAudioDriver->Start();
255 int JackServer::SetFreewheel(
bool onoff)
257 jack_log(
"JackServer::SetFreewheel is = %ld want = %ld", fFreewheel, onoff);
264 fThreadedFreewheelDriver->Stop();
265 fGraphManager->Restore(&fConnectionState);
266 fEngine->NotifyFreewheel(onoff);
267 fFreewheelDriver->SetMaster(
false);
268 fAudioDriver->SetMaster(
true);
269 return fAudioDriver->Start();
274 fAudioDriver->Stop();
275 fGraphManager->Save(&fConnectionState);
276 fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum);
277 fEngine->NotifyFreewheel(onoff);
278 fAudioDriver->SetMaster(
false);
279 fFreewheelDriver->SetMaster(
true);
280 return fThreadedFreewheelDriver->Start();
288 void JackServer::Notify(
int refnum,
int notify,
int value)
292 case kGraphOrderCallback:
293 fEngine->NotifyGraphReorder();
297 fEngine->NotifyXRun(refnum);
302 void JackServer::ClientKill(
int refnum)
304 jack_log(
"JackServer::ClientKill ref = %ld", refnum);
305 if (fEngine->ClientDeactivate(refnum) < 0) {
306 jack_error(
"JackServer::ClientKill ref = %ld cannot be removed from the graph !!", refnum);
308 if (fEngine->ClientExternalClose(refnum) < 0) {
309 jack_error(
"JackServer::ClientKill ref = %ld cannot be closed", refnum);
320 JackDriverClientInterface* slave = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
326 slave->SetMaster(
false);
327 fAudioDriver->AddSlave(slave);
333 JackDriverClientInterface* slave = info->GetBackend();
334 fAudioDriver->RemoveSlave(slave);
342 fAudioDriver->Stop();
343 fAudioDriver->Detach();
344 fAudioDriver->Close();
350 if (master == NULL) {
356 std::list<JackDriverInterface*> slave_list = fAudioDriver->GetSlaves();
357 std::list<JackDriverInterface*>::const_iterator it;
360 for (it = slave_list.begin(); it != slave_list.end(); it++) {
362 master->AddSlave(slave);
369 fAudioDriver = master;
371 fAudioDriver->Attach();
372 fAudioDriver->SetMaster(
true);
373 return fAudioDriver->Start();
380 int JackServer::ReleaseTimebase(
int refnum)
382 return fEngineControl->fTransport.ResetTimebase(refnum);
385 int JackServer::SetTimebaseCallback(
int refnum,
int conditional)
387 return fEngineControl->fTransport.SetTimebaseMaster(refnum, conditional);
390 JackLockedEngine* JackServer::GetEngine()
395 JackSynchro* JackServer::GetSynchroTable()
397 return fSynchroTable;
400 JackEngineControl* JackServer::GetEngineControl()
402 return fEngineControl;
405 JackGraphManager* JackServer::GetGraphManager()
407 return fGraphManager;
The base interface for drivers.
SERVER_EXPORT void jack_error(const char *fmt,...)
SERVER_EXPORT void jack_info(const char *fmt,...)
The base interface for drivers clients.
int SwitchMaster(jack_driver_desc_t *driver_desc, JSList *driver_params)
SERVER_EXPORT void jack_log(const char *fmt,...)