Jack2  1.9.10
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 
50  fEngineControl->UpdateTimeOut();
51  UpdateLatencies();
52 
53  // Redirected on slaves drivers...
54  return JackDriver::SetBufferSize(buffer_size);
55 }
56 
57 int JackAudioDriver::SetSampleRate(jack_nframes_t sample_rate)
58 {
59  fEngineControl->fSampleRate = sample_rate;
60  fEngineControl->UpdateTimeOut();
61 
62  // Redirected on slaves drivers...
63  return JackDriver::SetSampleRate(sample_rate);
64 }
65 
66 int JackAudioDriver::Open(jack_nframes_t buffer_size,
67  jack_nframes_t samplerate,
68  bool capturing,
69  bool playing,
70  int inchannels,
71  int outchannels,
72  bool monitor,
73  const char* capture_driver_name,
74  const char* playback_driver_name,
75  jack_nframes_t capture_latency,
76  jack_nframes_t playback_latency)
77 {
78  fCaptureChannels = inchannels;
79  fPlaybackChannels = outchannels;
80  fWithMonitorPorts = monitor;
81  memset(fCapturePortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
82  memset(fPlaybackPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
83  memset(fMonitorPortList, 0, sizeof(jack_port_id_t) * DRIVER_PORT_NUM);
84  return JackDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels,
85  monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
86 }
87 
88 void JackAudioDriver::UpdateLatencies()
89 {
90  jack_latency_range_t input_range;
91  jack_latency_range_t output_range;
92  jack_latency_range_t monitor_range;
93 
94  for (int i = 0; i < fCaptureChannels; i++) {
95  input_range.max = input_range.min = fEngineControl->fBufferSize + fCaptureLatency;
96  fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range);
97  }
98 
99  for (int i = 0; i < fPlaybackChannels; i++) {
100  output_range.max = output_range.min = fPlaybackLatency;
101  if (fEngineControl->fSyncMode) {
102  output_range.max = output_range.min += fEngineControl->fBufferSize;
103  } else {
104  output_range.max = output_range.min += fEngineControl->fBufferSize * 2;
105  }
106  fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range);
107  if (fWithMonitorPorts) {
108  monitor_range.min = monitor_range.max = fEngineControl->fBufferSize;
109  fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range);
110  }
111  }
112 }
113 
114 int JackAudioDriver::Attach()
115 {
116  JackPort* port;
117  jack_port_id_t port_index;
118  char name[REAL_JACK_PORT_NAME_SIZE];
119  char alias[REAL_JACK_PORT_NAME_SIZE];
120  int i;
121 
122  jack_log("JackAudioDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
123 
124  for (i = 0; i < fCaptureChannels; i++) {
125  snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1);
126  snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1);
127  if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
128  jack_error("driver: cannot register port for %s", name);
129  return -1;
130  }
131  port = fGraphManager->GetPort(port_index);
132  port->SetAlias(alias);
133  fCapturePortList[i] = port_index;
134  jack_log("JackAudioDriver::Attach fCapturePortList[i] port_index = %ld", port_index);
135  }
136 
137  for (i = 0; i < fPlaybackChannels; i++) {
138  snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1);
139  snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1);
140  if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
141  jack_error("driver: cannot register port for %s", name);
142  return -1;
143  }
144  port = fGraphManager->GetPort(port_index);
145  port->SetAlias(alias);
146  fPlaybackPortList[i] = port_index;
147  jack_log("JackAudioDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index);
148 
149  // Monitor ports
150  if (fWithMonitorPorts) {
151  jack_log("Create monitor port");
152  snprintf(name, sizeof(name), "%s:monitor_%u", fClientControl.fName, i + 1);
153  if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, fEngineControl->fBufferSize, &port_index) < 0) {
154  jack_error("Cannot register monitor port for %s", name);
155  return -1;
156  } else {
157  fMonitorPortList[i] = port_index;
158  }
159  }
160  }
161 
162  UpdateLatencies();
163  return 0;
164 }
165 
166 int JackAudioDriver::Detach()
167 {
168  int i;
169  jack_log("JackAudioDriver::Detach");
170 
171  for (i = 0; i < fCaptureChannels; i++) {
172  fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]);
173  }
174 
175  for (i = 0; i < fPlaybackChannels; i++) {
176  fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]);
177  if (fWithMonitorPorts) {
178  fEngine->PortUnRegister(fClientControl.fRefNum, fMonitorPortList[i]);
179  }
180  }
181 
182  return 0;
183 }
184 
185 int JackAudioDriver::Write()
186 {
187  for (int i = 0; i < fPlaybackChannels; i++) {
188  if (fGraphManager->GetConnectionsNum(fPlaybackPortList[i]) > 0) {
189  jack_default_audio_sample_t* buffer = GetOutputBuffer(i);
190  int size = sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize;
191  // Monitor ports
192  if (fWithMonitorPorts && fGraphManager->GetConnectionsNum(fMonitorPortList[i]) > 0) {
193  memcpy(GetMonitorBuffer(i), buffer, size);
194  }
195  }
196  }
197  return 0;
198 }
199 
200 int JackAudioDriver::Process()
201 {
202  return (fEngineControl->fSyncMode) ? ProcessSync() : ProcessAsync();
203 }
204 
205 /*
206 The driver "asynchronous" mode: output buffers computed at the *previous cycle* are used, the server does not
207 synchronize to the end of client graph execution.
208 */
209 
210 int JackAudioDriver::ProcessAsync()
211 {
212  // Read input buffers for the current cycle
213  if (Read() < 0) {
214  jack_error("JackAudioDriver::ProcessAsync: read error, stopping...");
215  return -1;
216  }
217 
218  // Write output buffers from the previous cycle
219  if (Write() < 0) {
220  jack_error("JackAudioDriver::ProcessAsync: write error, stopping...");
221  return -1;
222  }
223 
224  // Process graph
225  ProcessGraphAsync();
226 
227  // Keep end cycle time
228  JackDriver::CycleTakeEndTime();
229  return 0;
230 }
231 
232 void JackAudioDriver::ProcessGraphAsync()
233 {
234  // Process graph
235  if (fIsMaster) {
236  ProcessGraphAsyncMaster();
237  } else {
238  ProcessGraphAsyncSlave();
239  }
240 }
241 
242 /*
243 Used when the driver works in master mode.
244 */
245 
246 void JackAudioDriver::ProcessGraphAsyncMaster()
247 {
248  // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle
249  if (!fEngine->Process(fBeginDateUst, fEndDateUst)) {
250  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: Process error");
251  }
252 
253  if (ResumeRefNum() < 0) {
254  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ResumeRefNum error");
255  }
256 
257  if (ProcessReadSlaves() < 0) {
258  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessReadSlaves error");
259  }
260 
261  if (ProcessWriteSlaves() < 0) {
262  jack_error("JackAudioDriver::ProcessGraphAsyncMaster: ProcessWriteSlaves error");
263  }
264 
265  // Does not wait on graph execution end
266 }
267 
268 /*
269 Used when the driver works in slave mode.
270 */
271 
272 void JackAudioDriver::ProcessGraphAsyncSlave()
273 {
274  if (ResumeRefNum() < 0) {
275  jack_error("JackAudioDriver::ProcessGraphAsyncSlave: ResumeRefNum error");
276  }
277 }
278 
279 /*
280 The driver "synchronous" mode: the server does synchronize to the end of client graph execution,
281 if graph process succeed, output buffers computed at the *current cycle* are used.
282 */
283 
284 int JackAudioDriver::ProcessSync()
285 {
286  // Read input buffers for the current cycle
287  if (Read() < 0) {
288  jack_error("JackAudioDriver::ProcessSync: read error, stopping...");
289  return -1;
290  }
291 
292  // Process graph
293  ProcessGraphSync();
294 
295  // Write output buffers from the current cycle
296  if (Write() < 0) {
297  jack_error("JackAudioDriver::ProcessSync: write error, stopping...");
298  return -1;
299  }
300 
301  // Keep end cycle time
302  JackDriver::CycleTakeEndTime();
303  return 0;
304 }
305 
306 void JackAudioDriver::ProcessGraphSync()
307 {
308  // Process graph
309  if (fIsMaster) {
310  ProcessGraphSyncMaster();
311  } else {
312  ProcessGraphSyncSlave();
313  }
314 }
315 
316 /*
317 Used when the driver works in master mode.
318 */
319 
320 void JackAudioDriver::ProcessGraphSyncMaster()
321 {
322  // fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle
323  if (fEngine->Process(fBeginDateUst, fEndDateUst)) {
324 
325  if (ResumeRefNum() < 0) {
326  jack_error("JackAudioDriver::ProcessGraphSyncMaster: ResumeRefNum error");
327  }
328 
329  if (ProcessReadSlaves() < 0) {
330  jack_error("JackAudioDriver::ProcessGraphSync: ProcessReadSlaves error, engine may now behave abnormally!!");
331  }
332 
333  if (ProcessWriteSlaves() < 0) {
334  jack_error("JackAudioDriver::ProcessGraphSync: ProcessWriteSlaves error, engine may now behave abnormally!!");
335  }
336 
337  // Waits for graph execution end
338  if (SuspendRefNum() < 0) {
339  jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!");
340  }
341 
342  } else { // Graph not finished: do not activate it
343  jack_error("JackAudioDriver::ProcessGraphSync: Process error");
344  }
345 }
346 
347 /*
348 Used when the driver works in slave mode.
349 */
350 
351 void JackAudioDriver::ProcessGraphSyncSlave()
352 {
353  if (ResumeRefNum() < 0) {
354  jack_error("JackAudioDriver::ProcessGraphSyncSlave: ResumeRefNum error");
355  }
356 }
357 
358 jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index)
359 {
360  return fCapturePortList[port_index]
361  ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize)
362  : NULL;
363 }
364 
365 jack_default_audio_sample_t* JackAudioDriver::GetOutputBuffer(int port_index)
366 {
367  return fPlaybackPortList[port_index]
368  ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize)
369  : NULL;
370 }
371 
372 jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index)
373 {
374  return fPlaybackPortList[port_index]
375  ? (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize)
376  : NULL;
377 }
378 
379 int JackAudioDriver::ClientNotify(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
380 {
381  switch (notify) {
382 
383  case kLatencyCallback:
384  HandleLatencyCallback(value1);
385  break;
386 
387  default:
388  JackDriver::ClientNotify(refnum, name, notify, sync, message, value1, value2);
389  break;
390  }
391 
392  return 0;
393 }
394 
395 void JackAudioDriver::HandleLatencyCallback(int status)
396 {
397  jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency;
398 
399  for (int i = 0; i < fCaptureChannels; i++) {
400  if (mode == JackPlaybackLatency) {
401  fGraphManager->RecalculateLatency(fCapturePortList[i], mode);
402  }
403  }
404 
405  for (int i = 0; i < fPlaybackChannels; i++) {
406  if (mode == JackCaptureLatency) {
407  fGraphManager->RecalculateLatency(fPlaybackPortList[i], mode);
408  }
409  }
410 }
411 
412 } // end of namespace
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
jack_nframes_t min
Definition: types.h:270
jack_nframes_t max
Definition: types.h:274
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108