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