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