static int _bmo_pa_process_cb( const void *ins, void *outs, unsigned long _frames, const PaStreamCallbackTimeInfo *time_info, PaStreamCallbackFlags status_flags, void *data ) { (void)ins; // TODO (void)time_info; // TODO (void)status_flags; // TODO uint32_t frames = (uint32_t)_frames; float **outputs = outs; assert(frames < UINT32_MAX); BMO_state_t *state = (BMO_state_t *)data; if (bmo_status(state) == BMO_DSP_STOPPED) { bmo_info("Audio process quit detected\n"); bmo_zero_mb(outputs, state->n_playback_ch, frames); bmo_driver_callback_done(state, BMO_DSP_STOPPED); return paComplete; } else if (bmo_status(state) == BMO_DSP_RUNNING) { uint32_t frames_read = bmo_read_rb(state->ringbuffer, outputs, frames); if (frames_read != frames) { double xrun = (double)frames - frames_read; bmo_err("an xrun of %f frames occurred\n", xrun); } } state->dsp_load = (float)Pa_GetStreamCpuLoad(state->driver.pa.stream); bmo_driver_callback_done(state, BMO_DSP_RUNNING); return paContinue; }
int perform(const void *inputBuffer, void *outputBuffer, unsigned long frames, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags) { if (unlikely(!callback_initialized)) { engine_functor::init_thread(); engine_functor::sync_clock(); callback_initialized = true; } if (statusFlags & (paInputOverflow | paInputUnderflow | paOutputOverflow | paOutputUnderflow)) engine_functor::sync_clock(); const float * inputs[input_channels]; float * const *in = static_cast<float * const *>(inputBuffer); for (uint16_t i = 0; i != input_channels; ++i) inputs[i] = in[i]; float * outputs[output_channels]; float **out = static_cast<float **>(outputBuffer); for (uint16_t i = 0; i != output_channels; ++i) outputs[i] = out[i]; unsigned long processed = 0; while (processed != frames) { super::fetch_inputs(inputs, blocksize_, input_channels); engine_functor::run_tick(); super::deliver_outputs(outputs, blocksize_, output_channels); processed += blocksize_; } cpu_time_accumulator.update(Pa_GetStreamCpuLoad(stream) * 100.0); return paContinue; }
PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude ) { PaStream* stream; PaStreamParameters outputParameters; PaError err; data->left_phase = data->right_phase = 0; data->amplitude = amplitude; err = Pa_Initialize(); if (err != paNoError) goto done; 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.hostApiSpecificStreamInfo = NULL; outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */ /* When you change this, also */ /* adapt the callback routine! */ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device ) ->defaultLowOutputLatency; /* Low latency. */ err = Pa_OpenStream( &stream, NULL, /* No input. */ &outputParameters, SAMPLE_RATE, 1024, /* frames per buffer */ flags, sineCallback, (void*)data ); if (err != paNoError) goto done; err = Pa_StartStream( stream ); if (err != paNoError) goto done; Pa_Sleep( NUM_SECONDS * 1000 ); printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad(stream)); err = Pa_CloseStream( stream ); done: Pa_Sleep( 250 ); /* Just a small silence. */ Pa_Terminate(); return err; }
static int pa_stream_cpuload(lua_State *L) { pa_Stream *stream = NULL; int narg = lua_gettop(L); if(narg == 1 && luaT_isudata(L, 1, "pa.Stream")) stream = luaT_toudata(L, 1, "pa.Stream"); else luaL_error(L, "expected arguments: Stream"); if(!stream->id) luaL_error(L, "attempt to operate on a closed stream"); lua_pushnumber(L, Pa_GetStreamCpuLoad(stream->id)); return 1; }
PaError PlaySine( paTestData *data, unsigned long flags, float amplitude ) { PaStreamParameters outputParameters; PaStream *stream; PaError err; data->left_phase = data->right_phase = 0; data->amplitude = amplitude; err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto error; } 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, NULL, /* no input */ &outputParameters, SAMPLE_RATE, 1024, flags, sineCallback, data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; Pa_Sleep( NUM_SECONDS * 1000 ); printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad( stream ) ); err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); return paNoError; error: return err; }
/*-----------------------------------------------------------------------------------------*/ static int TestBadActions( void ) { PaStream* stream = NULL; PaError result; PaQaData myData; PaStreamParameters opp; const PaDeviceInfo* info = NULL; /* Setup data for synthesis thread. */ myData.framesLeft = (unsigned long)(SAMPLE_RATE * 100); /* 100 seconds */ myData.numChannels = 1; myData.mode = MODE_OUTPUT; opp.device = Pa_GetDefaultOutputDevice(); /* Default output. */ opp.channelCount = 2; /* Stereo output. */ opp.hostApiSpecificStreamInfo = NULL; opp.sampleFormat = paFloat32; info = Pa_GetDeviceInfo(opp.device); opp.suggestedLatency = info ? info->defaultLowOutputLatency : 0.100; if (opp.device != paNoDevice) { HOPEFOR(((result = Pa_OpenStream(&stream, NULL, /* Take NULL as input parame- */ &opp, /* ters, meaning try only output. */ SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, QaCallback, &myData )) == paNoError)); } HOPEFOR(((result = Pa_StartStream(NULL)) == paBadStreamPtr)); HOPEFOR(((result = Pa_StopStream(NULL)) == paBadStreamPtr)); HOPEFOR(((result = Pa_IsStreamStopped(NULL)) == paBadStreamPtr)); HOPEFOR(((result = Pa_IsStreamActive(NULL)) == paBadStreamPtr)); HOPEFOR(((result = Pa_CloseStream(NULL)) == paBadStreamPtr)); HOPEFOR(((result = Pa_SetStreamFinishedCallback(NULL, NULL)) == paBadStreamPtr)); HOPEFOR(((result = !Pa_GetStreamInfo(NULL)))); HOPEFOR(((result = Pa_GetStreamTime(NULL)) == 0.0)); HOPEFOR(((result = Pa_GetStreamCpuLoad(NULL)) == 0.0)); HOPEFOR(((result = Pa_ReadStream(NULL, NULL, 0)) == paBadStreamPtr)); HOPEFOR(((result = Pa_WriteStream(NULL, NULL, 0)) == paBadStreamPtr)); /** @todo test Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable */ if (stream != NULL) Pa_CloseStream(stream); return result; }
int main(void) { PaStreamParameters outputParameters; PaStream *stream; PaError err; int safeSineCount, stressedSineCount; int safeUnderflowCount, stressedUnderflowCount; paTestData data = {0}; double load; printf("PortAudio Test: output sine waves, count underflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n", SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD ); err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ outputParameters.channelCount = 1; /* mono output */ outputParameters.sampleFormat = paFloat32; /* 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, FRAMES_PER_BUFFER, paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, &data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Establishing load conditions...\n" ); /* Determine number of sines required to get to 50% */ do { data.sineCount++; Pa_Sleep( 100 ); load = Pa_GetStreamCpuLoad( stream ); printf("sineCount = %d, CPU load = %f\n", data.sineCount, load ); } while( load < 0.5 && data.sineCount < (MAX_SINES-1)); safeSineCount = data.sineCount; /* Calculate target stress value then ramp up to that level*/ stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD ); if( stressedSineCount > MAX_SINES ) stressedSineCount = MAX_SINES; for( ; data.sineCount < stressedSineCount; data.sineCount++ ) { Pa_Sleep( 100 ); load = Pa_GetStreamCpuLoad( stream ); printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load ); } printf("Counting underflows for 5 seconds.\n"); data.countUnderflows = 1; Pa_Sleep( 5000 ); stressedUnderflowCount = data.outputUnderflowCount; data.countUnderflows = 0; data.sineCount = safeSineCount; printf("Resuming safe load...\n"); Pa_Sleep( 1500 ); data.outputUnderflowCount = 0; Pa_Sleep( 1500 ); load = Pa_GetStreamCpuLoad( stream ); printf("sineCount = %d, CPU load = %f\n", data.sineCount, load ); printf("Counting underflows for 5 seconds.\n"); data.countUnderflows = 1; Pa_Sleep( 5000 ); safeUnderflowCount = data.outputUnderflowCount; printf("Stop stream.\n"); err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); if( stressedUnderflowCount == 0 ) printf("Test failed, no output underflows detected under stress.\n"); else if( safeUnderflowCount != 0 ) printf("Test failed, %d unexpected underflows detected under safe load.\n", safeUnderflowCount); else printf("Test passed, %d expected output underflows detected under stress, 0 unexpected underflows detected under safe load.\n", stressedUnderflowCount ); return err; 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 ) ); return err; }
int main(void) { PaStreamParameters outputParameters; PaStream *stream; PaError err; int numStress; paTestData data = {0}; double load; printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n", SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD ); err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto error; } outputParameters.channelCount = 1; /* mono output */ outputParameters.sampleFormat = paFloat32; /* 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, FRAMES_PER_BUFFER, paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, &data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; /* Determine number of sines required to get to 50% */ do { data.numSines++; Pa_Sleep( 100 ); load = Pa_GetStreamCpuLoad( stream ); printf("numSines = %d, CPU load = %f\n", data.numSines, load ); } while( load < 0.5 ); /* Calculate target stress value then ramp up to that level*/ numStress = (int) (2.0 * data.numSines * MAX_LOAD ); for( ; data.numSines < numStress; data.numSines++ ) { Pa_Sleep( 200 ); load = Pa_GetStreamCpuLoad( stream ); printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load ); } printf("Suffer for 5 seconds.\n"); Pa_Sleep( 5000 ); printf("Stop stream.\n"); err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); printf("Test finished.\n"); return err; 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 ) ); return err; }
double AudioIO::cpu() const { return Pa_GetStreamCpuLoad(mImpl->mStream); }
int main(void) { int i; PaStream* stream; PaStreamParameters outputParameters; PaError err; paTestData data = {0}; double load; printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */ err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto error; } outputParameters.channelCount = 2; /* Stereo output. */ outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */ outputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device) ->defaultHighOutputLatency; err = Pa_OpenStream(&stream, NULL, /* no input */ &outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, /* No out of range samples should occur. */ patestCallback, &data); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; /* Play an increasing number of sine waves until we hit MAX_USAGE */ do { data.numSines++; Pa_Sleep(200); load = Pa_GetStreamCpuLoad(stream); printf("numSines = %d, CPU load = %f\n", data.numSines, load ); fflush(stdout); } while((load < MAX_USAGE) && (data.numSines < MAX_SINES)); Pa_Sleep(2000); /* Stay for 2 seconds around 80% CPU. */ err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); printf("Test finished.\n"); return err; 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 ) ); return err; }
_CGUL_EXPORT double CGUL::PortAudio::Stream::GetCpuLoad() { return (double)Pa_GetStreamCpuLoad(stream); }
_JATTA_EXPORT double Jatta::PortAudio::Stream::GetCpuLoad() { return (double)Pa_GetStreamCpuLoad(stream); }
JNIEXPORT jdouble JNICALL Java_org_jpab_PortAudio_getStreamCpuLoad(JNIEnv *env, jclass paClass, jlong stream_id) { return Pa_GetStreamCpuLoad((PaStream *) stream_id); }
double PortAudioHelper::getCpuUsage() const { return Pa_GetStreamCpuLoad(stream); }
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 ); }
double AudioDevice_cpuLoad(AudioDevice *self) { return AudioDevice_isOpen(self) ? Pa_GetStreamCpuLoad( self->stream ) : 0; }
JNIEXPORT jdouble JNICALL Java_com_github_rjeschke_jpa_JPA_paGetStreamCpuLoad(JNIEnv *env, jclass clazz, jlong jPtr) { JPA_DATA *j = (JPA_DATA*)long2Ptr(jPtr); return (jdouble)Pa_GetStreamCpuLoad(j->stream); }