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