15 int PANetworkPlayer::ProcessCallback (
16 const void *inputBuffers,
18 unsigned long framesPerBuffer,
19 const PaStreamCallbackTimeInfo* timeInfo,
20 PaStreamCallbackFlags statusFlags,
26 if (statusFlags & paOutputUnderflow)
27 std::cerr <<
"Portaudio backend: Output Underflow" << std::endl;
28 if (statusFlags & paInputUnderflow)
29 std::cerr <<
"Portaudio backend: Input Underflow" << std::endl;
30 if (statusFlags & paOutputOverflow)
31 std::cerr <<
"Portaudio backend: Output Overflow" << std::endl;
32 if (statusFlags & paInputOverflow)
33 std::cerr <<
"Portaudio backend: Input Overflow" << std::endl;
34 if (statusFlags & paPrimingOutput)
35 std::cerr <<
"Portaudio backend: Priming Output" << std::endl;
39 player->Do(inputBuffers, outputBuffers, framesPerBuffer);
46 void displayPADevices()
48 int howManiApis = Pa_GetHostApiCount();
49 int defaultApi = Pa_GetDefaultHostApi();
50 std::cout <<
"Default API " << defaultApi << std::endl;
51 for (
int api=0; api<howManiApis; api++)
53 const PaHostApiInfo * apiInfo = Pa_GetHostApiInfo( api );
55 << (api==defaultApi?
"* ":
" ")
59 for (
int device=0; device<apiInfo->deviceCount; device++)
61 int fullDevice = Pa_HostApiDeviceIndexToDeviceIndex(api, device);
62 const PaDeviceInfo * deviceInfo = Pa_GetDeviceInfo(fullDevice);
64 <<
" (" << fullDevice <<
"/" << device <<
") "
65 << (fullDevice == Pa_GetDefaultInputDevice()?
"*<":
" ")
66 << (fullDevice == Pa_GetDefaultOutputDevice()?
"*>":
" ")
67 << (fullDevice == apiInfo->defaultInputDevice?
"*<":
" ")
68 << (fullDevice == apiInfo->defaultOutputDevice?
"*>":
" ")
70 <<
" Inputs: " << deviceInfo->maxInputChannels
71 <<
" Outputs: " << deviceInfo->maxOutputChannels
80 : mPreferredBufferSize(paFramesPerBufferUnspecified)
81 , mSamplingRate(44100)
100 if (CheckPaError(Pa_Initialize()))
return;
108 PaHostApiTypeId apiTryList[] = {
127 const PaHostApiInfo * apiInfo = 0;
128 for (
unsigned i=0; apiTryList[i]!=paInDevelopment; i++)
130 PaHostApiIndex apiIndex = Pa_HostApiTypeIdToHostApiIndex(apiTryList[i]);
131 std::cerr << apiIndex << std::endl;
132 if (apiIndex<0)
continue;
133 apiInfo = Pa_GetHostApiInfo( apiIndex );
134 std::cerr <<
"Portaudio Chosen API: " << apiInfo->name <<
" " << apiIndex << std::endl;
137 CLAM_ASSERT(apiInfo,
"PortAudio: No API available.");
140 PaStreamParameters inputParameters;
141 PaStreamParameters * inParams = 0;
144 inputParameters.device = apiInfo->defaultInputDevice;
145 if ( inputParameters.device == paNoDevice )
147 mErrorMessage =
"No free default input device";
148 std::cerr <<
"PortAudio Error: " << mErrorMessage << std::endl;
151 const PaDeviceInfo * info = Pa_GetDeviceInfo( inputParameters.device );
152 std::cerr <<
"PortAudio: Chosen Input: " << info->name << std::endl;
153 if (nInChannels > Pa_GetDeviceInfo( inputParameters.device )->maxInputChannels)
155 mErrorMessage =
"Too many input channels for the default device";
156 std::cerr <<
"PortAudio Error: " << mErrorMessage << std::endl;
159 inputParameters.channelCount = nInChannels;
160 inputParameters.sampleFormat = paFloat32 | paNonInterleaved ;
161 inputParameters.suggestedLatency = info->defaultLowOutputLatency;
162 inputParameters.hostApiSpecificStreamInfo =
NULL;
163 inParams = &inputParameters;
166 PaStreamParameters outputParameters;
167 PaStreamParameters * outParams = 0;
170 outputParameters.device = apiInfo->defaultOutputDevice;
171 if ( outputParameters.device == paNoDevice )
173 mErrorMessage =
"No free default output device";
174 std::cerr <<
"PortAudio Error: " << mErrorMessage << std::endl;
177 const PaDeviceInfo * info = Pa_GetDeviceInfo( outputParameters.device );
178 std::cerr <<
"PortAudio: Chosen Output: " << info->name << std::endl;
179 if (nOutChannels > Pa_GetDeviceInfo( outputParameters.device )->maxOutputChannels)
181 mErrorMessage =
"Too many output channels for the default device";
182 std::cerr <<
"PortAudio Error: " << mErrorMessage << std::endl;
185 outputParameters.channelCount = nOutChannels;
186 outputParameters.sampleFormat = paFloat32 | paNonInterleaved ;
187 outputParameters.suggestedLatency = info->defaultLowOutputLatency;
188 outputParameters.hostApiSpecificStreamInfo =
NULL;
189 outParams = &outputParameters;
192 CLAM_ASSERT(!mPortAudioStream,
"Portaudio: Previous stream not closed");
198 double(mSamplingRate),
199 mPreferredBufferSize,
205 mErrorMessage =
"Audio i/o devices requirements not fullfilled";
210 const PaStreamInfo * streamInfo = Pa_GetStreamInfo(mPortAudioStream);
211 std::cout <<
"Sample rate: " << streamInfo->sampleRate << std::endl;
212 std::cout <<
"Input latency: " << streamInfo->inputLatency << std::endl;
213 std::cout <<
"Output latency: " << streamInfo->outputLatency << std::endl;
216 Pa_StartStream( mPortAudioStream );
222 if ( mPortAudioStream )
224 Pa_StopStream( mPortAudioStream );
225 CheckPaError( Pa_CloseStream( mPortAudioStream ) );
234 return mError==paNoError;
239 return mErrorMessage;
242 bool PANetworkPlayer::CheckPaError(PaError result)
245 if( result == paNoError )
return false;
246 mErrorMessage = Pa_GetErrorText(mError);
248 <<
"PortAudio Error #" << result <<
": "
249 << Pa_GetErrorText( result ) << std::endl;
253 void PANetworkPlayer::Do(
const void *inputBuffers,
void *outputBuffers,
254 unsigned long framesPerBuffer)
259 mNeedsPriority =
false;
260 #ifdef TODO__was_WIN32
264 res = SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS );
265 err = GetLastError();
266 res = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL );
267 err = GetLastError();
269 struct sched_param sched_param;
272 if (pthread_getschedparam(pthread_self(), &policy, &sched_param) < 0)
273 std::cerr <<
"Scheduler getparam failed..." << std::endl;
274 sched_param.sched_priority = sched_get_priority_max(SCHED_RR)-1;
275 if (!pthread_setschedparam(pthread_self(), SCHED_RR, &sched_param))
276 std::cerr <<
"Scheduler set to Round Robin with priority "<< sched_param.sched_priority << std::endl;
281 MuteOutBuffers((
float**) outputBuffers, framesPerBuffer);
284 DoInPorts( (
float**) inputBuffers, framesPerBuffer);
285 DoOutPorts( (
float**) outputBuffers, framesPerBuffer);
289 void PANetworkPlayer::DoInPorts(
float** input,
unsigned long nframes)
297 void PANetworkPlayer::DoOutPorts(
float** output,
unsigned long nframes)
305 void PANetworkPlayer::MuteOutBuffers(
float** output,
unsigned long nframes)
308 for (
unsigned i=0; i<nSinks; i++)
309 std::memset(output[i], 0, nframes*
sizeof(
float));