00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00047 fEngineControl->fBufferSize = buffer_size;
00048 fGraphManager->SetBufferSize(buffer_size);
00049 fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize);
00050 if (!fEngineControl->fTimeOut) {
00051 fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
00052 }
00053
00054 UpdateLatencies();
00055
00056
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);
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
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
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
00231
00232
00233
00234 int JackAudioDriver::ProcessAsync()
00235 {
00236
00237 if (Read() < 0) {
00238 jack_error("JackAudioDriver::ProcessAsync: read error, stopping...");
00239 return -1;
00240 }
00241
00242
00243 if (Write() < 0) {
00244 jack_error("JackAudioDriver::ProcessAsync: write error, stopping...");
00245 return -1;
00246 }
00247
00248
00249 ProcessGraphAsync();
00250
00251
00252 JackDriver::CycleTakeEndTime();
00253 return 0;
00254 }
00255
00256 void JackAudioDriver::ProcessGraphAsync()
00257 {
00258
00259 if (fIsMaster) {
00260 ProcessGraphAsyncMaster();
00261 } else {
00262 ProcessGraphAsyncSlave();
00263 }
00264 }
00265
00266 void JackAudioDriver::ProcessGraphAsyncMaster()
00267 {
00268
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
00286 }
00287
00288 void JackAudioDriver::ProcessGraphAsyncSlave()
00289 {
00290 if (ResumeRefNum() < 0) {
00291 jack_error("JackAudioDriver::ProcessGraphAsyncSlave: ResumeRefNum error");
00292 }
00293 }
00294
00295
00296
00297
00298
00299
00300 int JackAudioDriver::ProcessSync()
00301 {
00302
00303 if (Read() < 0) {
00304 jack_error("JackAudioDriver::ProcessSync: read error, stopping...");
00305 return -1;
00306 }
00307
00308
00309 ProcessGraphSync();
00310
00311
00312 if (Write() < 0) {
00313 jack_error("JackAudioDriver::ProcessSync: write error, stopping...");
00314 return -1;
00315 }
00316
00317
00318 JackDriver::CycleTakeEndTime();
00319 return 0;
00320 }
00321
00322 void JackAudioDriver::ProcessGraphSync()
00323 {
00324
00325 if (fIsMaster) {
00326 ProcessGraphSyncMaster();
00327 } else {
00328 ProcessGraphSyncSlave();
00329 }
00330 }
00331
00332 void JackAudioDriver::ProcessGraphSyncMaster()
00333 {
00334
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
00350 if (SuspendRefNum() < 0) {
00351 jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!");
00352 }
00353
00354 } else {
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 }