|
- /*
- Copyright (C) 2008 Grame
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
- #include "JackPortAudioAdapter.h"
- #include "JackError.h"
-
- namespace Jack
- {
-
- int JackPortAudioAdapter::Render(const void* inputBuffer,
- void* outputBuffer,
- unsigned long framesPerBuffer,
- const PaStreamCallbackTimeInfo* timeInfo,
- PaStreamCallbackFlags statusFlags,
- void* userData)
- {
- static_cast<JackPortAudioAdapter*>(userData)->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, framesPerBuffer);
- return paContinue;
- }
-
- JackPortAudioAdapter::JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params)
- : JackAudioAdapterInterface(buffer_size, sample_rate)
- {
- jack_log("JackPortAudioAdapter::JackPortAudioAdapter buffer_size = %d, sample_rate = %d", buffer_size, sample_rate);
-
- const JSList* node;
- const jack_driver_param_t* param;
- int in_max = 0;
- int out_max = 0;
-
- fInputDevice = Pa_GetDefaultInputDevice();
- fOutputDevice = Pa_GetDefaultOutputDevice();
-
- for (node = params; node; node = jack_slist_next(node)) {
- param = (const jack_driver_param_t*) node->data;
-
- switch (param->character)
- {
- case 'i' :
- fCaptureChannels = param->value.ui;
- break;
- case 'o' :
- fPlaybackChannels = param->value.ui;
- break;
- case 'C' :
- if (fPaDevices.GetInputDeviceFromName(param->value.str, fInputDevice, in_max) < 0) {
- jack_error("Can't use %s, taking default input device", param->value.str);
- fInputDevice = Pa_GetDefaultInputDevice();
- }
- break;
- case 'P' :
- if (fPaDevices.GetOutputDeviceFromName(param->value.str, fOutputDevice, out_max) < 0) {
- jack_error("Can't use %s, taking default output device", param->value.str);
- fOutputDevice = Pa_GetDefaultOutputDevice();
- }
- break;
- case 'r' :
- SetAdaptedSampleRate(param->value.ui);
- break;
- case 'p' :
- SetAdaptedBufferSize(param->value.ui);
- break;
- case 'd' :
- if (fPaDevices.GetInputDeviceFromName(param->value.str, fInputDevice, in_max) < 0)
- jack_error("Can't use %s, taking default input device", param->value.str);
- if (fPaDevices.GetOutputDeviceFromName(param->value.str, fOutputDevice, out_max) < 0)
- jack_error("Can't use %s, taking default output device", param->value.str);
- break;
- case 'l' :
- fPaDevices.DisplayDevicesNames();
- break;
- case 'q':
- fQuality = param->value.ui;
- break;
- case 'g':
- fRingbufferCurSize = param->value.ui;
- fAdaptative = false;
- break;
- }
- }
-
- //max channels
- if (in_max == 0 && fInputDevice != paNoDevice)
- in_max = fPaDevices.GetDeviceInfo(fInputDevice)->maxInputChannels;
- if (out_max == 0 && fOutputDevice != paNoDevice)
- out_max = fPaDevices.GetDeviceInfo(fOutputDevice)->maxOutputChannels;
-
- //effective channels
- if ((fCaptureChannels == 0) || (fCaptureChannels > in_max))
- fCaptureChannels = in_max;
- if ((fPlaybackChannels == 0) || (fPlaybackChannels > out_max))
- fPlaybackChannels = out_max;
-
- //set adapter interface channels
- SetInputs(fCaptureChannels);
- SetOutputs(fPlaybackChannels);
- }
-
- int JackPortAudioAdapter::Open()
- {
- PaError err;
- PaStreamParameters inputParameters;
- PaStreamParameters outputParameters;
-
- if (fInputDevice == paNoDevice && fOutputDevice == paNoDevice) {
- jack_error("No input and output device!!");
- return -1;
- }
-
- jack_log("JackPortAudioAdapter::Open fInputDevice = %d DeviceName %s", fInputDevice, fPaDevices.GetFullName(fInputDevice).c_str());
- jack_log("JackPortAudioAdapter::Open fOutputDevice = %d DeviceName %s", fOutputDevice, fPaDevices.GetFullName(fOutputDevice).c_str());
- jack_log("JackPortAudioAdapter::Open fAdaptedBufferSize = %u fAdaptedSampleRate %u", fAdaptedBufferSize, fAdaptedSampleRate);
-
- inputParameters.device = fInputDevice;
- inputParameters.channelCount = fCaptureChannels;
- inputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
- inputParameters.suggestedLatency = (fInputDevice != paNoDevice) // TODO: check how to setup this on ASIO
- ? fPaDevices.GetDeviceInfo(fInputDevice)->defaultLowInputLatency
- : 0;
- inputParameters.hostApiSpecificStreamInfo = NULL;
-
- outputParameters.device = fOutputDevice;
- outputParameters.channelCount = fPlaybackChannels;
- outputParameters.sampleFormat = paFloat32 | paNonInterleaved; // 32 bit floating point output
- outputParameters.suggestedLatency = (fOutputDevice != paNoDevice) // TODO: check how to setup this on ASIO
- ? fPaDevices.GetDeviceInfo(fOutputDevice)->defaultLowOutputLatency
- : 0;
- outputParameters.hostApiSpecificStreamInfo = NULL;
-
- err = Pa_OpenStream( &fStream,
- (fInputDevice == paNoDevice) ? 0 : &inputParameters,
- (fOutputDevice == paNoDevice) ? 0 : &outputParameters,
- fAdaptedSampleRate,
- fAdaptedBufferSize,
- paNoFlag, // Clipping is on...
- Render,
- this);
-
- if (err != paNoError) {
- jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err));
- return -1;
- }
-
- err = Pa_StartStream(fStream);
-
- if (err != paNoError) {
- jack_error("Pa_StartStream error = %s", Pa_GetErrorText(err));
- return -1;
- }
-
- jack_log("JackPortAudioAdapter::Open OK");
- return 0;
- }
-
- int JackPortAudioAdapter::Close()
- {
- #ifdef JACK_MONITOR
- fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
- #endif
- jack_log("JackPortAudioAdapter::Close");
- Pa_StopStream(fStream);
- jack_log("JackPortAudioAdapter:: Pa_StopStream");
- Pa_CloseStream(fStream);
- jack_log("JackPortAudioAdapter:: Pa_CloseStream");
- return 0;
- }
-
- int JackPortAudioAdapter::SetSampleRate(jack_nframes_t sample_rate)
- {
- JackAudioAdapterInterface::SetHostSampleRate(sample_rate);
- Close();
- return Open();
- }
-
- int JackPortAudioAdapter::SetBufferSize(jack_nframes_t buffer_size)
- {
- JackAudioAdapterInterface::SetHostBufferSize(buffer_size);
- Close();
- return Open();
- }
-
- } // namespace
-
- #ifdef __cplusplus
- extern "C"
- {
- #endif
-
- SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
- {
- jack_driver_desc_t * desc;
- jack_driver_desc_filler_t filler;
- jack_driver_param_value_t value;
-
- desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler);
-
- value.ui = 0;
- jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamUInt, &value, NULL, "Maximum number of input channels", NULL);
- jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamUInt, &value, NULL, "Maximum number of output channels", NULL);
-
- jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set PortAudio device name", NULL);
-
- jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set PortAudio device name", NULL);
-
- value.ui = 44100U;
- jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
-
- value.ui = 512U;
- jack_driver_descriptor_add_parameter(desc, &filler, "periodsize", 'p', JackDriverParamUInt, &value, NULL, "Period size", NULL);
-
- jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "PortAudio device name", NULL);
-
- value.i = true;
- jack_driver_descriptor_add_parameter(desc, &filler, "list-devices", 'l', JackDriverParamBool, &value, NULL, "Display available PortAudio devices", NULL);
-
- value.ui = 0;
- jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamUInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL);
-
- value.ui = 32768;
- jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamUInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)");
-
- return desc;
- }
-
- #ifdef __cplusplus
- }
- #endif
|