PaError TestOnce( int buffersize, PaDeviceIndex device ) { PaStreamParameters outputParameters; PaStream *stream; PaError err; paTestData data; int i; int totalSamps; /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )); } data.left_phase = data.right_phase = 0; data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ err = Pa_Initialize(); if( err != paNoError ) goto error; if( device == -1 ) outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ else outputParameters.device = device ; if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto error; } outputParameters.channelCount = 2; /* stereo output */ outputParameters.sampleFormat = paInt16; /* 32 bit floating point output */ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &stream, NULL, /* no input */ &outputParameters, SAMPLE_RATE, buffersize, /* frames per buffer */ (paClipOff | paDitherOff), patest1Callback, &data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Waiting for sound to finish.\n"); Pa_Sleep(1000*NUM_SECONDS); err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); return paNoError; error: Pa_Terminate(); fprintf( stderr, "An error occured while using the portaudio stream\n" ); fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); fprintf( stderr, "Host Error message: %s\n", Pa_GetLastHostErrorInfo()->errorText ); return err; }
static void logPortAudioError(const char *msg, PaError error) { if (error == paUnanticipatedHostError) { const PaHostErrorInfo *info = Pa_GetLastHostErrorInfo(); qCritical("%s: unanticipated host error: %s (%ld)", msg, info->errorText, info->errorCode); } else { qCritical("%s: %s", msg, Pa_GetErrorText(error)); } }
static bool check_pa_ret(struct mp_log *log, int ret) { if (ret < 0) { mp_err(log, "%s\n", Pa_GetErrorText(ret)); if (ret == paUnanticipatedHostError) { const PaHostErrorInfo* hosterr = Pa_GetLastHostErrorInfo(); mp_err(log, "Host error: %s\n", hosterr->errorText); } return false; } return true; }
static bool check_pa_ret(int ret) { if (ret < 0) { mp_msg(MSGT_AO, MSGL_ERR, "[ao/portaudio] %s\n", Pa_GetErrorText(ret)); if (ret == paUnanticipatedHostError) { const PaHostErrorInfo* hosterr = Pa_GetLastHostErrorInfo(); mp_msg(MSGT_AO, MSGL_ERR, "[ao/portaudio] Host error: %s\n", hosterr->errorText); } return false; } return true; }
// Throw an exception on error. jint jpa_CheckError( JNIEnv *env, PaError err ) { if( err == -1 ) { return jpa_ThrowErrorNoCode( env, "-1, possibly no available default device" ); } else if( err < 0 ) { if( err == paUnanticipatedHostError ) { const PaHostErrorInfo *hostErrorInfo = Pa_GetLastHostErrorInfo(); return jpa_ThrowError( env, err, hostErrorInfo->errorText ); } else { return jpa_ThrowError( env, err, Pa_GetErrorText( err ) ); } } else { return err; } }
int main(int argc, char* argv[]) { PaStream *stream; PaError err; patest1data data; int i; PaStreamParameters inputParameters, outputParameters; const PaHostErrorInfo* herr; printf("patest1.c\n"); fflush(stdout); printf("Ring modulate input for 20 seconds.\n"); fflush(stdout); /* initialise sinusoidal wavetable */ for( i=0; i<100; i++ ) data.sine[i] = sin( ((double)i/100.) * M_PI * 2. ); data.phase = 0; data.sampsToGo = SAMPLE_RATE * 20; /* 20 seconds. */ /* initialise portaudio subsytem */ err = Pa_Initialize(); inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: No input default device.\n"); goto done; } inputParameters.channelCount = 2; /* stereo input */ inputParameters.sampleFormat = paFloat32; /* 32 bit floating point input */ inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto done; } outputParameters.channelCount = 2; /* stereo output */ outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &stream, &inputParameters, &outputParameters, (double)SAMPLE_RATE, /* Samplerate in Hertz. */ 512, /* Small buffers */ paClipOff, /* We won't output out of range samples so don't bother clipping them. */ patest1Callback, &data ); if( err != paNoError ) goto done; err = Pa_StartStream( stream ); if( err != paNoError ) goto done; printf( "Press any key to end.\n" ); fflush(stdout); getc( stdin ); /* wait for input before exiting */ err = Pa_AbortStream( stream ); if( err != paNoError ) goto done; printf( "Waiting for stream to complete...\n" ); /* sleep until playback has finished */ while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(1000); if( err < 0 ) goto done; err = Pa_CloseStream( stream ); if( err != paNoError ) goto done; done: Pa_Terminate(); if( err != paNoError ) { fprintf( stderr, "An error occured while using portaudio\n" ); if( err == paUnanticipatedHostError ) { fprintf( stderr, " unanticipated host error.\n"); herr = Pa_GetLastHostErrorInfo(); if (herr) { fprintf( stderr, " Error number: %ld\n", herr->errorCode ); if (herr->errorText) fprintf( stderr, " Error text: %s\n", herr->errorText ); } else fprintf( stderr, " Pa_GetLastHostErrorInfo() failed!\n" ); } else { fprintf( stderr, " Error number: %d\n", err ); fprintf( stderr, " Error text: %s\n", Pa_GetErrorText( err ) ); } err = 1; /* Always return 0 or 1, but no other return codes. */ } printf( "bye\n" ); return err; }
static int PAOpenStream( audio_output_t *p_aout ) { aout_sys_t *p_sys = p_aout->sys; const PaHostErrorInfo* paLastHostErrorInfo = Pa_GetLastHostErrorInfo(); PaStreamParameters paStreamParameters; vlc_value_t val; int i_channels, i_err; uint32_t i_channel_mask; if( var_Get( p_aout, "audio-device", &val ) < 0 ) { return VLC_EGENERIC; } if( val.i_int == AOUT_VAR_5_1 ) { p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE; } else if( val.i_int == AOUT_VAR_3F2R ) { p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; } else if( val.i_int == AOUT_VAR_2F2R ) { p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; } else if( val.i_int == AOUT_VAR_MONO ) { p_aout->format.i_physical_channels = AOUT_CHAN_CENTER; } else { p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } i_channels = aout_FormatNbChannels( &p_aout->format ); msg_Dbg( p_aout, "nb_channels requested = %d", i_channels ); i_channel_mask = p_aout->format.i_physical_channels; /* Calculate the frame size in bytes */ p_sys->i_sample_size = 4 * i_channels; aout_FormatPrepare( &p_aout->format ); aout_PacketInit( p_aout, &p_sys->packet, FRAME_SIZE ); aout_VolumeSoftInit( p_aout ); /* Check for channel reordering */ p_aout->sys->i_channel_mask = i_channel_mask; p_aout->sys->i_bits_per_sample = 32; /* forced to paFloat32 */ p_aout->sys->i_channels = i_channels; p_aout->sys->b_chan_reorder = aout_CheckChannelReorder( NULL, pi_channels_out, i_channel_mask, i_channels, p_aout->sys->pi_chan_table ); if( p_aout->sys->b_chan_reorder ) { msg_Dbg( p_aout, "channel reordering needed" ); } paStreamParameters.device = p_sys->i_device_id; paStreamParameters.channelCount = i_channels; paStreamParameters.sampleFormat = paFloat32; paStreamParameters.suggestedLatency = p_sys->deviceInfo->defaultLowOutputLatency; paStreamParameters.hostApiSpecificStreamInfo = NULL; i_err = Pa_OpenStream( &p_sys->p_stream, NULL /* no input */, &paStreamParameters, (double)p_aout->format.i_rate, FRAME_SIZE, paClipOff, paCallback, p_sys ); if( i_err != paNoError ) { msg_Err( p_aout, "Pa_OpenStream returns %d : %s", i_err, Pa_GetErrorText( i_err ) ); if( i_err == paUnanticipatedHostError ) { msg_Err( p_aout, "type %d code %ld : %s", paLastHostErrorInfo->hostApiType, paLastHostErrorInfo->errorCode, paLastHostErrorInfo->errorText ); } p_sys->p_stream = 0; aout_PacketDestroy( p_aout ); return VLC_EGENERIC; } i_err = Pa_StartStream( p_sys->p_stream ); if( i_err != paNoError ) { msg_Err( p_aout, "Pa_StartStream() failed" ); Pa_CloseStream( p_sys->p_stream ); aout_PacketDestroy( p_aout ); return VLC_EGENERIC; } return VLC_SUCCESS; }
void* AudioThread::Entry() { GlobalConfig* config = GlobalConfig::getInstance(); config->Log( "AudioThread::Entry();" ); m_Done = false; m_PaStreamIsActive = false; int cnt=0; while( not m_Done ) { // Check Audio-Device-State every 100 ms switch( m_AudioState ) { case STATE_CLOSED: { config->Log( "Audiothread-STATE: CLOSED" ); // closed ?!? Then try to configure it... Configure(); break; } case STATE_OPEN: { config->Log( "Audiothread-STATE: OPEN" ); // Open, but not running? Then start it by all means... int err=Pa_StartStream( m_PaStream ); int cnt=0; while( err != paNoError && cnt<5 ) { err = Pa_StartStream( m_PaStream ); cnt++; } if( err == paNoError ) { m_PaStreamIsActive = true; config->Log( "Audiothread-STATE: OPEN and Portaudio-Stream successfully started." ); config->Log( " Portaudio-Error-Code: %i ", err ); config->Log( " Portaudio-Error-Text: %s ", Pa_GetErrorText( err ) ); m_AudioState = STATE_RUNNING; } else { m_AudioState = STATE_ERROR; config->Log( "Audiothread-STATE: OPEN and Portaudio-Stream *NOT* successfully started." ); config->Log( " Portaudio-Error-Code: %i ", err ); config->Log( " Portaudio-Error-Text: %s ", Pa_GetErrorText( err ) ); } // change audio-state to running... break; } case STATE_ERROR: { // close all active streams ... if( m_PaStreamIsActive ) { Pa_CloseStream( m_PaStream ); m_PaStreamIsActive = false; } // send an event, so the user can notice that there is something // going wrong badly... //wxWindow* statusWindow = Config->getStatusWindow(); //wxCommandEvent event(wxEVT_COMMAND_MIXER_ERROR); //statusWindow->AddPendingEvent( event ); // now wait here(!) until the user changes the configuration // again while( m_AudioState == STATE_ERROR ) { config->Log( "Audiothread-STATE: *** ERROR ***" ); // Check for reconfiguration-request... m_ReconfigureLock.Lock(); if( m_ReconfigureFlag ) { // reset flag m_ReconfigureFlag = false; // change AudioState m_AudioState = STATE_CLOSED; } m_ReconfigureLock.Unlock(); Sleep( 1000 ); // wait a second } break; } case STATE_RUNNING: default: { // do nothing but wait for reconfigure-flag... and check that // all audio-streams are up and running... cnt = (cnt+1)%80; if( cnt==0 ) { double cpuLoad = Pa_GetStreamCpuLoad( m_PaStream ); config->Log( "Audiothread-STATE: RUNNING (%f)", floor(cpuLoad*1000.0+0.5)/10.0 ); } // Check for reconfiguration-request... m_ReconfigureLock.Lock(); if( m_ReconfigureFlag ) { // close all active streams and change state... if( m_PaStreamIsActive ) { Pa_CloseStream( m_PaStream ); m_PaStreamIsActive = false; } // reset flag m_ReconfigureFlag = false; // change AudioState m_AudioState = STATE_CLOSED; } m_ReconfigureLock.Unlock(); // Check that everything is OK with the streams... if( m_PaStreamIsActive ) { if( Pa_IsStreamActive( m_PaStream ) != 1 ) { // flag error m_AudioState = STATE_ERROR; // try to get some information on the // error... const PaHostErrorInfo* errorInfo = Pa_GetLastHostErrorInfo(); config->Log( "PaGetLastErrorInfo: %i %i %s", (int)errorInfo->hostApiType, errorInfo->errorCode, errorInfo->errorText ); } } } } Sleep( 100 ); // wait for 100 ms } // close all active streams ... if( m_PaStreamIsActive ) { Pa_StopStream( m_PaStream ); Pa_CloseStream( m_PaStream ); m_PaStreamIsActive = false; } // all finished here... return( 0 ); }
void AudioThread::Configure() { GlobalConfig* config = GlobalConfig::getInstance(); config->Log( "AudioThread::Configure();" ); // Try to configure Audio-Hardware bool everythingIsOk = true; bool outputIsOpen = false; // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // test desired output-device for allowed sample-rates // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ int PortaudioDeviceIndexOut = config->getOutputDevice_PA(); int PortaudioDeviceIndexIn = config->getInputDevice_PA (); m_SampleRate = config->getSampleRate(); config->Log( "Input-Device = %i", PortaudioDeviceIndexIn ); config->Log( "Output-Device = %i", PortaudioDeviceIndexOut ); config->Log( "Sample-Rate = %f", m_SampleRate ); // if we got a valid result, then open the output-device if( m_SampleRate > 0 and everythingIsOk ) { // all parameters in m_PaParameters are set, now, so we just need to // setup the callback-address and decide how many frames per buffer // we want to have... memset( &m_PaParametersIn, 0, sizeof( m_PaParametersIn ) ); memset( &m_PaParametersOut, 0, sizeof( m_PaParametersOut ) ); double inputLatency = Pa_GetDeviceInfo( PortaudioDeviceIndexOut ) ->defaultLowInputLatency; double outputLatency = inputLatency; config->Log( "Latency-In : %f seconds", inputLatency*m_SampleRate ); config->Log( "Latency-Out : %f seconds", outputLatency*m_SampleRate ); m_FramesPerBuffer = inputLatency*m_SampleRate/10.0; m_PaParametersOut.device = PortaudioDeviceIndexOut; m_PaParametersOut.channelCount = 2; m_PaParametersOut.suggestedLatency = outputLatency*3; m_PaParametersOut.sampleFormat = paFloat32; m_PaParametersOut.hostApiSpecificStreamInfo = NULL; m_PaParametersIn.device = PortaudioDeviceIndexIn; m_PaParametersIn.channelCount = 2; m_PaParametersIn.suggestedLatency = inputLatency*3; m_PaParametersIn.sampleFormat = paFloat32; m_PaParametersIn.hostApiSpecificStreamInfo = NULL; int err = Pa_OpenStream( &m_PaStream, &m_PaParametersIn, &m_PaParametersOut, m_SampleRate, paFramesPerBufferUnspecified,//m_FramesPerBuffer, paNeverDropInput,//paNoFlag, &(this->PaCallback), (void *)this ); if( err != paNoError ) { config->Log( "*** Portaudio-Error, when opening Device:" ); config->Log( "*** %s", Pa_GetErrorText(err) ); everythingIsOk = false; } else { outputIsOpen = true; } } else { config->Log( "*** Samplerate-Test failed on Device." ); everythingIsOk = false; } if( everythingIsOk ) { // Yessss.... we're open, now... ;-) wxMutexLocker lock( m_ThreadMutex ); m_AudioState = STATE_OPEN; delete m_SDRAudio; m_SDRAudio = new SDRAudio( m_SampleRate ); } else { // oops... something went bad... so, we close all already opened audio- // devices (if any)... if( outputIsOpen ) { Pa_CloseStream( &m_PaStream ); } m_AudioState = STATE_ERROR; // try to get some information on the // error... const PaHostErrorInfo* errorInfo = Pa_GetLastHostErrorInfo(); config->Log( "PaGetLastErrorInfo: %i %i %s", (int)errorInfo->hostApiType, errorInfo->errorCode, errorInfo->errorText ); } }
JNIEXPORT jobject JNICALL Java_com_github_rjeschke_jpa_JPA_getLastHostErrorInfo(JNIEnv *env, jclass clazz) { const PaHostErrorInfo *inf = Pa_GetLastHostErrorInfo(); return inf ? toHostErrorInfo(env, inf) : 0; }