00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef WIN32
00022 #pragma warning (disable : 4786)
00023 #endif
00024
00025 #include "JackServer.h"
00026 #include "JackTime.h"
00027 #include "JackFreewheelDriver.h"
00028 #include "JackLoopbackDriver.h"
00029 #include "JackThreadedDriver.h"
00030 #include "JackGlobals.h"
00031 #include "JackEngine.h"
00032 #include "JackAudioDriver.h"
00033 #include "JackChannel.h"
00034 #include "JackClientControl.h"
00035 #include "JackEngineControl.h"
00036 #include "JackSyncInterface.h"
00037 #include "JackGraphManager.h"
00038 #include "JackInternalClient.h"
00039
00040 namespace Jack
00041 {
00042
00043 JackServer* JackServer::fInstance = NULL;
00044
00045 JackServer::JackServer(bool sync, bool temporary, long timeout, bool rt, long priority, long loopback, bool verbose, const char* server_name)
00046 {
00047 JackGlobals::InitServer();
00048 for (int i = 0; i < CLIENT_NUM; i++)
00049 fSynchroTable[i] = JackGlobals::MakeSynchro();
00050 fGraphManager = new JackGraphManager();
00051 fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, server_name);
00052 fEngine = new JackEngine(fGraphManager, fSynchroTable, fEngineControl);
00053 fFreewheelDriver = new JackThreadedDriver(new JackFreewheelDriver("freewheel", fEngine, fSynchroTable));
00054 fLoopbackDriver = new JackLoopbackDriver("loopback", fEngine, fSynchroTable);
00055 fChannel = JackGlobals::MakeServerChannel();
00056 fFreewheel = false;
00057 fLoopback = loopback;
00058 fDriverInfo = NULL;
00059 fAudioDriver = NULL;
00060 fInstance = this;
00061 jack_verbose = verbose;
00062 }
00063
00064 JackServer::~JackServer()
00065 {
00066 for (int i = 0; i < CLIENT_NUM; i++)
00067 delete fSynchroTable[i];
00068 delete fGraphManager;
00069 delete fAudioDriver;
00070 delete fFreewheelDriver;
00071 delete fLoopbackDriver;
00072 delete fEngine;
00073 delete fChannel;
00074 delete fEngineControl;
00075 if (fDriverInfo) {
00076 UnloadDriverModule(fDriverInfo->handle);
00077 free(fDriverInfo);
00078 }
00079 JackGlobals::Destroy();
00080 }
00081
00082
00083
00084 int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params)
00085 {
00086 if (fChannel->Open(fEngineControl->fServerName, this) < 0) {
00087 jack_error("Server channel open error");
00088 return -1;
00089 }
00090
00091 if (fEngine->Open() != 0) {
00092 jack_error("Cannot open engine");
00093 return -1;
00094 }
00095
00096 if ((fDriverInfo = jack_load_driver(driver_desc)) == NULL) {
00097 return -1;
00098 }
00099
00100 if ((fAudioDriver = fDriverInfo->initialize(fEngine, fSynchroTable, driver_params)) == NULL) {
00101 jack_error("Cannot initialize driver");
00102 return -1;
00103 }
00104
00105 if (fFreewheelDriver->Open() != 0) {
00106 jack_error("Cannot open driver");
00107 return -1;
00108 }
00109
00110
00111 if (fLoopbackDriver->Open(fEngineControl->fBufferSize, fEngineControl->fSampleRate, 1, 1, fLoopback, fLoopback, false, "loopback", "loopback", 0, 0) != 0) {
00112 jack_error("Cannot open driver");
00113 return -1;
00114 }
00115
00116 if (fAudioDriver->Attach() != 0) {
00117 jack_error("Cannot attach audio driver");
00118 return -1;
00119 }
00120
00121 if (fLoopback > 0 && fLoopbackDriver->Attach() != 0) {
00122 jack_error("Cannot attach loopback driver");
00123 return -1;
00124 }
00125
00126 fFreewheelDriver->SetMaster(false);
00127 fAudioDriver->SetMaster(true);
00128 if (fLoopback > 0)
00129 fAudioDriver->AddSlave(fLoopbackDriver);
00130 fAudioDriver->AddSlave(fFreewheelDriver);
00131 InitTime();
00132 return 0;
00133 }
00134
00135 int JackServer::Close()
00136 {
00137 JackLog("JackServer::Close\n");
00138 fChannel->Close();
00139 fAudioDriver->Detach();
00140 if (fLoopback > 0)
00141 fLoopbackDriver->Detach();
00142 fAudioDriver->Close();
00143 fFreewheelDriver->Close();
00144 fLoopbackDriver->Close();
00145 fEngine->Close();
00146 return 0;
00147 }
00148
00149 int JackServer::InternalClientLoad(const char* client_name, const char* so_name, const char* objet_data, int options, int* int_ref, int* status)
00150 {
00151 try {
00152
00153 *status = 0;
00154 JackLoadableInternalClient* client = new JackLoadableInternalClient(fInstance, GetSynchroTable(), so_name, objet_data);
00155 assert(client);
00156 int res = client->Open("unused", client_name, (jack_options_t)options, (jack_status_t*)status);
00157 if (res < 0) {
00158 delete client;
00159 *int_ref = 0;
00160 } else {
00161 *int_ref = client->GetClientControl()->fRefNum;
00162 }
00163 } catch (...) {
00164 int my_status1 = *status | JackFailure;
00165 *status = (jack_status_t)my_status1;
00166 *int_ref = 0;
00167 }
00168
00169 return 0;
00170 }
00171
00172 int JackServer::Start()
00173 {
00174 JackLog("JackServer::Start\n");
00175 fEngineControl->InitFrameTime();
00176 return fAudioDriver->Start();
00177 }
00178
00179 int JackServer::Stop()
00180 {
00181 JackLog("JackServer::Stop\n");
00182 return fAudioDriver->Stop();
00183 }
00184
00185 int JackServer::SetBufferSize(jack_nframes_t buffer_size)
00186 {
00187 JackLog("JackServer::SetBufferSize nframes = %ld\n", buffer_size);
00188 jack_nframes_t current_buffer_size = fEngineControl->fBufferSize;
00189
00190 if (fAudioDriver->Stop() != 0) {
00191 jack_error("Cannot stop audio driver");
00192 return -1;
00193 }
00194
00195 if (fAudioDriver->SetBufferSize(buffer_size) == 0) {
00196 fFreewheelDriver->SetBufferSize(buffer_size);
00197 fEngine->NotifyBufferSize(buffer_size);
00198 fEngineControl->InitFrameTime();
00199 return fAudioDriver->Start();
00200 } else {
00201 jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size);
00202 fFreewheelDriver->SetBufferSize(current_buffer_size);
00203 fEngineControl->InitFrameTime();
00204 return fAudioDriver->Start();
00205 }
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 int JackServer::SetFreewheel(bool onoff)
00221 {
00222 JackLog("JackServer::SetFreewheel state = %ld\n", onoff);
00223
00224 if (fFreewheel) {
00225 if (onoff) {
00226 return -1;
00227 } else {
00228 fFreewheel = false;
00229 fFreewheelDriver->Stop();
00230 fGraphManager->Restore(&fConnectionState);
00231 fEngine->NotifyFreewheel(onoff);
00232 fFreewheelDriver->SetMaster(false);
00233 fEngineControl->InitFrameTime();
00234 return fAudioDriver->Start();
00235 }
00236 } else {
00237 if (onoff) {
00238 fFreewheel = true;
00239 fAudioDriver->Stop();
00240 fGraphManager->Save(&fConnectionState);
00241 fGraphManager->DisconnectAllPorts(fAudioDriver->GetClientControl()->fRefNum);
00242 fEngine->NotifyFreewheel(onoff);
00243 fFreewheelDriver->SetMaster(true);
00244 return fFreewheelDriver->Start();
00245 } else {
00246 return -1;
00247 }
00248 }
00249 }
00250
00251
00252 void JackServer::Notify(int refnum, int notify, int value)
00253 {
00254 switch (notify) {
00255
00256 case kGraphOrderCallback:
00257 fEngine->NotifyGraphReorder();
00258 break;
00259
00260 case kXRunCallback:
00261 fEngine->NotifyXRun(refnum);
00262 break;
00263
00264 case kDeadClient:
00265 JackLog("JackServer: kDeadClient ref = %ld\n", refnum);
00266 if (fEngine->ClientDeactivate(refnum) < 0)
00267 jack_error("JackServer: DeadClient ref = %ld cannot be removed from the graph !!", refnum);
00268 fEngine->ClientExternalClose(refnum);
00269 break;
00270 }
00271 }
00272
00273
00274
00275
00276
00277 int JackServer::ReleaseTimebase(int refnum)
00278 {
00279 return fEngineControl->fTransport.ResetTimebase(refnum);
00280 }
00281
00282 int JackServer::SetTimebaseCallback(int refnum, int conditional)
00283 {
00284 return fEngineControl->fTransport.SetTimebase(refnum, conditional);
00285 }
00286
00287 JackEngine* JackServer::GetEngine()
00288 {
00289 return fEngine;
00290 }
00291
00292 JackSynchro** JackServer::GetSynchroTable()
00293 {
00294 return fSynchroTable;
00295 }
00296
00297 JackEngineControl* JackServer::GetEngineControl()
00298 {
00299 return fEngineControl;
00300 }
00301
00302 JackGraphManager* JackServer::GetGraphManager()
00303 {
00304 return fGraphManager;
00305 }
00306
00307 }
00308