Jack2  1.9.8
JackAudioDriver.cpp
1 /*
2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2008 Grame.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 (at your option) any later version.
12 
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19 */
20 
21 #include "JackSystemDeps.h"
22 #include "JackAudioDriver.h"
23 #include "JackTime.h"
24 #include "JackError.h"
25 #include "JackEngineControl.h"
26 #include "JackPort.h"
27 #include "JackGraphManager.h"
28 #include "JackLockedEngine.h"
29 #include "JackException.h"
30 #include <assert.h>
31 
32 using namespace std;
33 
34 namespace Jack
35 {
36 
37 JackAudioDriver::JackAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
38  : JackDriver(name, alias, engine, table)
39 {}
40 
41 JackAudioDriver::~JackAudioDriver()
42 {}
43 
44 int JackAudioDriver::SetBufferSize(jack_nframes_t buffer_size)
45 {
46  // Update engine and graph manager state
47  fEngineControl->fBufferSize = buffer_size;
48  fGraphManager->SetBufferSize(buffer_size);
49  fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec
50  if (!fEngineControl->fTimeOut) {
51  fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
52  }
53 
54  UpdateLatencies();
55 
56  // Redirect on slaves drivers...
57  return JackDriver::SetBufferSize(buffer_size);
58 }
59 
60 int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate)
61 {
62  fEngineControl->fSampleRate = sample_rate;
63  fEngineControl->fPeriodUsecs = jack_time_t(1000000.f / fEngineControl->fSampleRate * fEngineControl->fBufferSize); // in microsec
64  if (!fEngineControl->fTimeOut) {
65  fEngineControl->fTimeOutUsecs = jack_time_t(2.f * fEngineControl->fPeriodUsecs);
66  }
67 
68  return JackDriver::SetSampleRate(sample_rate);
69 }
70 
71 int JackAudioDriver::Open(jack_nframes_t buffer_size,
72  jack_nframes_t samplerate,
73  bool capturing,
74  bool playing,
75  int inchannels,
76  int outchannels,
77  bool monitor,
78  const char* capture_driver_name,
79  const char* playback_driver_name,
80  jack_nframes_t capture_latency,
81  jack_nframes_t playback_latency)
82 {
83  fCaptureChannels = inchannels;
84  fPlaybackChannels = outchannels;
85  fWithMonitorPorts = monitor;
86  memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
87  memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
88  memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
89  return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels,
90  monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
91 }
92 
93 int JackAudioDriver::Open(bool capturing,
94  bool playing,
95  int inchannels,
96  int outchannels,
97  bool monitor,
98  const char* capture_driver_name,
99  const char* playback_driver_name,
100  jack_nframes_t capture_latency,
101  jack_nframes_t playback_latency)
102 {
103  fCaptureChannels = inchannels;
104  fPlaybackChannels = outchannels;
105  fWithMonitorPorts = monitor;
106  memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
107  memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
108  memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
109  return JackDriver::Open(capturing, playing, inchannels, outchannels,
110  monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
111 }
112 
113 void JackAudioDriver::UpdateLatencies()
114 {
115  jack_latency_range_t input_range;
116  jack_latency_range_t output_range;
117  jack_latency_range_t monitor_range;
118 
119  for (int i = 0; i < fCaptureChannels; i++) {
120  input_range.max = input_range.min = fEngineControl->fBufferSize + fCaptureLatency;
121  fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range);
122  }
123 
124  for (int i = 0; i < fPlaybackChannels; i++) {
125  output_range.max = output_range.min = fPlaybackLatency;
126  if (fEngineControl->fSyncMode) {
127  output_range.max = output_range.min += fEngineControl->fBufferSize;
128  } else {
129  output_range.max = output_range.min += fEngineControl->fBufferSize * 2;
130  }
131  fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range);
132  if (fWithMonitorPorts) {
133  monitor_range.min = monitor_range.max = fEngineControl->fBufferSize;
134  fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range);
135  }
136  }
137 }
138 
139 int JackAudioDriver::Attach()
140 {
141  JackPort* port;
142  jack_port_id_t port_index;
143  char name[REAL_JACK_PORT_NAME_SIZE];
144  char alias[REAL_JACK_PORT_NAME_SIZE];
145  int i;
146 
147  jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
148 
149  for (i = 0; i < fCaptureChannels; i++) {
150  snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1);
151  snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1);
152  if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
153  jack_error("driver: cannot register port for %s", name);
154  return -1;
155  }
156  port = fGraphManager->GetPort(port_index);
157  port->SetAlias(alias);
158  fCapturePortList[i] = port_index;
159  jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index);
160  }
161 
162  for (i = 0; i < fPlaybackChannels; i++) {
163  snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1);
164  snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1);
165  if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
166  jack_error("driver: cannot register port for %s", name);
167  return -1;
168  }
169  port = fGraphManager->GetPort(port_index);
170  port->SetAlias(alias);
171  fPlaybackPortList[i] = port_index;
172  jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index);
173 
174  // Monitor ports
175  if (fWithMonitorPorts) {
176  jack_log("Create monitor port");
177  snprintf(name, sizeof(name), "%s:monitor_%u", fClientControl.fName, i + 1);
178  if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize, &port_index) < 0) {
179  jack_error("Cannot register monitor port for %s", name);
180  return -1;
181  } else {
182  fMonitorPortList[i] = port_index;
183  }
184  }
185  }
186 
187  UpdateLatencies();
188  return 0;
189 }
190 
191 int JackAudioDriver::Detach()
192 {
193  int i;
194  jack_log("JackAudioDriver::Detach");
195 
196  for (i = 0; i < fCaptureChannels; i++) {
197  fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]);
198  }
199 
200  for (i = 0; i < fPlaybackChannels; i++) {
201  fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]);
202  if (fWithMonitorPorts) {
203  fEngine->PortUnRegister(fClientControl.fRefNum, fMonitorPortList[i]);
204  }
205  }
206 
207  return 0;
208 }
209 
210 int JackAudioDriver::Write()
211 {
212  for (int i = 0; i < fPlaybackChannels; i++) {
213  if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) {
214  jack_default_audio_sample_t* buffer = GetOutputBuffer(i);
215  int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize;
216  // Monitor ports
217  if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0)
218  memcpy(GetMonitorBuffer(i), buffer, size);
219  }
220  }
221  return 0;
222 }
223 
224 int JackAudioDriver::Process()
225 {
226  return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
227 }
228 
229 /*
230 The driver ASYNC mode: output buffers computed at the *previous cycle* are used, the server does not
231 synchronize to the end of client graph execution.
232 */
233 
234 int JackAudioDriver::ProcessAsync()
235 {
236  // Read input buffers for the current cycle
237  if (Read() < 0) {
238  jack_error("JackAudioDriver::ProcessAsync: read error, stopping...");
239  return -1;
240  }
241 
242  // Write output buffers from the previous cycle
243  if (Write() < 0) {
244  jack_error("JackAudioDriver::ProcessAsync: write error, stopping...");
245  return -1;
246  }
247 
248  // Process graph
249  ProcessGraphAsync();
250 
251  // Keep end cycle time
252  JackDriver::CycleTakeEndTime();
253  return 0;
254 }
255 
256 void JackAudioDriver::ProcessGraphAsync()
257 {
258  // Process graph
259  if (fIsMaster) {
260  ProcessGraphAsyncMaster();
261  } else {
262  ProcessGraphAsyncSlave();
263  }
264 }
265 
266 void JackAudioDriver::ProcessGraphAsyncMaster()
267 {
268  // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle
269  if (!fEngine->Process(fBeginDateUst, fEndDateUst)) {
270  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: Process error");
271  }
272 
273  if (ResumeRefNum() < 0) {
274  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ResumeRefNum error");
275  }
276 
277  if (ProcessReadSlaves() < 0) {
278  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessReadSlaves error");
279  }
280 
281  if (ProcessWriteSlaves() < 0) {
282  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessWriteSlaves error");
283  }
284 
285  // Does not wait on graph execution end
286 }
287 
288 void JackAudioDriver::ProcessGraphAsyncSlave()
289 {
290  if (ResumeRefNum() < 0) {
291  jack_error("JackAudioDriver::ProcessGraphAsyncSlave: ResumeRefNum error");
292  }
293 }
294 
295 /*
296 The driver SYNC mode: the server does synchronize to the end of client graph execution,
297 if graph process succeed, output buffers computed at the *current cycle* are used.
298 */
299 
300 int JackAudioDriver::ProcessSync()
301 {
302  // Read input buffers for the current cycle
303  if (Read() < 0) {
304  jack_error("JackAudioDriver::ProcessSync: read error, stopping...");
305  return -1;
306  }
307 
308  // Process graph
309  ProcessGraphSync();
310 
311  // Write output buffers from the current cycle
312  if (Write() < 0) {
313  jack_error("JackAudioDriver::ProcessSync: write error, stopping...");
314  return -1;
315  }
316 
317  // Keep end cycle time
318  JackDriver::CycleTakeEndTime();
319  return 0;
320 }
321 
322 void JackAudioDriver::ProcessGraphSync()
323 {
324  // Process graph
325  if (fIsMaster) {
326  ProcessGraphSyncMaster();
327  } else {
328  ProcessGraphSyncSlave();
329  }
330 }
331 
332 void JackAudioDriver::ProcessGraphSyncMaster()
333 {
334  // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle
335  if (fEngine->Process(fBeginDateUst, fEndDateUst)) {
336 
337  if (ResumeRefNum() < 0) {
338  jack_error("JackAudioDriver::ProcessGraphSyncMaster: ResumeRefNum error");
339  }
340 
341  if (ProcessReadSlaves() < 0) {
342  jack_error("JackAudioDriver::ProcessGraphSync: ProcessReadSlaves error, engine may now behave abnormally!!");
343  }
344 
345  if (ProcessWriteSlaves() < 0) {
346  jack_error("JackAudioDriver::ProcessGraphSync: ProcessWriteSlaves error, engine may now behave abnormally!!");
347  }
348 
349  // Waits for graph execution end
350  if (SuspendRefNum() < 0) {
351  jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!");
352  }
353 
354  } else { // Graph not finished: do not activate it
355  jack_error("JackAudioDriver::ProcessGraphSync: Process error");
356  }
357 }
358 
359 void JackAudioDriver::ProcessGraphSyncSlave()
360 {
361  if (ResumeRefNum() < 0) {
362  jack_error("JackAudioDriver::ProcessGraphSyncSlave: ResumeRefNum error");
363  }
364 }
365 
366 jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index)
367 {
368  return fCapturePortList[port_index]
369  ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize)
370  : NULL;
371 }
372 
373 jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index)
374 {
375  return fPlaybackPortList[port_index]
376  ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize)
377  : NULL;
378 }
379 
380 jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index)
381 {
382  return fPlaybackPortList[port_index]
383  ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize)
384  : NULL;
385 }
386 
387 int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
388 {
389  switch (notify) {
390 
391  case kLatencyCallback:
392  HandleLatencyCallback(value1);
393  break;
394 
395  default:
396  JackDriver::ClientNotify(refnum, name, notify, sync, message, value1, value2);
397  break;
398  }
399 
400  return 0;
401 }
402 
403 void JackAudioDriver::HandleLatencyCallback(int status)
404 {
405  jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency;
406 
407  for (int i = 0; i < fCaptureChannels; i++) {
408  if (mode == JackPlaybackLatency) {
409  fGraphManager->RecalculateLatency(fCapturePortList[i], mode);
410  }
411  }
412 
413  for (int i = 0; i < fPlaybackChannels; i++) {
414  if (mode == JackCaptureLatency) {
415  fGraphManager->RecalculateLatency(fPlaybackPortList[i], mode);
416  }
417  }
418 }
419 
420 } // end of namespace