Jack2
1.9.8
|
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 using namespace std; 00033 00034 namespace Jack 00035 { 00036 00037 JackAudioDriver::JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table) 00038 : JackDriver(name, alias, engine, table) 00039 {} 00040 00041 JackAudioDriver::~JackAudioDriver() 00042 {} 00043 00044 int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size) 00045 { 00046 // Update engine and graph manager state 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 } 00053 00054 UpdateLatencies(); 00055 00056 // Redirect on slaves drivers... 00057 return JackDriver::SetBufferSize(buffer_size); 00058 } 00059 00060 int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate) 00061 { 00062 fEngineControl->fSampleRate = sample_rate; 00063 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec 00064 if (!fEngineControl->fTimeOut) { 00065 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs); 00066 } 00067 00068 return JackDriver::SetSampleRate(sample_rate); 00069 } 00070 00071 int JackAudioDriver::Open(jack_nframes_t buffer_size, 00072 jack_nframes_t samplerate, 00073 bool capturing, 00074 bool playing, 00075 int inchannels, 00076 int outchannels, 00077 bool monitor, 00078 const char* capture_driver_name, 00079 const char* playback_driver_name, 00080 jack_nframes_t capture_latency, 00081 jack_nframes_t playback_latency) 00082 { 00083 fCaptureChannels = inchannels; 00084 fPlaybackChannels = outchannels; 00085 fWithMonitorPorts = monitor; 00086 memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); 00087 memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); 00088 memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); 00089 return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, 00090 monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); 00091 } 00092 00093 int JackAudioDriver::Open(bool capturing, 00094 bool playing, 00095 int inchannels, 00096 int outchannels, 00097 bool monitor, 00098 const char* capture_driver_name, 00099 const char* playback_driver_name, 00100 jack_nframes_t capture_latency, 00101 jack_nframes_t playback_latency) 00102 { 00103 fCaptureChannels = inchannels; 00104 fPlaybackChannels = outchannels; 00105 fWithMonitorPorts = monitor; 00106 memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); 00107 memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); 00108 memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM); 00109 return JackDriver::Open(capturing, playing, inchannels, outchannels, 00110 monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency); 00111 } 00112 00113 void JackAudioDriver::UpdateLatencies() 00114 { 00115 jack_latency_range_t input_range; 00116 jack_latency_range_t output_range; 00117 jack_latency_range_t monitor_range; 00118 00119 for (int i = 0; i < fCaptureChannels; i++) { 00120 input_range.max = input_range.min = fEngineControl->fBufferSize + fCaptureLatency; 00121 fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range); 00122 } 00123 00124 for (int i = 0; i < fPlaybackChannels; i++) { 00125 output_range.max = output_range.min = fPlaybackLatency; 00126 if (fEngineControl->fSyncMode) { 00127 output_range.max = output_range.min += fEngineControl->fBufferSize; 00128 } else { 00129 output_range.max = output_range.min += fEngineControl->fBufferSize * 2; 00130 } 00131 fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range); 00132 if (fWithMonitorPorts) { 00133 monitor_range.min = monitor_range.max = fEngineControl->fBufferSize; 00134 fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range); 00135 } 00136 } 00137 } 00138 00139 int JackAudioDriver::Attach() 00140 { 00141 JackPort* port; 00142 jack_port_id_t port_index; 00143 char name[REAL_JACK_PORT_NAME_SIZE]; 00144 char alias[REAL_JACK_PORT_NAME_SIZE]; 00145 int i; 00146 00147 jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); 00148 00149 for (i = 0; i < fCaptureChannels; i++) { 00150 snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); 00151 snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1); 00152 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { 00153 jack_error("driver: cannot register port for %s", name); 00154 return -1; 00155 } 00156 port = fGraphManager->GetPort(port_index); 00157 port->SetAlias(alias); 00158 fCapturePortList[i] = port_index; 00159 jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); 00160 } 00161 00162 for (i = 0; i < fPlaybackChannels; i++) { 00163 snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); 00164 snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1); 00165 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) { 00166 jack_error("driver: cannot register port for %s", name); 00167 return -1; 00168 } 00169 port = fGraphManager->GetPort(port_index); 00170 port->SetAlias(alias); 00171 fPlaybackPortList[i] = port_index; 00172 jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); 00173 00174 // Monitor ports 00175 if (fWithMonitorPorts) { 00176 jack_log("Create monitor port"); 00177 snprintf(name, sizeof(name), "%s:monitor_%u", fClientControl.fName, i + 1); 00178 if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize, &port_index) < 0) { 00179 jack_error("Cannot register monitor port for %s", name); 00180 return -1; 00181 } else { 00182 fMonitorPortList[i] = port_index; 00183 } 00184 } 00185 } 00186 00187 UpdateLatencies(); 00188 return 0; 00189 } 00190 00191 int JackAudioDriver::Detach() 00192 { 00193 int i; 00194 jack_log("JackAudioDriver::Detach"); 00195 00196 for (i = 0; i < fCaptureChannels; i++) { 00197 fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]); 00198 } 00199 00200 for (i = 0; i < fPlaybackChannels; i++) { 00201 fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]); 00202 if (fWithMonitorPorts) { 00203 fEngine->PortUnRegister(fClientControl.fRefNum, fMonitorPortList[i]); 00204 } 00205 } 00206 00207 return 0; 00208 } 00209 00210 int JackAudioDriver::Write() 00211 { 00212 for (int i = 0; i < fPlaybackChannels; i++) { 00213 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { 00214 jack_default_audio_sample_t* buffer = GetOutputBuffer(i); 00215 int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize; 00216 // Monitor ports 00217 if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) 00218 memcpy(GetMonitorBuffer(i), buffer, size); 00219 } 00220 } 00221 return 0; 00222 } 00223 00224 int JackAudioDriver::Process() 00225 { 00226 return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); 00227 } 00228 00229 /* 00230 The driver ASYNC mode: output buffers computed at the *previous cycle* are used, the server does not 00231 synchronize to the end of client graph execution. 00232 */ 00233 00234 int JackAudioDriver::ProcessAsync() 00235 { 00236 // Read input buffers for the current cycle 00237 if (Read() < 0) { 00238 jack_error("JackAudioDriver::ProcessAsync: read error, stopping..."); 00239 return -1; 00240 } 00241 00242 // Write output buffers from the previous cycle 00243 if (Write() < 0) { 00244 jack_error("JackAudioDriver::ProcessAsync: write error, stopping..."); 00245 return -1; 00246 } 00247 00248 // Process graph 00249 ProcessGraphAsync(); 00250 00251 // Keep end cycle time 00252 JackDriver::CycleTakeEndTime(); 00253 return 0; 00254 } 00255 00256 void JackAudioDriver::ProcessGraphAsync() 00257 { 00258 // Process graph 00259 if (fIsMaster) { 00260 ProcessGraphAsyncMaster(); 00261 } else { 00262 ProcessGraphAsyncSlave(); 00263 } 00264 } 00265 00266 void JackAudioDriver::ProcessGraphAsyncMaster() 00267 { 00268 // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle 00269 if (!fEngine->Process(fBeginDateUst, fEndDateUst)) { 00270 jack_error("JackAudioDriver::ProcessGraphAsyncMaster: Process error"); 00271 } 00272 00273 if (ResumeRefNum() < 0) { 00274 jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ResumeRefNum error"); 00275 } 00276 00277 if (ProcessReadSlaves() < 0) { 00278 jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessReadSlaves error"); 00279 } 00280 00281 if (ProcessWriteSlaves() < 0) { 00282 jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessWriteSlaves error"); 00283 } 00284 00285 // Does not wait on graph execution end 00286 } 00287 00288 void JackAudioDriver::ProcessGraphAsyncSlave() 00289 { 00290 if (ResumeRefNum() < 0) { 00291 jack_error("JackAudioDriver::ProcessGraphAsyncSlave: ResumeRefNum error"); 00292 } 00293 } 00294 00295 /* 00296 The driver SYNC mode: the server does synchronize to the end of client graph execution, 00297 if graph process succeed, output buffers computed at the *current cycle* are used. 00298 */ 00299 00300 int JackAudioDriver::ProcessSync() 00301 { 00302 // Read input buffers for the current cycle 00303 if (Read() < 0) { 00304 jack_error("JackAudioDriver::ProcessSync: read error, stopping..."); 00305 return -1; 00306 } 00307 00308 // Process graph 00309 ProcessGraphSync(); 00310 00311 // Write output buffers from the current cycle 00312 if (Write() < 0) { 00313 jack_error("JackAudioDriver::ProcessSync: write error, stopping..."); 00314 return -1; 00315 } 00316 00317 // Keep end cycle time 00318 JackDriver::CycleTakeEndTime(); 00319 return 0; 00320 } 00321 00322 void JackAudioDriver::ProcessGraphSync() 00323 { 00324 // Process graph 00325 if (fIsMaster) { 00326 ProcessGraphSyncMaster(); 00327 } else { 00328 ProcessGraphSyncSlave(); 00329 } 00330 } 00331 00332 void JackAudioDriver::ProcessGraphSyncMaster() 00333 { 00334 // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle 00335 if (fEngine->Process(fBeginDateUst, fEndDateUst)) { 00336 00337 if (ResumeRefNum() < 0) { 00338 jack_error("JackAudioDriver::ProcessGraphSyncMaster: ResumeRefNum error"); 00339 } 00340 00341 if (ProcessReadSlaves() < 0) { 00342 jack_error("JackAudioDriver::ProcessGraphSync: ProcessReadSlaves error, engine may now behave abnormally!!"); 00343 } 00344 00345 if (ProcessWriteSlaves() < 0) { 00346 jack_error("JackAudioDriver::ProcessGraphSync: ProcessWriteSlaves error, engine may now behave abnormally!!"); 00347 } 00348 00349 // Waits for graph execution end 00350 if (SuspendRefNum() < 0) { 00351 jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!"); 00352 } 00353 00354 } else { // Graph not finished: do not activate it 00355 jack_error("JackAudioDriver::ProcessGraphSync: Process error"); 00356 } 00357 } 00358 00359 void JackAudioDriver::ProcessGraphSyncSlave() 00360 { 00361 if (ResumeRefNum() < 0) { 00362 jack_error("JackAudioDriver::ProcessGraphSyncSlave: ResumeRefNum error"); 00363 } 00364 } 00365 00366 jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) 00367 { 00368 return fCapturePortList[port_index] 00369 ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize) 00370 : NULL; 00371 } 00372 00373 jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index) 00374 { 00375 return fPlaybackPortList[port_index] 00376 ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize) 00377 : NULL; 00378 } 00379 00380 jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) 00381 { 00382 return fPlaybackPortList[port_index] 00383 ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize) 00384 : NULL; 00385 } 00386 00387 int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) 00388 { 00389 switch (notify) { 00390 00391 case kLatencyCallback: 00392 HandleLatencyCallback(value1); 00393 break; 00394 00395 default: 00396 JackDriver::ClientNotify(refnum, name, notify, sync, message, value1, value2); 00397 break; 00398 } 00399 00400 return 0; 00401 } 00402 00403 void JackAudioDriver::HandleLatencyCallback(int status) 00404 { 00405 jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency; 00406 00407 for (int i = 0; i < fCaptureChannels; i++) { 00408 if (mode == JackPlaybackLatency) { 00409 fGraphManager->RecalculateLatency(fCapturePortList[i], mode); 00410 } 00411 } 00412 00413 for (int i = 0; i < fPlaybackChannels; i++) { 00414 if (mode == JackCaptureLatency) { 00415 fGraphManager->RecalculateLatency(fPlaybackPortList[i], mode); 00416 } 00417 } 00418 } 00419 00420 } // end of namespace