Jack2 1.9.8

JackAudioDriver.cpp

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