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