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