Jack2 1.9.6
|
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 int i; 00105 00106 jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate); 00107 00108 for (i = 0; i < fCaptureChannels; i++) { 00109 snprintf(alias, sizeof(alias) - 1, "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1); 00110 snprintf(name, sizeof(name) - 1, "%s:capture_%d", fClientControl.fName, i + 1); 00111 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { 00112 jack_error("driver: cannot register port for %s", name); 00113 return -1; 00114 } 00115 port = fGraphManager->GetPort(port_index); 00116 port->SetAlias(alias); 00117 port->SetLatency(fEngineControl->fBufferSize + fCaptureLatency); 00118 fCapturePortList[i] = port_index; 00119 jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index); 00120 } 00121 00122 for (i = 0; i < fPlaybackChannels; i++) { 00123 snprintf(alias, sizeof(alias) - 1, "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1); 00124 snprintf(name, sizeof(name) - 1, "%s:playback_%d", fClientControl.fName, i + 1); 00125 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize)) == NO_PORT) { 00126 jack_error("driver: cannot register port for %s", name); 00127 return -1; 00128 } 00129 port = fGraphManager->GetPort(port_index); 00130 port->SetAlias(alias); 00131 // Add more latency if "async" mode is used... 00132 port->SetLatency(fEngineControl->fBufferSize + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + fPlaybackLatency); 00133 fPlaybackPortList[i] = port_index; 00134 jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index); 00135 00136 // Monitor ports 00137 if (fWithMonitorPorts) { 00138 jack_log("Create monitor port "); 00139 snprintf(name, sizeof(name) - 1, "%s:monitor_%u", fClientControl.fName, i + 1); 00140 if ((port_index = fGraphManager->AllocatePort(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize)) == NO_PORT) { 00141 jack_error("Cannot register monitor port for %s", name); 00142 return -1; 00143 } else { 00144 port = fGraphManager->GetPort(port_index); 00145 port->SetAlias(alias); 00146 port->SetLatency(fEngineControl->fBufferSize); 00147 fMonitorPortList[i] = port_index; 00148 } 00149 } 00150 } 00151 00152 return 0; 00153 } 00154 00155 int JackAudioDriver::Detach() 00156 { 00157 int i; 00158 jack_log("JackAudioDriver::Detach"); 00159 00160 for (i = 0; i < fCaptureChannels; i++) { 00161 fGraphManager->ReleasePort(fClientControl.fRefNum, fCapturePortList[i]); 00162 } 00163 00164 for (i = 0; i < fPlaybackChannels; i++) { 00165 fGraphManager->ReleasePort(fClientControl.fRefNum, fPlaybackPortList[i]); 00166 if (fWithMonitorPorts) 00167 fGraphManager->ReleasePort(fClientControl.fRefNum, fMonitorPortList[i]); 00168 } 00169 00170 return 0; 00171 } 00172 00173 int JackAudioDriver::Write() 00174 { 00175 for (int i = 0; i < fPlaybackChannels; i++) { 00176 if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) { 00177 float* buffer = GetOutputBuffer(i); 00178 int size = sizeof(float) * fEngineControl->fBufferSize; 00179 // Monitor ports 00180 if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) 00181 memcpy(GetMonitorBuffer(i), buffer, size); 00182 } 00183 } 00184 return 0; 00185 } 00186 00187 int JackAudioDriver::ProcessNull() 00188 { 00189 // Keep begin cycle time 00190 JackDriver::CycleTakeBeginTime(); 00191 00192 if (fEngineControl->fSyncMode) { 00193 ProcessGraphSync(); 00194 } else { 00195 ProcessGraphAsync(); 00196 } 00197 00198 // Keep end cycle time 00199 JackDriver::CycleTakeEndTime(); 00200 WaitUntilNextCycle(); 00201 return 0; 00202 } 00203 00204 int JackAudioDriver::Process() 00205 { 00206 return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync(); 00207 } 00208 00209 /* 00210 The driver ASYNC mode: output buffers computed at the *previous cycle* are used, the server does not 00211 synchronize to the end of client graph execution. 00212 */ 00213 00214 int JackAudioDriver::ProcessAsync() 00215 { 00216 // Read input buffers for the current cycle 00217 if (Read() < 0) { 00218 jack_error("JackAudioDriver::ProcessAsync: read error, skip cycle"); 00219 return 0; // Skip cycle, but continue processing... 00220 } 00221 00222 // Write output buffers from the previous cycle 00223 if (Write() < 0) { 00224 jack_error("JackAudioDriver::ProcessAsync: write error, skip cycle"); 00225 return 0; // Skip cycle, but continue processing... 00226 } 00227 00228 if (fIsMaster) { 00229 ProcessGraphAsync(); 00230 } else { 00231 fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); 00232 } 00233 00234 // Keep end cycle time 00235 JackDriver::CycleTakeEndTime(); 00236 return 0; 00237 } 00238 00239 /* 00240 The driver SYNC mode: the server does synchronize to the end of client graph execution, 00241 output buffers computed at the *current cycle* are used. 00242 */ 00243 00244 int JackAudioDriver::ProcessSync() 00245 { 00246 // Read input buffers for the current cycle 00247 if (Read() < 0) { 00248 jack_error("JackAudioDriver::ProcessSync: read error, skip cycle"); 00249 return 0; // Skip cycle, but continue processing... 00250 } 00251 00252 if (fIsMaster) { 00253 ProcessGraphSync(); 00254 } else { 00255 fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); 00256 } 00257 00258 // Write output buffers for the current cycle 00259 if (Write() < 0) { 00260 jack_error("JackAudioDriver::ProcessSync: write error, skip cycle"); 00261 return 0; // Skip cycle, but continue processing... 00262 } 00263 00264 // Keep end cycle time 00265 JackDriver::CycleTakeEndTime(); 00266 return 0; 00267 } 00268 00269 void JackAudioDriver::ProcessGraphAsync() 00270 { 00271 // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle 00272 if (!fEngine->Process(fBeginDateUst, fEndDateUst)) 00273 jack_error("JackAudioDriver::ProcessAsync Process error"); 00274 fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); 00275 if (ProcessSlaves() < 0) 00276 jack_error("JackAudioDriver::ProcessAsync ProcessSlaves error"); 00277 } 00278 00279 void JackAudioDriver::ProcessGraphSync() 00280 { 00281 // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle 00282 if (fEngine->Process(fBeginDateUst, fEndDateUst)) { 00283 fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable); 00284 if (ProcessSlaves() < 0) 00285 jack_error("JackAudioDriver::ProcessSync ProcessSlaves error, engine may now behave abnormally!!"); 00286 if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0) 00287 jack_error("JackAudioDriver::ProcessSync SuspendRefNum error, engine may now behave abnormally!!"); 00288 } else { // Graph not finished: do not activate it 00289 jack_error("JackAudioDriver::ProcessSync: error"); 00290 } 00291 } 00292 00293 void JackAudioDriver::WaitUntilNextCycle() 00294 { 00295 int wait_time_usec = (int((float(fEngineControl->fBufferSize) / (float(fEngineControl->fSampleRate))) * 1000000.0f)); 00296 wait_time_usec = int(wait_time_usec - (GetMicroSeconds() - fBeginDateUst)); 00297 if (wait_time_usec > 0) 00298 JackSleep(wait_time_usec); 00299 } 00300 00301 jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) 00302 { 00303 assert(fCapturePortList[port_index]); 00304 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize); 00305 } 00306 00307 jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index) 00308 { 00309 assert(fPlaybackPortList[port_index]); 00310 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize); 00311 } 00312 00313 jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) 00314 { 00315 assert(fPlaybackPortList[port_index]); 00316 return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize); 00317 } 00318 00319 } // end of namespace