33 const void *inputBuffer,
35 unsigned long framesPerBuffer,
36 const PaStreamCallbackTimeInfo* timeInfo,
37 PaStreamCallbackFlags statusFlags,
40 float *out = (
float* )outputBuffer;
42 if ( pDriver ==
nullptr ) {
47 while ( framesPerBuffer > 0 ) {
48 unsigned long nFrames = std::min( (
unsigned long)
MAX_BUFFER_SIZE, framesPerBuffer );
51 for (
unsigned i = 0; i < nFrames; i++ ) {
55 framesPerBuffer -= nFrames;
115 if ( HostAPI.isNull() || HostAPI ==
"" ) {
117 auto pInfo = Pa_GetHostApiInfo( Pa_GetDefaultHostApi() );
118 if ( pInfo ==
nullptr ) {
119 ERRORLOG(
"Unable to obtain default Host API" );
123 HostAPI = pInfo->name;
126 int nDevices = Pa_GetDeviceCount();
127 for (
int nDevice = 0; nDevice < nDevices; nDevice++ ) {
128 const PaDeviceInfo *pDeviceInfo = Pa_GetDeviceInfo( nDevice );
129 if ( pDeviceInfo ==
nullptr ) {
134 auto pInfo = Pa_GetHostApiInfo( pDeviceInfo->hostApi );
135 if ( pInfo ==
nullptr || pInfo->name != HostAPI ) {
138 if ( pDeviceInfo->maxOutputChannels >= 2 ) {
139 devices.push_back( QString( pDeviceInfo->name ) );
158 bool bUseDefaultStream =
true;
167 err = Pa_Initialize();
169 if ( err != paNoError ) {
170 ERRORLOG(
"Portaudio error in Pa_Initialize: " + QString( Pa_GetErrorText( err ) ) );
179 int nDevices = Pa_GetDeviceCount();
180 const PaDeviceInfo *pDeviceInfo;
181 for (
int nDevice = 0; nDevice < nDevices; nDevice++ ) {
182 pDeviceInfo = Pa_GetDeviceInfo( nDevice );
183 if ( pDeviceInfo ==
nullptr ) {
189 auto pInfo = Pa_GetHostApiInfo( pDeviceInfo->hostApi );
195 if ( pDeviceInfo->maxOutputChannels >= 2
196 && ( QString::compare(
m_sDevice, pDeviceInfo->name, Qt::CaseInsensitive ) == 0 ||
198 PaStreamParameters outputParameters;
199 memset( &outputParameters,
'\0',
sizeof( outputParameters ) );
200 outputParameters.channelCount = 2;
201 outputParameters.device = nDevice;
202 outputParameters.hostApiSpecificStreamInfo =
nullptr;
203 outputParameters.sampleFormat = paFloat32;
207 outputParameters.suggestedLatency =
208 Pa_GetDeviceInfo( nDevice )->defaultHighInputLatency;
218 if ( err != paNoError ) {
219 ERRORLOG( QString(
"Found but can't open device '%1' (max %3 in, %4 out): %2" )
220 .arg(
m_sDevice ).arg( Pa_GetErrorText( err ) )
221 .arg( pDeviceInfo->maxInputChannels ).arg( pDeviceInfo->maxOutputChannels ) );
226 bUseDefaultStream =
false;
230 if ( bUseDefaultStream ) {
231 ERRORLOG( QString(
"Can't use device '%1', using default stream" )
236 if ( bUseDefaultStream ) {
239 err = Pa_OpenDefaultStream(
245 paFramesPerBufferUnspecified,
250 if ( err != paNoError ) {
251 ERRORLOG(
"Portaudio error in Pa_OpenDefaultStream: " + QString( Pa_GetErrorText( err ) ) );
260 const PaStreamInfo *pStreamInfo = Pa_GetStreamInfo(
m_pStream );
261 if ( pStreamInfo ==
nullptr ) {
267 ERRORLOG( QString(
"Couldn't get sample rate %d, using %d instead" ).arg(
m_nSampleRate ).arg( pStreamInfo->sampleRate ) );
270 INFOLOG( QString(
"PortAudio outpot latency: %1 s" ).arg( pStreamInfo->outputLatency ) );
275 if ( err != paNoError ) {
276 ERRORLOG(
"Portaudio error in Pa_StartStream: " + QString( Pa_GetErrorText( err ) ) );
int portAudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)