2 Copyright (C) 2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "JackPortAudioAdapter.h"
21 #include "JackError.h"
26 int JackPortAudioAdapter::Render(const void* inputBuffer
,
28 unsigned long framesPerBuffer
,
29 const PaStreamCallbackTimeInfo
* timeInfo
,
30 PaStreamCallbackFlags statusFlags
,
33 static_cast<JackPortAudioAdapter
*>(userData
)->PushAndPull((jack_default_audio_sample_t
**)inputBuffer
, (jack_default_audio_sample_t
**)outputBuffer
, framesPerBuffer
);
37 JackPortAudioAdapter::JackPortAudioAdapter(jack_nframes_t buffer_size
, jack_nframes_t sample_rate
, const JSList
* params
)
38 : JackAudioAdapterInterface(buffer_size
, sample_rate
)
40 jack_log("JackPortAudioAdapter::JackPortAudioAdapter buffer_size = %d, sample_rate = %d", buffer_size
, sample_rate
);
43 const jack_driver_param_t
* param
;
47 fInputDevice
= Pa_GetDefaultInputDevice();
48 fOutputDevice
= Pa_GetDefaultOutputDevice();
50 for (node
= params
; node
; node
= jack_slist_next(node
)) {
51 param
= (const jack_driver_param_t
*) node
->data
;
53 switch (param
->character
)
56 fCaptureChannels
= param
->value
.ui
;
59 fPlaybackChannels
= param
->value
.ui
;
62 if (fPaDevices
.GetInputDeviceFromName(param
->value
.str
, fInputDevice
, in_max
) < 0) {
63 jack_error("Can't use %s, taking default input device", param
->value
.str
);
64 fInputDevice
= Pa_GetDefaultInputDevice();
68 if (fPaDevices
.GetOutputDeviceFromName(param
->value
.str
, fOutputDevice
, out_max
) < 0) {
69 jack_error("Can't use %s, taking default output device", param
->value
.str
);
70 fOutputDevice
= Pa_GetDefaultOutputDevice();
74 SetAdaptedSampleRate(param
->value
.ui
);
77 SetAdaptedBufferSize(param
->value
.ui
);
80 if (fPaDevices
.GetInputDeviceFromName(param
->value
.str
, fInputDevice
, in_max
) < 0)
81 jack_error("Can't use %s, taking default input device", param
->value
.str
);
82 if (fPaDevices
.GetOutputDeviceFromName(param
->value
.str
, fOutputDevice
, out_max
) < 0)
83 jack_error("Can't use %s, taking default output device", param
->value
.str
);
86 fPaDevices
.DisplayDevicesNames();
89 fQuality
= param
->value
.ui
;
92 fRingbufferCurSize
= param
->value
.ui
;
99 if (in_max
== 0 && fInputDevice
!= paNoDevice
)
100 in_max
= fPaDevices
.GetDeviceInfo(fInputDevice
)->maxInputChannels
;
101 if (out_max
== 0 && fOutputDevice
!= paNoDevice
)
102 out_max
= fPaDevices
.GetDeviceInfo(fOutputDevice
)->maxOutputChannels
;
105 if ((fCaptureChannels
== 0) || (fCaptureChannels
> in_max
))
106 fCaptureChannels
= in_max
;
107 if ((fPlaybackChannels
== 0) || (fPlaybackChannels
> out_max
))
108 fPlaybackChannels
= out_max
;
110 //set adapter interface channels
111 SetInputs(fCaptureChannels
);
112 SetOutputs(fPlaybackChannels
);
115 int JackPortAudioAdapter::Open()
118 PaStreamParameters inputParameters
;
119 PaStreamParameters outputParameters
;
121 if (fInputDevice
== paNoDevice
&& fOutputDevice
== paNoDevice
) {
122 jack_error("No input and output device!!");
126 jack_log("JackPortAudioAdapter::Open fInputDevice = %d DeviceName %s", fInputDevice
, fPaDevices
.GetFullName(fInputDevice
).c_str());
127 jack_log("JackPortAudioAdapter::Open fOutputDevice = %d DeviceName %s", fOutputDevice
, fPaDevices
.GetFullName(fOutputDevice
).c_str());
128 jack_log("JackPortAudioAdapter::Open fAdaptedBufferSize = %u fAdaptedSampleRate %u", fAdaptedBufferSize
, fAdaptedSampleRate
);
130 inputParameters
.device
= fInputDevice
;
131 inputParameters
.channelCount
= fCaptureChannels
;
132 inputParameters
.sampleFormat
= paFloat32
| paNonInterleaved
; // 32 bit floating point output
133 inputParameters
.suggestedLatency
= (fInputDevice
!= paNoDevice
) // TODO: check how to setup this on ASIO
134 ? fPaDevices
.GetDeviceInfo(fInputDevice
)->defaultLowInputLatency
136 inputParameters
.hostApiSpecificStreamInfo
= NULL
;
138 outputParameters
.device
= fOutputDevice
;
139 outputParameters
.channelCount
= fPlaybackChannels
;
140 outputParameters
.sampleFormat
= paFloat32
| paNonInterleaved
; // 32 bit floating point output
141 outputParameters
.suggestedLatency
= (fOutputDevice
!= paNoDevice
) // TODO: check how to setup this on ASIO
142 ? fPaDevices
.GetDeviceInfo(fOutputDevice
)->defaultLowOutputLatency
144 outputParameters
.hostApiSpecificStreamInfo
= NULL
;
146 err
= Pa_OpenStream( &fStream
,
147 (fInputDevice
== paNoDevice
) ? 0 : &inputParameters
,
148 (fOutputDevice
== paNoDevice
) ? 0 : &outputParameters
,
151 paNoFlag
, // Clipping is on...
155 if (err
!= paNoError
) {
156 jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err
));
160 err
= Pa_StartStream(fStream
);
162 if (err
!= paNoError
) {
163 jack_error("Pa_StartStream error = %s", Pa_GetErrorText(err
));
167 jack_log("JackPortAudioAdapter::Open OK");
171 int JackPortAudioAdapter::Close()
174 fTable
.Save(fHostBufferSize
, fHostSampleRate
, fAdaptedSampleRate
, fAdaptedBufferSize
);
176 jack_log("JackPortAudioAdapter::Close");
177 Pa_StopStream(fStream
);
178 jack_log("JackPortAudioAdapter:: Pa_StopStream");
179 Pa_CloseStream(fStream
);
180 jack_log("JackPortAudioAdapter:: Pa_CloseStream");
184 int JackPortAudioAdapter::SetSampleRate(jack_nframes_t sample_rate
)
186 JackAudioAdapterInterface::SetHostSampleRate(sample_rate
);
191 int JackPortAudioAdapter::SetBufferSize(jack_nframes_t buffer_size
)
193 JackAudioAdapterInterface::SetHostBufferSize(buffer_size
);
205 SERVER_EXPORT jack_driver_desc_t
* jack_get_descriptor()
207 jack_driver_desc_t
* desc
;
208 jack_driver_desc_filler_t filler
;
209 jack_driver_param_value_t value
;
211 desc
= jack_driver_descriptor_construct("audioadapter", JackDriverNone
, "netjack audio <==> net backend adapter", &filler
);
214 jack_driver_descriptor_add_parameter(desc
, &filler
, "in-channels", 'i', JackDriverParamUInt
, &value
, NULL
, "Maximum number of input channels", NULL
);
215 jack_driver_descriptor_add_parameter(desc
, &filler
, "out-channels", 'o', JackDriverParamUInt
, &value
, NULL
, "Maximum number of output channels", NULL
);
217 jack_driver_descriptor_add_parameter(desc
, &filler
, "capture", 'C', JackDriverParamString
, &value
, NULL
, "Provide capture ports. Optionally set PortAudio device name", NULL
);
219 jack_driver_descriptor_add_parameter(desc
, &filler
, "playback", 'P', JackDriverParamString
, &value
, NULL
, "Provide playback ports. Optionally set PortAudio device name", NULL
);
222 jack_driver_descriptor_add_parameter(desc
, &filler
, "rate", 'r', JackDriverParamUInt
, &value
, NULL
, "Sample rate", NULL
);
225 jack_driver_descriptor_add_parameter(desc
, &filler
, "periodsize", 'p', JackDriverParamUInt
, &value
, NULL
, "Period size", NULL
);
227 jack_driver_descriptor_add_parameter(desc
, &filler
, "device", 'd', JackDriverParamString
, &value
, NULL
, "PortAudio device name", NULL
);
230 jack_driver_descriptor_add_parameter(desc
, &filler
, "list-devices", 'l', JackDriverParamBool
, &value
, NULL
, "Display available PortAudio devices", NULL
);
233 jack_driver_descriptor_add_parameter(desc
, &filler
, "quality", 'q', JackDriverParamUInt
, &value
, NULL
, "Resample algorithm quality (0 - 4)", NULL
);
236 jack_driver_descriptor_add_parameter(desc
, &filler
, "ring-buffer", 'g', JackDriverParamUInt
, &value
, NULL
, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)");