Jack2
1.9.7
|
00001 /* 00002 Copyright (C) 2001 Paul Davis 00003 Copyright (C) 2004-2008 Grame. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 (at your option) any later version. 00012 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 00019 */ 00020 00021 #include "JackSystemDeps.h" 00022 #include "JackAudioDriver.h" 00023 #include "JackTime.h" 00024 #include "JackError.h" 00025 #include "JackEngineControl.h" 00026 #include "JackPort.h" 00027 #include "JackGraphManager.h" 00028 #include "JackLockedEngine.h" 00029 #include "JackException.h" 00030 #include <assert.h> 00031 00032 namespace Jack 00033 { 00034 00035 JackAudioDriver::JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) 00036 : JackDriver(name, alias, engine, table), 00037 fCaptureChannels(0), 00038 fPlaybackChannels(0), 00039 fWithMonitorPorts(false) 00040 {} 00041 00042 JackAudioDriver::~JackAudioDriver() 00043 {} 00044 00045 int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size) 00046 { 00047 fEngineControl->fBufferSize = buffer_size; 00048 fGraphManager->SetBufferSize(buffer_size); 00049 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec 00050 if (!fEngineControl->fTimeOut) 00051 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); 00052 return 0; 00053 } 00054 00055 int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate) 00056 { 00057 fEngineControl->fSampleRate = sample_rate; 00058 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec 00059 if (!fEngineControl->fTimeOut) 00060 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); 00061 return 0; 00062 } 00063 00064 int JackAudioDriver::Open(jack_nframes_t buffer_size, 00065 jack_nframes_t samplerate, 00066 bool capturing, 00067 bool playing, 00068 int inchannels, 00069 int outchannels, 00070 bool monitor, 00071 const char* capture_driver_name, 00072 const char* playback_driver_name, 00073 jack_nframes_t capture_latency, 00074 jack_nframes_t playback_latency) 00075 { 00076 fCaptureChannels = inchannels; 00077 fPlaybackChannels = outchannels; 00078 fWithMonitorPorts = monitor; 00079 return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); 00080 } 00081 00082 int JackAudioDriver::Open(bool capturing, 00083 bool playing, 00084 int inchannels, 00085 int outchannels, 00086 bool monitor, 00087 const char* capture_driver_name, 00088 const char* playback_driver_name, 00089 jack_nframes_t capture_latency, 00090 jack_nframes_t playback_latency) 00091 { 00092 fCaptureChannels = inchannels; 00093 fPlaybackChannels = outchannels; 00094 fWithMonitorPorts = monitor; 00095 return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); 00096 } 00097 00098 int JackAudioDriver::Attach() 00099 { 00100 JackPort* port; 00101 jack_port_id_t port_index; 00102 char name[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; 00103 char alias[JACK_CLIENT_NAME_SIZE + JACK_PORT_NAME_SIZE]; 00104 jack_latency_range_t range; 00105 int i; 00106 00107 jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); 00108 00109 for (i = 0; i < fCaptureChannels; i++) { 00110 snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); 00111 snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); 00112 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { 00113 jack_error("driver: cannot register port for %s", name); 00114 return -1; 00115 } 00116 port = fGraphManager->GetPort(port_index); 00117 port->SetAlias(alias); 00118 range.min = range.max = fEngineControl->fBufferSize + fCaptureLatency; 00119 port->SetLatencyRange(JackCaptureLatency, &range); 00120 fCapturePortList[i] = port_index; 00121 jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); 00122 } 00123 00124 for (i = 0; i < fPlaybackChannels; i++) { 00125 snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); 00126 snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); 00127 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { 00128 jack_error("driver: cannot register port for %s", name); 00129 return -1; 00130 } 00131 port = fGraphManager->GetPort(port_index); 00132 port->SetAlias(alias); 00133 // Add more latency if "async" mode is used... 00134 range.min = range.max = fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + fPlaybackLatency; 00135 port->SetLatencyRange(JackPlaybackLatency, &range); 00136 fPlaybackPortList[i] = port_index; 00137 jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); 00138 00139 // Monitor ports 00140 if (fWithMonitorPorts) { 00141 jack_log("Create monitor port"); 00142 snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); 00143 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { 00144 jack_error("Cannot register monitor port for %s", name); 00145 return -1; 00146 } else { 00147 port = fGraphManager->GetPort(port_index); 00148 range.min = range.max = fEngineControl->fBufferSize; 00149 port->SetLatencyRange(JackCaptureLatency, &range); 00150 fMonitorPortList[i] = port_index; 00151 } 00152 } 00153 } 00154 00155 return 0; 00156 } 00157 00158 int JackAudioDriver::Detach() 00159 { 00160 int i; 00161 jack_log("JackAudioDriver::Detach"); 00162 00163 for (i = 0; i < fCaptureChannels; i++) { 00164 fGraphManager->ReleasePort(fClientControl.fRefNum, fCapturePortList[i]); 00165 } 00166 00167 for (i = 0; i < fPlaybackChannels; i++) { 00168 fGraphManager->ReleasePort(fClientControl.fRefNum, fPlaybackPortList[i]); 00169 if (fWithMonitorPorts) 00170 fGraphManager->ReleasePort(fClientControl.fRefNum, fMonitorPortList[i]); 00171 } 00172 00173 return 0; 00174 } 00175 00176 int JackAudioDriver::Write() 00177 { 00178 for (int i = 0; i < fPlaybackChannels; i++) { 00179 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { 00180 jack_default_audio_sample_t* buffer = GetOutputBuffer(i); 00181 int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; 00182 // Monitor ports 00183 if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) 00184 memcpy(GetMonitorBuffer(i), buffer, size); 00185 } 00186 } 00187 return 0; 00188 } 00189 00190 int JackAudioDriver::ProcessNull() 00191 { 00192 // Keep begin cycle time 00193 JackDriver::CycleTakeBeginTime(); 00194 00195 if (fEngineControl->fSyncMode) { 00196 ProcessGraphSync(); 00197 } else { 00198 ProcessGraphAsync(); 00199 } 00200 00201 // Keep end cycle time 00202 JackDriver::CycleTakeEndTime(); 00203 WaitUntilNextCycle(); 00204 return 0; 00205 } 00206 00207 int JackAudioDriver::Process() 00208 { 00209 return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); 00210 } 00211 00212 /* 00213 The driver ASYNC mode: output buffers computed at the *previous cycle* are used, the server does not 00214 synchronize to the end of client graph execution. 00215 */ 00216 00217 int JackAudioDriver::ProcessAsync() 00218 { 00219 // Read input buffers for the current cycle 00220 if (Read() < 0) { 00221 jack_error("JackAudioDriver::ProcessAsync: read error, stopping..."); 00222 return -1; 00223 } 00224 00225 // Write output buffers from the previous cycle 00226 if (Write() < 0) { 00227 jack_error("JackAudioDriver::ProcessAsync: write error, stopping..."); 00228 return -1; 00229 } 00230 00231 // Process graph 00232 if (fIsMaster) { 00233 ProcessGraphAsync(); 00234 } else { 00235 fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); 00236 } 00237 00238 // Keep end cycle time 00239 JackDriver::CycleTakeEndTime(); 00240 return 0; 00241 } 00242 00243 /* 00244 The driver SYNC mode: the server does synchronize to the end of client graph execution, 00245 if graph process succeed, output buffers computed at the *current cycle* are used. 00246 */ 00247 00248 int JackAudioDriver::ProcessSync() 00249 { 00250 // Read input buffers for the current cycle 00251 if (Read() < 0) { 00252 jack_error("JackAudioDriver::ProcessSync: read error, stopping..."); 00253 return -1; 00254 } 00255 00256 // Process graph 00257 if (fIsMaster) { 00258 if (ProcessGraphSync() < 0) { 00259 jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); 00260 goto end; 00261 } 00262 } else { 00263 if (fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable) < 0) { 00264 jack_error("JackAudioDriver::ProcessSync: process error, skip cycle..."); 00265 goto end; 00266 } 00267 } 00268 00269 // Write output buffers from the current cycle 00270 if (Write() < 0) { 00271 jack_error("JackAudioDriver::ProcessSync: write error, stopping..."); 00272 return -1; 00273 } 00274 00275 end: 00276 00277 // Keep end cycle time 00278 JackDriver::CycleTakeEndTime(); 00279 return 0; 00280 } 00281 00282 void JackAudioDriver::ProcessGraphAsync() 00283 { 00284 // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle 00285 if (!fEngine->Process(fBeginDateUst, fEndDateUst)) 00286 jack_error("JackAudioDriver::ProcessGraphAsync: Process error"); 00287 fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); 00288 if (ProcessSlaves() < 0) 00289 jack_error("JackAudioDriver::ProcessGraphAsync: ProcessSlaves error"); 00290 } 00291 00292 int JackAudioDriver::ProcessGraphSync() 00293 { 00294 int res = 0; 00295 00296 // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle 00297 if (fEngine->Process(fBeginDateUst, fEndDateUst)) { 00298 fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); 00299 if (ProcessSlaves() < 0) { 00300 jack_error("JackAudioDriver::ProcessGraphSync: ProcessSlaves error, engine may now behave abnormally!!"); 00301 res = -1; 00302 } 00303 if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) { 00304 jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!"); 00305 res = -1; 00306 } 00307 } else { // Graph not finished: do not activate it 00308 jack_error("JackAudioDriver::ProcessGraphSync: Process error"); 00309 res = -1; 00310 } 00311 00312 return res; 00313 } 00314 00315 int JackAudioDriver::Start() 00316 { 00317 int res = JackDriver::Start(); 00318 if ((res >= 0) && fIsMaster) { 00319 res = StartSlaves(); 00320 } 00321 return res; 00322 } 00323 00324 int JackAudioDriver::Stop() 00325 { 00326 int res = JackDriver::Stop(); 00327 if (fIsMaster) { 00328 if (StopSlaves() < 0) { 00329 res = -1; 00330 } 00331 } 00332 return res; 00333 } 00334 00335 void JackAudioDriver::WaitUntilNextCycle() 00336 { 00337 int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f)); 00338 wait_time_usec = int(wait_time_usec - (GetMicroSeconds() - fBeginDateUst)); 00339 if (wait_time_usec > 0) 00340 JackSleep(wait_time_usec); 00341 } 00342 00343 jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) 00344 { 00345 assert(fCapturePortList[port_index]); 00346 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize); 00347 } 00348 00349 jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index) 00350 { 00351 assert(fPlaybackPortList[port_index]); 00352 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize); 00353 } 00354 00355 jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) 00356 { 00357 assert(fPlaybackPortList[port_index]); 00358 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize); 00359 } 00360 00361 int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) 00362 { 00363 switch (notify) { 00364 00365 case kLatencyCallback: 00366 HandleLatencyCallback(value1); 00367 break; 00368 00369 default: 00370 JackDriver::ClientNotify(refnum, name, notify, sync, message, value1, value2); 00371 break; 00372 } 00373 00374 return 0; 00375 } 00376 00377 void JackAudioDriver::HandleLatencyCallback(int status) 00378 { 00379 jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; 00380 00381 for (int i = 0; i < fCaptureChannels; i++) { 00382 if (mode == JackPlaybackLatency) { 00383 fGraphManager->RecalculateLatency(fCapturePortList[i], mode); 00384 } 00385 } 00386 00387 for (int i = 0; i < fPlaybackChannels; i++) { 00388 if (mode == JackCaptureLatency) { 00389 fGraphManager->RecalculateLatency(fPlaybackPortList[i], mode); 00390 } 00391 } 00392 } 00393 00394 } // end of namespace