20 #include "JackDriverLoader.h"
21 #include "driver_interface.h"
22 #include "JackPortAudioDriver.h"
23 #include "JackEngineControl.h"
24 #include "JackGraphManager.h"
25 #include "JackError.h"
27 #include "JackTools.h"
28 #include "JackCompilerDeps.h"
37 int JackPortAudioDriver::Render(
const void* inputBuffer,
void* outputBuffer,
38 unsigned long framesPerBuffer,
43 JackPortAudioDriver* driver = (JackPortAudioDriver*)userData;
44 driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer;
45 driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer;
47 MMCSSAcquireRealTime(GetCurrentThread());
51 jack_error(
"JackPortAudioDriver::Render paOutputUnderflow");
53 jack_error(
"JackPortAudioDriver::Render paInputUnderflow");
55 jack_error(
"JackPortAudioDriver::Render paOutputOverflow");
57 jack_error(
"JackPortAudioDriver::Render paInputOverflow");
59 jack_error(
"JackPortAudioDriver::Render paOutputUnderflow");
61 if (statusFlags != paPrimingOutput) {
62 jack_time_t cur_time = GetMicroSeconds();
63 driver->NotifyXRun(cur_time,
float(cur_time - driver->fBeginDateUst));
68 set_threaded_log_function();
69 driver->CycleTakeBeginTime();
70 return (driver->Process() == 0) ? paContinue : paAbort;
73 int JackPortAudioDriver::Read()
75 for (
int i = 0; i < fCaptureChannels; i++) {
76 memcpy(GetInputBuffer(i), fInputBuffer[i],
sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize);
81 int JackPortAudioDriver::Write()
83 for (
int i = 0; i < fPlaybackChannels; i++) {
84 memcpy(fOutputBuffer[i], GetOutputBuffer(i),
sizeof(jack_default_audio_sample_t) * fEngineControl->fBufferSize);
89 PaError JackPortAudioDriver::OpenStream(jack_nframes_t buffer_size)
95 inputParameters.
device = fInputDevice;
103 outputParameters.
device = fOutputDevice;
112 (fInputDevice ==
paNoDevice) ? 0 : &inputParameters,
113 (fOutputDevice ==
paNoDevice) ? 0 : &outputParameters,
114 fEngineControl->fSampleRate,
121 void JackPortAudioDriver::UpdateLatencies()
130 for (
int i = 0; i < fCaptureChannels; i++) {
131 input_range.
max = input_range.
min = fEngineControl->fBufferSize + (info->
inputLatency * fEngineControl->fSampleRate) + fCaptureLatency;
132 fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &input_range);
135 for (
int i = 0; i < fPlaybackChannels; i++) {
136 output_range.
max = output_range.
min = (info->
outputLatency * fEngineControl->fSampleRate) + fPlaybackLatency;
137 if (fEngineControl->fSyncMode) {
138 output_range.
max = output_range.
min += fEngineControl->fBufferSize;
140 output_range.
max = output_range.
min += fEngineControl->fBufferSize * 2;
142 fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &output_range);
143 if (fWithMonitorPorts) {
144 monitor_range.
min = monitor_range.
max = fEngineControl->fBufferSize;
145 fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &monitor_range);
150 int JackPortAudioDriver::Open(jack_nframes_t buffer_size,
151 jack_nframes_t samplerate,
157 const char* capture_driver_uid,
158 const char* playback_driver_uid,
159 jack_nframes_t capture_latency,
160 jack_nframes_t playback_latency)
166 fCaptureLatency = capture_latency;
167 fPlaybackLatency = playback_latency;
169 jack_log(
"JackPortAudioDriver::Open nframes = %ld in = %ld out = %ld capture name = %s playback name = %s samplerate = %ld",
170 buffer_size, inchannels, outchannels, capture_driver_uid, playback_driver_uid, samplerate);
173 if (JackAudioDriver::Open(buffer_size, samplerate, capturing, playing, inchannels, outchannels, monitor,
174 capture_driver_uid, playback_driver_uid, capture_latency, playback_latency) != 0) {
180 if (fPaDevices->GetInputDeviceFromName(capture_driver_uid, fInputDevice, in_max) < 0) {
185 if (fPaDevices->GetOutputDeviceFromName(playback_driver_uid, fOutputDevice, out_max) < 0) {
190 jack_log(
"JackPortAudioDriver::Open fInputDevice = %d, fOutputDevice %d", fInputDevice, fOutputDevice);
193 if (inchannels == 0) {
194 jack_log(
"JackPortAudioDriver::Open setup max in channels = %ld", in_max);
197 if (outchannels == 0) {
198 jack_log(
"JackPortAudioDriver::Open setup max out channels = %ld", out_max);
199 outchannels = out_max;
203 if (inchannels > in_max) {
204 jack_error(
"This device has only %d available input channels.", in_max);
207 if (outchannels > out_max) {
208 jack_error(
"This device has only %d available output channels.", out_max);
209 outchannels = out_max;
213 fCaptureChannels = inchannels;
214 fPlaybackChannels = outchannels;
216 err = OpenStream(buffer_size);
217 if (err != paNoError) {
223 fEngineControl->fPeriod = fEngineControl->fPeriodUsecs * 1000;
224 fEngineControl->fComputation = JackTools::ComputationMicroSec(fEngineControl->fBufferSize) * 1000;
225 fEngineControl->fConstraint = fEngineControl->fPeriodUsecs * 1000;
228 assert(strlen(capture_driver_uid) < JACK_CLIENT_NAME_SIZE);
229 assert(strlen(playback_driver_uid) < JACK_CLIENT_NAME_SIZE);
231 strcpy(fCaptureDriverName, capture_driver_uid);
232 strcpy(fPlaybackDriverName, playback_driver_uid);
237 JackAudioDriver::Close();
238 jack_error(
"Can't open default PortAudio device");
242 int JackPortAudioDriver::Close()
245 int res = JackAudioDriver::Close();
246 jack_log(
"JackPortAudioDriver::Close");
251 int JackPortAudioDriver::Start()
253 jack_log(
"JackPortAudioDriver::Start");
254 if (JackAudioDriver::Start() >= 0) {
256 if (err == paNoError) {
259 JackAudioDriver::Stop();
264 int JackPortAudioDriver::Stop()
266 jack_log(
"JackPortAudioDriver::Stop");
268 int res = (err == paNoError) ? 0 : -1;
269 if (JackAudioDriver::Stop() < 0) {
275 int JackPortAudioDriver::SetBufferSize(jack_nframes_t buffer_size)
284 err = OpenStream(buffer_size);
285 if (err != paNoError) {
289 JackAudioDriver::SetBufferSize(buffer_size);
301 #include "JackCompilerDeps.h"
309 desc = jack_driver_descriptor_construct(
"portaudio", JackDriverMaster,
"PortAudio API based audio backend", &filler);
312 jack_driver_descriptor_add_parameter(desc, &filler,
"channels",
'c', JackDriverParamUInt, &value, NULL,
"Maximum number of channels", NULL);
313 jack_driver_descriptor_add_parameter(desc, &filler,
"inchannels",
'i', JackDriverParamUInt, &value, NULL,
"Maximum number of input channels", NULL);
314 jack_driver_descriptor_add_parameter(desc, &filler,
"outchannels",
'o', JackDriverParamUInt, &value, NULL,
"Maximum number of output channels", NULL);
316 strcpy(value.str,
"will take default PortAudio input device");
317 jack_driver_descriptor_add_parameter(desc, &filler,
"capture",
'C', JackDriverParamString, &value, NULL,
"Provide capture ports. Optionally set PortAudio device name", NULL);
319 strcpy(value.str,
"will take default PortAudio output device");
320 jack_driver_descriptor_add_parameter(desc, &filler,
"playback",
'P', JackDriverParamString, &value, NULL,
"Provide playback ports. Optionally set PortAudio device name", NULL);
323 jack_driver_descriptor_add_parameter(desc, &filler,
"monitor",
'm', JackDriverParamBool, &value, NULL,
"Provide monitor ports for the output", NULL);
326 jack_driver_descriptor_add_parameter(desc, &filler,
"duplex",
'D', JackDriverParamBool, &value, NULL,
"Provide both capture and playback ports", NULL);
329 jack_driver_descriptor_add_parameter(desc, &filler,
"rate",
'r', JackDriverParamUInt, &value, NULL,
"Sample rate", NULL);
332 jack_driver_descriptor_add_parameter(desc, &filler,
"period",
'p', JackDriverParamUInt, &value, NULL,
"Frames per period", NULL);
334 strcpy(value.str,
"will take default PortAudio device name");
335 jack_driver_descriptor_add_parameter(desc, &filler,
"device",
'd', JackDriverParamString, &value, NULL,
"PortAudio device name", NULL);
338 jack_driver_descriptor_add_parameter(desc, &filler,
"input-latency",
'I', JackDriverParamUInt, &value, NULL,
"Extra input latency", NULL);
339 jack_driver_descriptor_add_parameter(desc, &filler,
"output-latency",
'O', JackDriverParamUInt, &value, NULL,
"Extra output latency", NULL);
342 jack_driver_descriptor_add_parameter(desc, &filler,
"list-devices",
'l', JackDriverParamBool, &value, NULL,
"Display available PortAudio devices", NULL);
349 jack_nframes_t srate = 44100;
350 jack_nframes_t frames_per_interrupt = 512;
351 const char* capture_pcm_name =
"";
352 const char* playback_pcm_name =
"";
353 bool capture =
false;
354 bool playback =
false;
357 bool monitor =
false;
360 jack_nframes_t systemic_input_latency = 0;
361 jack_nframes_t systemic_output_latency = 0;
364 for (node = params; node; node = jack_slist_next(node))
368 switch (param->character) {
371 capture_pcm_name = param->value.str;
372 playback_pcm_name = param->value.str;
381 chan_in = chan_out = (int)param->value.ui;
385 chan_in = (
int)param->value.ui;
389 chan_out = (int)param->value.ui;
394 if (strcmp(param->value.str,
"none") != 0) {
395 capture_pcm_name = param->value.str;
401 if (strcmp(param->value.str,
"none") != 0) {
402 playback_pcm_name = param->value.str;
407 monitor = param->value.i;
411 srate = param->value.ui;
415 frames_per_interrupt = (
unsigned int)param->value.ui;
419 systemic_input_latency = param->value.ui;
423 systemic_output_latency = param->value.ui;
427 pa_devices->DisplayDevicesNames();
433 if (!capture && !playback) {
439 if (driver->Open(frames_per_interrupt, srate, capture, playback,
440 chan_in, chan_out, monitor, capture_pcm_name,
441 playback_pcm_name, systemic_input_latency,
442 systemic_output_latency) == 0) {