00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackSystemDeps.h"
00022 #include "JackServerGlobals.h"
00023 #include "JackTime.h"
00024 #include "JackFreewheelDriver.h"
00025 #include "JackDummyDriver.h"
00026 #include "JackThreadedDriver.h"
00027 #include "JackGlobals.h"
00028 #include "JackLockedEngine.h"
00029 #include "JackAudioDriver.h"
00030 #include "JackChannel.h"
00031 #include "JackClientControl.h"
00032 #include "JackEngineControl.h"
00033 #include "JackGraphManager.h"
00034 #include "JackInternalClient.h"
00035 #include "JackError.h"
00036 #include "JackMessageBuffer.h"
00037
00038 namespace Jack
00039 {
00040
00041 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)
00042 {
00043 if (rt) {
00044 jack_info("JACK server starting in realtime mode with priority %ld", priority);
00045 } else {
00046 jack_info("JACK server starting in non-realtime mode");
00047 }
00048
00049 fGraphManager = JackGraphManager::Allocate(port_max);
00050 fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name);
00051 fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl);
00052
00053
00054
00055
00056
00057 JackFreewheelDriver *freewheelDriver =
00058 new JackFreewheelDriver(fEngine, GetSynchroTable());
00059 fThreadedFreewheelDriver = new JackThreadedDriver(freewheelDriver);
00060
00061 fFreewheelDriver = freewheelDriver;
00062 fDriverInfo = new JackDriverInfo();
00063 fAudioDriver = NULL;
00064 fFreewheel = false;
00065 JackServerGlobals::fInstance = this;
00066 JackServerGlobals::fUserCount = 1;
00067 JackGlobals::fVerbose = verbose;
00068 }
00069
00070 JackServer::~JackServer()
00071 {
00072 JackGraphManager::Destroy(fGraphManager);
00073 delete fDriverInfo;
00074 delete fThreadedFreewheelDriver;
00075 delete fEngine;
00076 delete fEngineControl;
00077 }
00078
00079 int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params)
00080 {
00081
00082 JackMessageBuffer::Create();
00083
00084 if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) {
00085 jack_error("Cannot initialize driver");
00086 goto fail_close1;
00087 }
00088
00089 if (fChannel.Open(fEngineControl->fServerName, this) < 0) {
00090 jack_error("Server channel open error");
00091 goto fail_close2;
00092 }
00093
00094 if (fEngine->Open() < 0) {
00095 jack_error("Cannot open engine");
00096 goto fail_close3;
00097 }
00098
00099 if (fFreewheelDriver->Open() < 0) {
00100 jack_error("Cannot open freewheel driver");
00101 goto fail_close4;
00102 }
00103
00104 if (fAudioDriver->Attach() < 0) {
00105 jack_error("Cannot attach audio driver");
00106 goto fail_close5;
00107 }
00108
00109 fFreewheelDriver->SetMaster(false);
00110 fAudioDriver->SetMaster(true);
00111 fAudioDriver->AddSlave(fFreewheelDriver);
00112 InitTime();
00113 SetClockSource(fEngineControl->fClockSource);
00114 return 0;
00115
00116 fail_close5:
00117 fFreewheelDriver->Close();
00118
00119 fail_close4:
00120 fEngine->Close();
00121
00122 fail_close3:
00123 fChannel.Close();
00124
00125 fail_close2:
00126 fAudioDriver->Close();
00127
00128 fail_close1:
00129 JackMessageBuffer::Destroy();
00130 return -1;
00131 }
00132
00133 int JackServer::Close()
00134 {
00135 jack_log("JackServer::Close");
00136 fEngine->NotifyQuit();
00137 fChannel.Close();
00138 fAudioDriver->Detach();
00139 fAudioDriver->Close();
00140 fFreewheelDriver->Close();
00141 fEngine->Close();
00142
00143 JackMessageBuffer::Destroy();
00144 return 0;
00145 }
00146
00147 int JackServer::InternalClientLoad1(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int uuid, int* status)
00148 {
00149 JackLoadableInternalClient* client = new JackLoadableInternalClient1(JackServerGlobals::fInstance, GetSynchroTable(), objet_data);
00150 assert(client);
00151 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
00152 }
00153
00154 int JackServer::InternalClientLoad2(const char* client_name, const char* so_name, const JSList * parameters, int options, int* int_ref, int uuid, int* status)
00155 {
00156 JackLoadableInternalClient* client = new JackLoadableInternalClient2(JackServerGlobals::fInstance, GetSynchroTable(), parameters);
00157 assert(client);
00158 return InternalClientLoadAux(client, so_name, client_name, options, int_ref, uuid, status);
00159 }
00160
00161 int JackServer::InternalClientLoadAux(JackLoadableInternalClient* client, const char* so_name, const char* client_name, int options, int* int_ref, int uuid, int* status)
00162 {
00163
00164 *status = 0;
00165
00166
00167 if ((client->Init(so_name) < 0) || (client->Open(JACK_DEFAULT_SERVER_NAME, client_name, uuid, (jack_options_t)options, (jack_status_t*)status) < 0)) {
00168 delete client;
00169 int my_status1 = *status | JackFailure;
00170 *status = (jack_status_t)my_status1;
00171 *int_ref = 0;
00172 return -1;
00173 } else {
00174 *int_ref = client->GetClientControl()->fRefNum;
00175 return 0;
00176 }
00177 }
00178
00179 int JackServer::Start()
00180 {
00181 jack_log("JackServer::Start");
00182 if (fAudioDriver->Start() < 0) {
00183 return -1;
00184 }
00185 return fChannel.Start();
00186 }
00187
00188 int JackServer::Stop()
00189 {
00190 jack_log("JackServer::Stop");
00191 if (fFreewheel) {
00192 return fThreadedFreewheelDriver->Stop();
00193 } else {
00194 return fAudioDriver->Stop();
00195 }
00196 }
00197
00198 bool JackServer::IsRunning()
00199 {
00200 jack_log("JackServer::IsRunning");
00201 assert(fAudioDriver);
00202 return fAudioDriver->IsRunning();
00203 }
00204
00205 int JackServer::SetBufferSize(jack_nframes_t buffer_size)
00206 {
00207 jack_log("JackServer::SetBufferSize nframes = %ld", buffer_size);
00208 jack_nframes_t current_buffer_size = fEngineControl->fBufferSize;
00209
00210 if (current_buffer_size == buffer_size) {
00211 jack_log("SetBufferSize: requirement for new buffer size equals current value");
00212 return 0;
00213 }
00214
00215 if (fAudioDriver->IsFixedBufferSize()) {
00216 jack_log("SetBufferSize: driver only supports a fixed buffer size");
00217 return -1;
00218 }
00219
00220 if (fAudioDriver->Stop() != 0) {
00221 jack_error("Cannot stop audio driver");
00222 return -1;
00223 }
00224
00225 if (fAudioDriver->SetBufferSize(buffer_size) == 0) {
00226 fFreewheelDriver->SetBufferSize(buffer_size);
00227 fEngine->NotifyBufferSize(buffer_size);
00228 return fAudioDriver->Start();
00229 } else {
00230 jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size);
00231 fAudioDriver->SetBufferSize(current_buffer_size);
00232 fFreewheelDriver->SetBufferSize(current_buffer_size);
00233 fAudioDriver->Start();
00234
00235 return -1;
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 int JackServer::SetFreewheel(bool onoff)
00252 {
00253 jack_log("JackServer::SetFreewheel is = %ld want = %ld", fFreewheel, onoff);
00254
00255 if (fFreewheel) {
00256 if (onoff) {
00257 return -1;
00258 } else {
00259 fFreewheel = false;
00260 fThreadedFreewheelDriver->Stop();
00261 fGraphManager->Restore(&fConnectionState);
00262 fEngine->NotifyFreewheel(onoff);
00263 fFreewheelDriver->SetMaster(false);
00264 fAudioDriver->SetMaster(true);
00265 return fAudioDriver->Start();
00266 }
00267 } else {
00268 if (onoff) {
00269 fFreewheel = true;
00270 fAudioDriver->Stop();
00271 fGraphManager->Save(&fConnectionState);
00272 fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum);
00273 fEngine->NotifyFreewheel(onoff);
00274 fAudioDriver->SetMaster(false);
00275 fFreewheelDriver->SetMaster(true);
00276 return fThreadedFreewheelDriver->Start();
00277 } else {
00278 return -1;
00279 }
00280 }
00281 }
00282
00283
00284 void JackServer::Notify(int refnum, int notify, int value)
00285 {
00286 switch (notify) {
00287
00288 case kGraphOrderCallback:
00289 fEngine->NotifyGraphReorder();
00290 break;
00291
00292 case kXRunCallback:
00293 fEngine->NotifyXRun(refnum);
00294 break;
00295 }
00296 }
00297
00298 void JackServer::ClientKill(int refnum)
00299 {
00300 jack_log("JackServer::ClientKill ref = %ld", refnum);
00301 if (fEngine->ClientDeactivate(refnum) < 0) {
00302 jack_error("JackServer::ClientKill ref = %ld cannot be removed from the graph !!", refnum);
00303 }
00304 if (fEngine->ClientExternalClose(refnum) < 0) {
00305 jack_error("JackServer::ClientKill ref = %ld cannot be closed", refnum);
00306 }
00307 }
00308
00309
00310
00311
00312
00313 JackDriverInfo* JackServer::AddSlave(jack_driver_desc_t* driver_desc, JSList* driver_params)
00314 {
00315 JackDriverInfo* info = new JackDriverInfo();
00316 JackDriverClientInterface* slave = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
00317 if (slave == NULL) {
00318 delete info;
00319 return NULL;
00320 }
00321 slave->Attach();
00322 slave->SetMaster(false);
00323 fAudioDriver->AddSlave(slave);
00324 return info;
00325 }
00326
00327 void JackServer::RemoveSlave(JackDriverInfo* info)
00328 {
00329 JackDriverClientInterface* slave = info->GetBackend();
00330 fAudioDriver->RemoveSlave(slave);
00331 slave->Detach();
00332 slave->Close();
00333 }
00334
00335 int JackServer::SwitchMaster(jack_driver_desc_t* driver_desc, JSList* driver_params)
00336 {
00338 fAudioDriver->Stop();
00339 fAudioDriver->Detach();
00340 fAudioDriver->Close();
00341
00342
00343 JackDriverInfo* info = new JackDriverInfo();
00344 JackDriverClientInterface* master = info->Open(driver_desc, fEngine, GetSynchroTable(), driver_params);
00345
00346 if (master == NULL) {
00347 delete info;
00348 return -1;
00349 }
00350
00351
00352 std::list<JackDriverInterface*> slave_list = fAudioDriver->GetSlaves();
00353 std::list<JackDriverInterface*>::const_iterator it;
00354
00355
00356 for (it = slave_list.begin(); it != slave_list.end(); it++) {
00357 JackDriverInterface* slave = *it;
00358 master->AddSlave(slave);
00359 }
00360
00361
00362 delete fDriverInfo;
00363
00364
00365 fAudioDriver = master;
00366 fDriverInfo = info;
00367 fAudioDriver->Attach();
00368 fAudioDriver->SetMaster(true);
00369 return fAudioDriver->Start();
00370 }
00371
00372
00373
00374
00375
00376 int JackServer::ReleaseTimebase(int refnum)
00377 {
00378 return fEngineControl->fTransport.ResetTimebase(refnum);
00379 }
00380
00381 int JackServer::SetTimebaseCallback(int refnum, int conditional)
00382 {
00383 return fEngineControl->fTransport.SetTimebaseMaster(refnum, conditional);
00384 }
00385
00386 JackLockedEngine* JackServer::GetEngine()
00387 {
00388 return fEngine;
00389 }
00390
00391 JackSynchro* JackServer::GetSynchroTable()
00392 {
00393 return fSynchroTable;
00394 }
00395
00396 JackEngineControl* JackServer::GetEngineControl()
00397 {
00398 return fEngineControl;
00399 }
00400
00401 JackGraphManager* JackServer::GetGraphManager()
00402 {
00403 return fGraphManager;
00404 }
00405
00406
00407 }
00408