00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackPortAudioAdapter.h"
00021 #include "JackError.h"
00022
00023 namespace Jack
00024 {
00025
00026 int JackPortAudioAdapter::Render(const void* inputBuffer,
00027 void* outputBuffer,
00028 unsigned long framesPerBuffer,
00029 const PaStreamCallbackTimeInfo* timeInfo,
00030 PaStreamCallbackFlags statusFlags,
00031 void* userData)
00032 {
00033 static_cast<JackPortAudioAdapter*>(userData)->PushAndPull((jack_default_audio_sample_t**)inputBuffer, (jack_default_audio_sample_t**)outputBuffer, framesPerBuffer);
00034 return paContinue;
00035 }
00036
00037 JackPortAudioAdapter::JackPortAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params)
00038 : JackAudioAdapterInterface(buffer_size, sample_rate)
00039 {
00040 jack_log("JackPortAudioAdapter::JackPortAudioAdapter buffer_size = %d, sample_rate = %d", buffer_size, sample_rate);
00041
00042 const JSList* node;
00043 const jack_driver_param_t* param;
00044 int in_max = 0;
00045 int out_max = 0;
00046
00047 fInputDevice = Pa_GetDefaultInputDevice();
00048 fOutputDevice = Pa_GetDefaultOutputDevice();
00049
00050 for (node = params; node; node = jack_slist_next(node)) {
00051 param = (const jack_driver_param_t*) node->data;
00052
00053 switch (param->character)
00054 {
00055 case 'i' :
00056 fCaptureChannels = param->value.ui;
00057 break;
00058 case 'o' :
00059 fPlaybackChannels = param->value.ui;
00060 break;
00061 case 'C' :
00062 if (fPaDevices.GetInputDeviceFromName(param->value.str, fInputDevice, in_max) < 0) {
00063 jack_error("Can't use %s, taking default input device", param->value.str);
00064 fInputDevice = Pa_GetDefaultInputDevice();
00065 }
00066 break;
00067 case 'P' :
00068 if (fPaDevices.GetOutputDeviceFromName(param->value.str, fOutputDevice, out_max) < 0) {
00069 jack_error("Can't use %s, taking default output device", param->value.str);
00070 fOutputDevice = Pa_GetDefaultOutputDevice();
00071 }
00072 break;
00073 case 'r' :
00074 SetAdaptedSampleRate(param->value.ui);
00075 break;
00076 case 'p' :
00077 SetAdaptedBufferSize(param->value.ui);
00078 break;
00079 case 'd' :
00080 if (fPaDevices.GetInputDeviceFromName(param->value.str, fInputDevice, in_max) < 0)
00081 jack_error("Can't use %s, taking default input device", param->value.str);
00082 if (fPaDevices.GetOutputDeviceFromName(param->value.str, fOutputDevice, out_max) < 0)
00083 jack_error("Can't use %s, taking default output device", param->value.str);
00084 break;
00085 case 'l' :
00086 fPaDevices.DisplayDevicesNames();
00087 break;
00088 case 'q':
00089 fQuality = param->value.ui;
00090 break;
00091 case 'g':
00092 fRingbufferCurSize = param->value.ui;
00093 fAdaptative = false;
00094 break;
00095 }
00096 }
00097
00098
00099 if (in_max == 0 && fInputDevice != paNoDevice)
00100 in_max = fPaDevices.GetDeviceInfo(fInputDevice)->maxInputChannels;
00101 if (out_max == 0 && fOutputDevice != paNoDevice)
00102 out_max = fPaDevices.GetDeviceInfo(fOutputDevice)->maxOutputChannels;
00103
00104
00105 if ((fCaptureChannels == 0) || (fCaptureChannels > in_max))
00106 fCaptureChannels = in_max;
00107 if ((fPlaybackChannels == 0) || (fPlaybackChannels > out_max))
00108 fPlaybackChannels = out_max;
00109
00110
00111 SetInputs(fCaptureChannels);
00112 SetOutputs(fPlaybackChannels);
00113 }
00114
00115 int JackPortAudioAdapter::Open()
00116 {
00117 PaError err;
00118 PaStreamParameters inputParameters;
00119 PaStreamParameters outputParameters;
00120
00121 if (fInputDevice == paNoDevice && fOutputDevice == paNoDevice) {
00122 jack_error("No input and output device!!");
00123 return -1;
00124 }
00125
00126 jack_log("JackPortAudioAdapter::Open fInputDevice = %d DeviceName %s", fInputDevice, fPaDevices.GetFullName(fInputDevice).c_str());
00127 jack_log("JackPortAudioAdapter::Open fOutputDevice = %d DeviceName %s", fOutputDevice, fPaDevices.GetFullName(fOutputDevice).c_str());
00128 jack_log("JackPortAudioAdapter::Open fAdaptedBufferSize = %u fAdaptedSampleRate %u", fAdaptedBufferSize, fAdaptedSampleRate);
00129
00130 inputParameters.device = fInputDevice;
00131 inputParameters.channelCount = fCaptureChannels;
00132 inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
00133 inputParameters.suggestedLatency = (fInputDevice != paNoDevice)
00134 ? fPaDevices.GetDeviceInfo(fInputDevice)->defaultLowInputLatency
00135 : 0;
00136 inputParameters.hostApiSpecificStreamInfo = NULL;
00137
00138 outputParameters.device = fOutputDevice;
00139 outputParameters.channelCount = fPlaybackChannels;
00140 outputParameters.sampleFormat = paFloat32 | paNonInterleaved;
00141 outputParameters.suggestedLatency = (fOutputDevice != paNoDevice)
00142 ? fPaDevices.GetDeviceInfo(fOutputDevice)->defaultLowOutputLatency
00143 : 0;
00144 outputParameters.hostApiSpecificStreamInfo = NULL;
00145
00146 err = Pa_OpenStream( &fStream,
00147 (fInputDevice == paNoDevice) ? 0 : &inputParameters,
00148 (fOutputDevice == paNoDevice) ? 0 : &outputParameters,
00149 fAdaptedSampleRate,
00150 fAdaptedBufferSize,
00151 paNoFlag,
00152 Render,
00153 this);
00154
00155 if (err != paNoError) {
00156 jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err));
00157 return -1;
00158 }
00159
00160 err = Pa_StartStream(fStream);
00161
00162 if (err != paNoError) {
00163 jack_error("Pa_StartStream error = %s", Pa_GetErrorText(err));
00164 return -1;
00165 }
00166
00167 jack_log("JackPortAudioAdapter::Open OK");
00168 return 0;
00169 }
00170
00171 int JackPortAudioAdapter::Close()
00172 {
00173 #ifdef JACK_MONITOR
00174 fTable.Save(fHostBufferSize, fHostSampleRate, fAdaptedSampleRate, fAdaptedBufferSize);
00175 #endif
00176 jack_log("JackPortAudioAdapter::Close");
00177 Pa_StopStream(fStream);
00178 jack_log("JackPortAudioAdapter:: Pa_StopStream");
00179 Pa_CloseStream(fStream);
00180 jack_log("JackPortAudioAdapter:: Pa_CloseStream");
00181 return 0;
00182 }
00183
00184 int JackPortAudioAdapter::SetSampleRate(jack_nframes_t sample_rate)
00185 {
00186 JackAudioAdapterInterface::SetHostSampleRate(sample_rate);
00187 Close();
00188 return Open();
00189 }
00190
00191 int JackPortAudioAdapter::SetBufferSize(jack_nframes_t buffer_size)
00192 {
00193 JackAudioAdapterInterface::SetHostBufferSize(buffer_size);
00194 Close();
00195 return Open();
00196 }
00197
00198 }
00199
00200 #ifdef __cplusplus
00201 extern "C"
00202 {
00203 #endif
00204
00205 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor()
00206 {
00207 jack_driver_desc_t * desc;
00208 jack_driver_desc_filler_t filler;
00209 jack_driver_param_value_t value;
00210
00211 desc = jack_driver_descriptor_construct("audioadapter", JackDriverNone, "netjack audio <==> net backend adapter", &filler);
00212
00213 value.ui = 0;
00214 jack_driver_descriptor_add_parameter(desc, &filler, "in-channels", 'i', JackDriverParamInt, &value, NULL, "Maximum number of input channels", NULL);
00215 jack_driver_descriptor_add_parameter(desc, &filler, "out-channels", 'o', JackDriverParamInt, &value, NULL, "Maximum number of output channels", NULL);
00216
00217 jack_driver_descriptor_add_parameter(desc, &filler, "capture", 'C', JackDriverParamString, &value, NULL, "Provide capture ports. Optionally set PortAudio device name", NULL);
00218
00219 jack_driver_descriptor_add_parameter(desc, &filler, "playback", 'P', JackDriverParamString, &value, NULL, "Provide playback ports. Optionally set PortAudio device name", NULL);
00220
00221 value.ui = 44100U;
00222 jack_driver_descriptor_add_parameter(desc, &filler, "rate", 'r', JackDriverParamUInt, &value, NULL, "Sample rate", NULL);
00223
00224 value.ui = 512U;
00225 jack_driver_descriptor_add_parameter(desc, &filler, "periodsize", 'p', JackDriverParamUInt, &value, NULL, "Period size", NULL);
00226
00227 jack_driver_descriptor_add_parameter(desc, &filler, "device", 'd', JackDriverParamString, &value, NULL, "PortAudio device name", NULL);
00228
00229 value.i = true;
00230 jack_driver_descriptor_add_parameter(desc, &filler, "list-devices", 'l', JackDriverParamBool, &value, NULL, "Display available PortAudio devices", NULL);
00231
00232 value.ui = 0;
00233 jack_driver_descriptor_add_parameter(desc, &filler, "quality", 'q', JackDriverParamInt, &value, NULL, "Resample algorithm quality (0 - 4)", NULL);
00234
00235 value.ui = 32768;
00236 jack_driver_descriptor_add_parameter(desc, &filler, "ring-buffer", 'g', JackDriverParamInt, &value, NULL, "Fixed ringbuffer size", "Fixed ringbuffer size (if not set => automatic adaptative)");
00237
00238 return desc;
00239 }
00240
00241 #ifdef __cplusplus
00242 }
00243 #endif
00244