int jtaudio_(int *ndevin, int *ndevout, short y1[], short y2[], int *nbuflen, int *iwrite, short iwave[], int *nwave, int *nfsample, int *nsamperbuf, int *TRPeriod, int *TxOK, int *ndebug, int *Transmitting, double *Tsec, int *ngo, int *nmode, double tbuf[], int *ibuf, int *ndsec) { paTestData data; PaStream *outstream; PaStreamParameters outputParameters; int nfs,ndin,ndout; PaError err1,err2,err2a,err3,err3a; double dnfs; data.Tsec = Tsec; data.tbuf = tbuf; data.iwrite = iwrite; data.ibuf = ibuf; data.TxOK = TxOK; data.ndebug = ndebug; data.ndsec = ndsec; data.Transmitting = Transmitting; data.y1 = y1; data.y2 = y2; data.nbuflen = *nbuflen; data.nmode = nmode; data.nwave = nwave; data.iwave = iwave; data.nfs = *nfsample; data.trperiod = TRPeriod; nfs=*nfsample; err1=Pa_Initialize(); // Initialize PortAudio if(err1) { printf("Error initializing PortAudio.\n"); printf("%s\n",Pa_GetErrorText(err1)); goto error; } ndin=*ndevin; ndout=*ndevout; dnfs=(double)nfs; printf("Opening device %d for output.\n",ndout); outputParameters.device=*ndevout; outputParameters.channelCount=2; outputParameters.sampleFormat=paInt16; outputParameters.suggestedLatency=1.0; outputParameters.hostApiSpecificStreamInfo=NULL; err2a=Pa_OpenStream( &outstream, //address of stream NULL, &outputParameters, dnfs, //Sample rate 2048, //Frames per buffer paNoFlag, SoundOut, //Callback routine &data); //address of data structure if(err2a) { printf("Error opening Audio stream for output.\n"); printf("%s\n",Pa_GetErrorText(err2a)); goto error; } err3a=Pa_StartStream(outstream); //Start output stream if(err3a) { printf("Error starting output Audio stream\n"); printf("%s\n",Pa_GetErrorText(err3a)); goto error; } printf("Audio output stream running normally.\n******************************************************************\n"); while(Pa_IsStreamActive(outstream)) { if(*ngo==0) goto StopStream; Pa_Sleep(200); } StopStream: Pa_AbortStream(outstream); // Abort stream Pa_CloseStream(outstream); // Close stream, we're done. Pa_Terminate(); return(0); error: printf("%d %f %d %d %d\n",ndout,dnfs,err1,err2a,err3a); Pa_Terminate(); return(1); }
int main(void) { // PortAudioStream *stream; // int inputDevice = Pa_GetDefaultInputDeviceID(); // int i,numDevices; // PaDeviceInfo pdi; // printf("Channel data acquisition configuration test\n"); // printf("\n"); fflush(stdout); // numDevices = Pa_CountDevices(); // printf( "Number of total devices : Pa_CountDevices()\t: %d.\n", numDevices ); // for( i=0; i<numDevices; i++ ) { // pdi = *Pa_GetDeviceInfo( i ); // printf("Device(%d) name \t: %s.\n", i, pdi.name); // printf("\tMax Inputs = %d\n", pdi.maxInputChannels ); // printf("\tMax Outputs = %d\n", pdi.maxOutputChannels ); // } // printf("Default Devic id : %d.\n", Pa_GetDefaultInputDeviceID() ); int i,numDevices; PaDeviceInfo pdi; PaError err; err = Pa_Initialize(); if( err != paNoError ) goto error; numDevices = Pa_CountDevices(); printf( "Number of total devices : Pa_CountDevices()\t: %d.\n", numDevices ); for( i=0; i<numDevices; i++ ) { pdi = *Pa_GetDeviceInfo( i ); printf("Device(%d) name \t: %s.\n", i, pdi.name); printf("\tMax Inputs = %d\n", pdi.maxInputChannels ); printf("\tMax Outputs = %d\n", pdi.maxOutputChannels ); } printf("Default Devic id : %d.\n", Pa_GetDefaultInputDeviceID() ); Pa_Terminate(); printf("\n"); audio_rc_open(); printf("\nNow display channel acquisition 0 up to 9 during 10seconds!!\n"); fflush(stdout); for( i=0; i<100; i++ ) { Pa_Sleep(100); /* launch test */ audio_rc_test(); fflush(stdout); } audio_rc_close(); return 0; 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 -1; }
int main(int argc, char* argv[]) { PaStreamParameters outputParameters; PaWinMmeStreamInfo wmmeStreamInfo; PaStream *stream; PaError err; paTestData data; int i; int deviceIndex; printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT); err = Pa_Initialize(); if( err != paNoError ) goto error; deviceIndex = Pa_GetDefaultOutputDevice(); if( argc == 2 ){ sscanf( argv[1], "%d", &deviceIndex ); } printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name ); /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } data.phase = 0; data.currentChannel = 0; data.cycleCount = 0; outputParameters.device = deviceIndex; outputParameters.channelCount = CHANNEL_COUNT; outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; /* it's not strictly necessary to provide a channelMask for surround sound output. But if you want to be sure which channel mask PortAudio will use then you should supply one */ wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo); wmmeStreamInfo.hostApiType = paMME; wmmeStreamInfo.version = 1; wmmeStreamInfo.flags = paWinMmeUseChannelMask; wmmeStreamInfo.channelMask = PAWIN_SPEAKER_5POINT1_SURROUND; /* request 5.1 output format */ outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo; if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){ printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT ); }else{ printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT ); } 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("Play for %d seconds.\n", NUM_SECONDS ); Pa_Sleep( NUM_SECONDS * 1000 ); 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; }
PaError WriteStream( PaStream* stream, const void *buffer, unsigned long framesRequested ) { PaMacCoreStream *macStream = (PaMacCoreStream*)stream; PaMacBlio *blio = &macStream->blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("WriteStream()\n")); while( framesRequested > 0 && macStream->state != STOPPING ) { ring_buffer_size_t framesAvailable; ring_buffer_size_t framesToTransfer; ring_buffer_size_t framesTransferred; do { framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); /* printf( "Write Buffer is %%%g full: %ld of %ld.\n", 100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize, framesAvailable, blio->outputRingBuffer.bufferSize ); */ if( framesAvailable == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /*block while full*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( ret ) return ret; while( blio->isOutputFull ) { ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( framesAvailable == 0 && macStream->state != STOPPING ); if( macStream->state == STOPPING ) { break; } framesToTransfer = MIN( framesAvailable, framesRequested ); framesTransferred = PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, framesToTransfer ); cbuf += framesTransferred * blio->outputSampleSizeActual * blio->outChan; framesRequested -= framesTransferred; #ifdef PA_MAC_BLIO_MUTEX if( framesToTransfer == framesAvailable ) { /* we just filled up the buffer, so we need to mark it as filled. */ ret = blioSetIsOutputFull( blio, true ); if( ret ) return ret; /* of course, in the meantime, we may have emptied the buffer, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) { blioSetIsOutputFull( blio, false ); /* FIXME remove or review this code, does not fix race, ret not set! */ if( ret ) return ret; } } #endif } if ( macStream->state == STOPPING ) { ret = paInternalError; } else if (ret == paNoError ) { /* Test for underflow. */ ret = blio->statusFlags & paOutputUnderflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags ); ret = paOutputUnderflowed; } } return ret; }
int main(void) { //printf("InfiniteLooper--based on patest_record.c\n"); //fflush(stdout); //Record for a few seconds. data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; data.frameIndex = 0; numSamples = totalFrames * NUM_CHANNELS; numBytes = numSamples * sizeof(SAMPLE); // From now on, recordedSamples is initialised. // 5 minutes of record buffer allocated 5% of free // on rPi zero. could record 90 minutes on rPi 0 //++++++++++++++++++++++++++++++++++++++++++++++++++++ data.recordedSamples = (SAMPLE*) malloc( numBytes ); //++++++++++++++++++++++++++++++++++++++++++++++++++++ if( data.recordedSamples == NULL ) { //printf("Could not allocate record array.\n"); goto done; } else { //printf("allocated %d bytes\n", numBytes ); } ringbufferWPTR = 0; ringbufferRPTR = 0; all_complete = FALSE; // ****************************************** doState(S_INIT, data.recordedSamples); // ****************************************** // we do the recording set-up just once and cycle power // to do it again. This initialization should be moved to // ilooper_audio if multiple recordings are implemented err = Pa_Initialize(); if( err != paNoError ) goto done; // default input device inputParameters.device = Pa_GetDefaultInputDevice(); if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default input device.\n"); goto done; } inputParameters.channelCount = 2; //stereo input inputParameters.sampleFormat = PA_SAMPLE_TYPE; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; //Record some audio. -------------------------------------------- err = Pa_OpenStream ( &stream, &inputParameters, NULL, // &outputParameters, SAMPLE_RATE, // ADC sample rate is a constant FRAMES_PER_BUFFER, //we won't output out of range samples so //don't bother clipping them //paClipOff, // ***wm6h for this app, let's clip paNoFlag, recordCallback, &data ); if( err != paNoError ) goto done; // the output sample rate is checked in playback() err = Pa_IsFormatSupported( &inputParameters, NULL, SAMPLE_RATE ); if( err == paFormatIsSupported ) { //printf("\n ADC samplerate is supported %d, FPB %d\n", \ // SAMPLE_RATE, FRAMES_PER_BUFFER); } else { //printf("\n ADC samplerate is NOT supported\n"); goto done; } //printf(" %s\n", Pa_GetVersionText()); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //GPIO-0 access for Green LED and test //rPi J8-11 and gnd J8-6 if(wiringPiSetup () < 0 ) { fprintf(stderr, "Unable to setup wiringPi: %s\n", strerror(errno)); return 1; } pinMode (LED_PIN, OUTPUT) ; digitalWrite (LED_PIN, OFF) ; pinMode (BUTTON_PIN, INPUT) ; //pullUpDnControl(BUTTON_PIN, PUD_OFF); pullUpDnControl(BUTTON_PIN, PUD_UP); pinMode (DIRECTION_PIN, INPUT) ; pullUpDnControl(DIRECTION_PIN, PUD_UP); pinMode (REBOOT_PIN, INPUT) ; pullUpDnControl(REBOOT_PIN, PUD_UP); pinMode (ERROR_PIN, OUTPUT) ; digitalWrite (ERROR_PIN, OFF) ; sync(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // underway--shift ship's colors--all ahead 8K sps // err = Pa_StartStream( stream ); if( err != paNoError ) goto done; // ============================================================================= // ============================================================================= // collecting samples phase // ****************************************** doState(S_COLLECTING, data.recordedSamples); // ****************************************** // we are running the callbacks while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) { Pa_Sleep(500); if(buttonPress == TRUE) { Pa_Sleep(100); all_complete = TRUE; //stop the sample interrupt, exit while loop } else { // no button press // give the state machine a chance to run // ****************************************** doState(currentSTATE, (void*) NULL); // ****************************************** } } // ============================================================================= // ============================================================================= if( err < 0 ) goto done; // all stop err = Pa_CloseStream( stream ); if( err != paNoError ) goto done; buttonValue = digitalRead(BUTTON_PIN); //printf("button = %d\n", buttonValue); if(buttonValue == 0) { //if button still pressed, it's a hold buttonHold = TRUE; //printf("button hold\n"); //fflush(stdout); } else { //else, it's a button press buttonPress = FALSE; //acknowledged, reset flag //printf("button pressed\n"); //fflush(stdout); } // Measure maximum peak amplitude. // we could indicate over-driving/clipping the audio // or AGC it max = 0; average = 0.0; for( i=0; i<numSamples; i++ ) { val = data.recordedSamples[i]; if( val < 0 ) val = -val; // ABS if( val > max ) { max = val; } average += val; } average = average / (double)numSamples; //printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max ); //printf("sample average = %lf\n", average ); // Write recorded data to a file. #if WRITE_TO_FILE { // the file size should be 5 minutes of 8K samples * 2 // the entire ring buffer is recorded without regard to the // read/write pointers. Make sense of the file by editing it in // Audacity // todo: write the file in correct time order using rd/wr pointers FILE *fid; fid = fopen("recorded.raw", "wb"); if( fid == NULL ) { //printf("Could not open file."); } else { fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid ); fclose( fid ); //printf("Wrote data to 'recorded.raw'\n"); } } #endif // initial state after recording // all future state changes from within state machine if(buttonHold == FALSE) { // ****************************************** doState(S_REWIND_10, (void*) NULL); // ****************************************** } else { // ****************************************** doState(S_REWIND_PLAYBACK, (void*) NULL); // ****************************************** } // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| while (1) { // advance state in the state machine // ****************************************** doState(currentSTATE, (void*) NULL); // ****************************************** Pa_Sleep(100); if(terminate != FALSE) goto done; } // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| done: Pa_Terminate(); if( data.recordedSamples ) // Sure it is NULL or valid. free( data.recordedSamples ); if( err != paNoError ) { 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 ) ); fatalError(); err = 1; // Always return 0 or 1, but no other return codes. } return err; }
int main(void) { PaStreamParameters outputParameters; PaStream *stream; PaError err; TestData data; int i, j; 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. ); } err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); 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, FRAMES_PER_BUFFER, paClipOff, /* output will be in-range, so no need to clip */ TestCallback, &data ); if( err != paNoError ) goto error; printf("Repeating test %d times.\n", NUM_LOOPS ); for( i=0; i < NUM_LOOPS; ++i ) { data.phase = 0; data.generatedFramesCount = 0; data.callbackReturnedPaComplete = 0; data.callbackInvokedAfterReturningPaComplete = 0; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Play for %d seconds.\n", NUM_SECONDS ); /* wait for the callback to complete generating NUM_SECONDS of tone */ do { Pa_Sleep( 500 ); } while( !data.callbackReturnedPaComplete ); printf( "Callback returned paComplete.\n" ); printf( "Waiting for buffers to finish playing...\n" ); /* wait for stream to become inactive, or for a timeout of approximately NUM_SECONDS */ j = 0; while( (err = Pa_IsStreamActive( stream )) == 1 && j < NUM_SECONDS * 2 ) { printf(".\n" ); Pa_Sleep( 500 ); ++j; } if( err < 0 ) { goto error; } else if( err == 1 ) { printf( "TEST FAILED: Timed out waiting for buffers to finish playing.\n" ); } else { printf("Buffers finished.\n" ); } if( data.callbackInvokedAfterReturningPaComplete ) { printf( "TEST FAILED: Callback was invoked after returning paComplete.\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; }
PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("WriteStream()\n")); while( frames > 0 ) { long avail = 0; long toWrite; do { avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); /* printf( "Write Buffer is %%%g full: %ld of %ld.\n", 100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize, avail, blio->outputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /*block while full*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( ret ) return ret; while( blio->isOutputFull ) { ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toWrite = MIN( avail, frames * blio->outputSampleSizeActual * blio->outChan ); toWrite -= toWrite % blio->outputSampleSizeActual * blio->outChan ; PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, toWrite ); cbuf += toWrite; frames -= toWrite / ( blio->outputSampleSizeActual * blio->outChan ); #ifdef PA_MAC_BLIO_MUTEX if( toWrite == avail ) { /* we just filled up the buffer, so we need to mark it as filled. */ ret = blioSetIsOutputFull( blio, true ); if( ret ) return ret; /* of course, in the meantime, we may have emptied the buffer, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) { blioSetIsOutputFull( blio, false ); if( ret ) return ret; } } #endif } /* Report either paNoError or paOutputUnderflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paOutputUnderflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags ); ret = paOutputUnderflowed; } return ret; }
int main(void) { PaStreamParameters outputParameters; PaStream *stream; PaError err; paTestData data; int i; 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.left_phase = data.right_phase = 0; err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ 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, 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("Play for %d seconds.\n", NUM_SECONDS ); Pa_Sleep( NUM_SECONDS * 1000 ); 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; }
JNIEXPORT void JNICALL Java_com_github_rjeschke_jpa_JPA_sleep(JNIEnv *env, jclass clazz, jlong msec) { Pa_Sleep((long int)msec); }
int main(void) { PortAudioStream *stream; PaError err; mute=false; bool quit; char ch; printf("A sample on how to use RakVoice. You need a microphone for this sample.\n"); printf("RakVoice relies on Speex for voice encoding and decoding.\n"); printf("See DependentExtensions/RakVoice/speex-1.1.12 for speex projects.\n"); printf("For windows, I had to define HAVE_CONFIG_H, include win32/config.h,\n"); printf("and include the files under libspeex, except those that start with test.\n"); printf("PortAudio is also included and is used to read and write audio data. You\n"); printf("can substitute whatever you want if you do not want to use portaudio.\n"); printf("Difficulty: Advanced\n\n"); // Since voice is peer to peer, we give the option to use the nat punchthrough client if desired. RakNet::NatPunchthroughClient natPunchthroughClient; char port[256]; rakPeer = RakNet::RakPeerInterface::GetInstance(); printf("Enter local port (enter for default): "); Gets(port, sizeof(port)); if (port[0]==0) strcpy(port, "60000"); RakNet::SocketDescriptor socketDescriptor(atoi(port),0); rakPeer->Startup(4, &socketDescriptor, 1); rakPeer->SetMaximumIncomingConnections(4); rakPeer->AttachPlugin(&rakVoice); rakPeer->AttachPlugin(&natPunchthroughClient); rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER*sizeof(SAMPLE)); err = Pa_Initialize(); if( err != paNoError ) goto error; err = Pa_OpenStream( &stream, Pa_GetDefaultInputDeviceID(), 1, // Num channels, whatever that means PA_SAMPLE_TYPE, NULL, Pa_GetDefaultOutputDeviceID(), 1, // Num channels PA_SAMPLE_TYPE, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ 0, /* paDitherOff, // flags */ PACallback, 0 ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Support NAT punchthrough? (y/n)? "); bool useNatPunchthrough; useNatPunchthrough=(getche()=='y'); printf("\n"); char facilitatorIP[256]; {//Linux fix. Won't compile without it. Because of the goto error above, the scope is ambigious. Make it a block to define that it will not be used after the jump. //Doesn't change current logic RakNet::SystemAddress facilitator; if (useNatPunchthrough) { printf("My GUID is %s\n", rakPeer->GetGuidFromSystemAddress(RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); printf("Enter IP of facilitator (enter for default): "); Gets(facilitatorIP,sizeof(facilitatorIP)); if (facilitatorIP[0]==0) strcpy(facilitatorIP, "natpunch.jenkinssoftware.com"); facilitator.FromString(facilitatorIP); facilitator.SetPortHostOrder(NAT_PUNCHTHROUGH_FACILITATOR_PORT); rakPeer->Connect(facilitatorIP, NAT_PUNCHTHROUGH_FACILITATOR_PORT, 0, 0); printf("Connecting to facilitator...\n"); } else { printf("Not supporting NAT punchthrough.\n"); } RakNet::Packet *p; quit=false; if (useNatPunchthrough==false) printf("(Q)uit. (C)onnect. (D)isconnect. C(l)ose voice channels. (M)ute. ' ' for stats.\n"); while (!quit) { if (kbhit()) { ch=getch(); if (ch=='y') { quit=true; } else if (ch=='c') { if (useNatPunchthrough) { RakNet::RakNetGUID destination; printf("Enter GUID of destination: "); char guidStr[256]; while (1) { Gets(guidStr,sizeof(guidStr)); if (!destination.FromString(guidStr)) printf("Invalid GUID format. Try again.\nEnter GUID of destination: "); else break; } printf("Starting NAT punch. Please wait...\n"); natPunchthroughClient.OpenNAT(destination,facilitator); } else { char ip[256]; printf("Enter IP of remote system: "); Gets(ip, sizeof(ip)); if (ip[0]==0) strcpy(ip, "127.0.0.1"); printf("Enter port of remote system: "); Gets(port, sizeof(port)); if (port[0]==0) strcpy(port, "60000"); rakPeer->Connect(ip, atoi(port), 0,0); } } else if (ch=='m') { mute=!mute; if (mute) printf("Now muted.\n"); else printf("No longer muted.\n"); } else if (ch=='d') { rakPeer->Shutdown(100,0); } else if (ch=='l') { rakVoice.CloseAllChannels(); } else if (ch==' ') { char message[2048]; RakNet::RakNetStatistics *rss=rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0)); StatisticsToString(rss, message, 2); printf("%s", message); } else if (ch=='q') quit=true; ch=0; } p=rakPeer->Receive(); while (p) { if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { if (p->systemAddress==facilitator) { printf("Connection to facilitator completed\n"); printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n"); } else { printf("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString()); rakVoice.RequestVoiceChannel(p->guid); } } else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED) { if (p->systemAddress==facilitator) { printf("Connection to facilitator failed. Using direct connections\n"); useNatPunchthrough=false; printf("(Q)uit. (C)onnect. (D)isconnect. (M)ute. ' ' for stats.\n"); } else { printf("ID_CONNECTION_ATTEMPT_FAILED\n"); } } else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST || p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY) { printf("Got new channel from %s\n", p->systemAddress.ToString()); } else if (p->data[0]==ID_NAT_TARGET_NOT_CONNECTED) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_TARGET_NOT_CONNECTED for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_TARGET_UNRESPONSIVE) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_TARGET_UNRESPONSIVE for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_CONNECTION_TO_TARGET_LOST for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_ALREADY_IN_PROGRESS) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); printf("ID_NAT_ALREADY_IN_PROGRESS for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_FAILED) { printf("ID_NAT_PUNCHTHROUGH_FAILED for %s\n", p->guid.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_SUCCEEDED) { printf("ID_NAT_PUNCHTHROUGH_SUCCEEDED for %s. Connecting...\n", p->guid.ToString()); rakPeer->Connect(p->systemAddress.ToString(false),p->systemAddress.GetPort(),0,0); } else if (p->data[0]==ID_ALREADY_CONNECTED) { printf("ID_ALREADY_CONNECTED\n"); } else if (p->data[0]==ID_RAKVOICE_CLOSE_CHANNEL) { printf("ID_RAKVOICE_CLOSE_CHANNEL\n"); } else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION) { printf("ID_DISCONNECTION_NOTIFICATION\n"); } else if (p->data[0]==ID_NEW_INCOMING_CONNECTION) { printf("ID_NEW_INCOMING_CONNECTION\n"); } else { printf("Unknown packet ID %i\n", p->data[0]); } rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); } Pa_Sleep( 30 ); } } err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); rakPeer->Shutdown(300); RakNet::RakPeerInterface::DestroyInstance(rakPeer); return 0; 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 -1; }
int audioPlayRec( int playdevID, SAMPLE * playbuffer, int playbuflen, int playbuffirstchannel, int playbuflastchannel, int recdevID, SAMPLE * recbuffer, int recbuflen, int recbuffirstchannel, int recbuflastchannel, char * recCallbackName, int samplerate ) { paAudioData audio; mxArray * precRingArray = NULL; audio.recMode = PLAYREC_NONE; audio.playBuffer = NULL; audio.playBufLen = 0; audio.playBufPos = 0; audio.playFirstChannel = 0; audio.playChannels = 0; audio.playDevChannels = 0; audio.recBuffer = NULL; audio.recBufLen = 0; audio.recBufWritePos = 0; audio.recBufReadPos = 0; audio.recFirstChannel = 0; audio.recChannels = 0; audio.recDevChannels = 0; if( playdevID != paNoDevice && playbuffer != NULL && playbuflen > 0 && playbuffirstchannel >= 0 && playbuflastchannel >= playbuffirstchannel ) { int playChannels = playbuflastchannel - playbuffirstchannel + 1; audio.recMode |= PLAYREC_PLAY; audio.playBuffer = playbuffer; audio.playBufLen = playbuflen / playChannels; // just only one channel samples audio.playFirstChannel = playbuffirstchannel; audio.playChannels = playChannels; } if( recdevID != paNoDevice && playbuffirstchannel >= 0 && recbuflastchannel >= recbuffirstchannel ) { int recChannels = recbuflastchannel - recbuffirstchannel + 1; if( recbuffer != NULL && recbuflen > 0 ) { audio.recMode |= PLAYREC_REC; audio.recBuffer = recbuffer; audio.recBufLen = recbuflen / recChannels; // just only one channel samples audio.recFirstChannel = recbuffirstchannel; audio.recChannels = recChannels; } else if( recCallbackName != NULL ) { int recBufferLength = samplerate * 2; // 2 seconds ring buffer precRingArray = mxCreateNumericMatrix( recBufferLength, recChannels, SAMPLE_CLASSID, mxREAL ); SAMPLE * recBuf = (SAMPLE *)mxGetData( precRingArray ); if( recBuf != NULL ) { audio.recMode |= PLAYREC_REC; audio.recBuffer = recBuf; audio.recBufLen = recBufferLength; // just only one channel samples audio.recFirstChannel = recbuffirstchannel; audio.recChannels = recChannels; } } } if( audio.recMode == PLAYREC_NONE ) { errorPrintf( ( "Playback and Recording parameters is wrong!\n" ) ); return paNoError; } PaStreamParameters inputParameters, outputParameters; PaStreamParameters *pinputParameters, *poutputParameters; PaStream *stream; PaError err; err = Pa_Initialize(); if( err != paNoError ) goto error; if( audio.recMode & PLAYREC_PLAY ) { poutputParameters = &outputParameters; outputParameters.device = playdevID; outputParameters.channelCount = Pa_GetDeviceInfo( outputParameters.device )->maxOutputChannels; outputParameters.sampleFormat = SAMPLE_FORMAT; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; audio.playDevChannels = outputParameters.channelCount; } else poutputParameters = NULL; if( audio.recMode & PLAYREC_REC ) { pinputParameters = &inputParameters; inputParameters.device = recdevID; inputParameters.channelCount = Pa_GetDeviceInfo( inputParameters.device )->maxInputChannels; inputParameters.sampleFormat = SAMPLE_FORMAT; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; audio.recDevChannels = inputParameters.channelCount; } else pinputParameters = NULL; err = Pa_OpenStream( &stream, pinputParameters, poutputParameters, samplerate, FRAMES_PER_BUFFER, paNoFlag, paCallback, &audio ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) { if( recCallbackName != NULL ) { bool stop = false; while( getRecDataLen( &audio ) >= FRAMES_PER_BUFFER ) // recording data is more than FRAMES_PER_BUFFER { mxArray * pdataArray = mxCreateNumericMatrix( FRAMES_PER_BUFFER, audio.recChannels, SAMPLE_CLASSID, mxREAL ); mxArray * presultArray = NULL; SAMPLE * dataBuf = (SAMPLE *)mxGetData( pdataArray ); if( dataBuf != NULL ) { for( int index = 0; index < FRAMES_PER_BUFFER; index++ ) // frame { for( int channel = 0; channel < audio.recChannels; channel++ ) // channel { *(dataBuf + FRAMES_PER_BUFFER * channel + index) = *(audio.recBuffer + audio.recBufLen * channel + audio.recBufReadPos); } if( nextReadPos( &audio ) == -1 ) break; } mexCallMATLAB( 1, &presultArray, 1, &pdataArray, recCallbackName ); if( !mxIsDouble( presultArray ) || mxGetPr( presultArray ) == NULL || ((int)*mxGetPr( presultArray )) != 0 ) // return 0 should be continue, others should be stop stop = true; } if( presultArray != NULL ) mxDestroyArray( presultArray ); if( pdataArray != NULL ) mxDestroyArray( pdataArray ); if( stop ) break; // recording stop } if( stop ) break; // recording stop Pa_Sleep( (FRAMES_PER_BUFFER * 1000) / samplerate ); } else Pa_Sleep( 50 ); } if( err < 0 ) goto error; err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); if( precRingArray != NULL ) mxDestroyArray( precRingArray ); return err; error: Pa_Terminate(); errorPrintf( ( "Error number: %d\n", err ) ); errorPrintf( ( "Error message: %s\n", Pa_GetErrorText(err) ) ); if( precRingArray != NULL ) mxDestroyArray( precRingArray ); return err; }
int main(void) { PaError err; PortAudioStream *stream1; PortAudioStream *stream2; paTestData data1 = {0}; paTestData data2 = {0}; printf("PortAudio Test: two rates.\n" ); err = Pa_Initialize(); if( err != paNoError ) goto error; /* Start first stream. **********************/ err = Pa_OpenStream( &stream1, paNoDevice, /* default input device */ 0, /* no input */ paFloat32, /* 32 bit floating point input */ NULL, OUTPUT_DEVICE, 2, /* Stereo */ paFloat32, /* 32 bit floating point output */ NULL, SAMPLE_RATE_1, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, &data1 ); if( err != paNoError ) goto error; err = Pa_StartStream( stream1 ); if( err != paNoError ) goto error; Pa_Sleep( 3 * 1000 ); /* Start second stream. **********************/ err = Pa_OpenStream( &stream2, paNoDevice, /* default input device */ 0, /* no input */ paFloat32, /* 32 bit floating point input */ NULL, OUTPUT_DEVICE, 2, /* Stereo */ paFloat32, /* 32 bit floating point output */ NULL, SAMPLE_RATE_2, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ paClipOff, /* we won't output out of range samples so don't bother clipping them */ patestCallback, &data2 ); if( err != paNoError ) goto error; err = Pa_StartStream( stream2 ); if( err != paNoError ) goto error; Pa_Sleep( 3 * 1000 ); err = Pa_StopStream( stream2 ); if( err != paNoError ) goto error; Pa_Sleep( 3 * 1000 ); err = Pa_StopStream( stream1 ); if( err != paNoError ) goto error; Pa_CloseStream( stream2 ); Pa_CloseStream( stream1 ); 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; }
int main(void) { PortAudioStream *stream; PaError err; paTestData data; int i; int timeout; printf("Play different tone sine waves that alternate between left and right channel.\n"); printf("The low tone should be on the left channel.\n"); /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } data.left_phase = data.right_phase = data.toggle = 0; data.countDown = SAMPLE_RATE; err = Pa_Initialize(); if( err != paNoError ) goto error; err = Pa_OpenStream( &stream, paNoDevice,/* default input device */ 0, /* no input */ paFloat32, /* 32 bit floating point input */ NULL, Pa_GetDefaultOutputDeviceID(), /* default output device */ 2, /* stereo output */ paFloat32, /* 32 bit floating point output */ NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ 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("Play for several seconds.\n"); timeout = NUM_SECONDS * 4; while( timeout > 0 ) { Pa_Sleep( 300 ); timeout -= 1; } 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; }
int main(void) { PaStreamParameters outputParameters; PaStream *stream; PaError err; TestData data; float writeBuffer[ FRAMES_PER_BUFFER * 2 ]; printf("PortAudio Test: check that stopping stream plays out all queued samples. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); InitTestSignalGenerator( &data ); err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ outputParameters.channelCount = 2; /* stereo output */ outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; /* test paComplete ---------------------------------------------------------- */ ResetTestSignalGenerator( &data ); 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 */ TestCallback1, &data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("\nPlaying 'tone-blip' %d times using callback, stops by returning paComplete from callback.\n", NUM_REPEATS ); printf("If final blip is not intact, callback+paComplete implementation may be faulty.\n\n" ); while( (err = Pa_IsStreamActive( stream )) == 1 ) Pa_Sleep( 5 ); if( err != 0 ) goto error; err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Sleep( 500 ); /* test Pa_StopStream() with callback --------------------------------------- */ ResetTestSignalGenerator( &data ); testCallback2Finished = 0; 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 */ TestCallback2, &data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("\nPlaying 'tone-blip' %d times using callback, stops by calling Pa_StopStream.\n", NUM_REPEATS ); printf("If final blip is not intact, callback+Pa_StopStream implementation may be faulty.\n\n" ); /* note that polling a volatile flag is not a good way to synchronise with the callback, but it's the best we can do portably. */ while( !testCallback2Finished ) Pa_Sleep( 2 ); err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Sleep( 500 ); /* test Pa_StopStream() with Pa_WriteStream --------------------------------- */ ResetTestSignalGenerator( &data ); 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 */ NULL, /* no callback, use blocking API */ NULL ); /* no callback, so no callback userData */ if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("\nPlaying 'tone-blip' %d times using Pa_WriteStream, stops by calling Pa_StopStream.\n", NUM_REPEATS ); printf("If final blip is not intact, Pa_WriteStream+Pa_StopStream implementation may be faulty.\n\n" ); do{ GenerateTestSignal( &data, writeBuffer, FRAMES_PER_BUFFER ); err = Pa_WriteStream( stream, writeBuffer, FRAMES_PER_BUFFER ); if( err != paNoError ) goto error; }while( !IsTestSignalFinished( &data ) ); 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; }
int main(void) { PortAudioStream *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; err = Pa_OpenStream( &stream, paNoDevice,/* default input device */ 0, /* no input */ paFloat32, /* 32 bit floating point input */ NULL, Pa_GetDefaultOutputDeviceID(), /* default output device */ 1, /* mono output */ paFloat32, /* 32 bit floating point output */ NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ 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_GetCPULoad( 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_GetCPULoad( 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; }
int main(void) { PortAudioStream *stream; PaError err; paTestData data; int i; int totalFrames; int numSamples; int numBytes; SAMPLE max, average, val; printf("patest_record.c\n"); fflush(stdout); data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */ data.frameIndex = 0; numSamples = totalFrames * NUM_CHANNELS; numBytes = numSamples * sizeof(SAMPLE); data.recordedSamples = (SAMPLE *) malloc( numBytes ); if( data.recordedSamples == NULL ) { printf("Could not allocate record array.\n"); exit(1); } for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0; err = Pa_Initialize(); if( err != paNoError ) goto error; /* Record some audio. -------------------------------------------- */ err = Pa_OpenStream( &stream, Pa_GetDefaultInputDeviceID(), NUM_CHANNELS, PA_SAMPLE_TYPE, NULL, paNoDevice, 0, PA_SAMPLE_TYPE, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ 0, /* paDitherOff, // flags */ recordCallback, &data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Now recording!!\n"); fflush(stdout); while( Pa_StreamActive( stream ) ) { Pa_Sleep(1000); printf("index = %d\n", data.frameIndex ); fflush(stdout); } err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; /* Measure maximum peak amplitude. */ max = 0; average = 0; for( i=0; i<numSamples; i++ ) { val = data.recordedSamples[i]; if( val < 0 ) val = -val; /* ABS */ if( val > max ) { max = val; } average += val; } average = average / numSamples; if( PA_SAMPLE_TYPE == paFloat32 ) /* This should be done at compile-time with "#if" ?? */ { /* MIPS-compiler warns at the int-version below. */ printf("sample max amplitude = %f\n", max ); printf("sample average = %f\n", average ); } else { printf("sample max amplitude = %d\n", max ); /* <-- This IS compiled anyhow. */ printf("sample average = %d\n", average ); } /* Write recorded data to a file. */ #if 0 { FILE *fid; fid = fopen("recorded.raw", "wb"); if( fid == NULL ) { printf("Could not open file."); } else { fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid ); fclose( fid ); printf("Wrote data to 'recorded.raw'\n"); } } #endif /* Playback recorded data. -------------------------------------------- */ data.frameIndex = 0; printf("Begin playback.\n"); fflush(stdout); err = Pa_OpenStream( &stream, paNoDevice, 0, /* NO input */ PA_SAMPLE_TYPE, NULL, Pa_GetDefaultOutputDeviceID(), NUM_CHANNELS, PA_SAMPLE_TYPE, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ paClipOff, /* we won't output out of range samples so don't bother clipping them */ playCallback, &data ); if( err != paNoError ) goto error; if( stream ) { err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Waiting for playback to finish.\n"); fflush(stdout); while( Pa_StreamActive( stream ) ) Pa_Sleep(100); err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; printf("Done.\n"); fflush(stdout); } free( data.recordedSamples ); Pa_Terminate(); return 0; 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 -1; }
int main(void) { PortAudioStream *stream; PaError err; paTestData data; int i; int totalSamps; #if TEST_UNSIGNED printf("PortAudio Test: output UNsigned 8 bit sine wave.\n"); #else printf("PortAudio Test: output signed 8 bit sine wave.\n"); #endif /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (char) (127.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )); #if TEST_UNSIGNED data.sine[i] += (unsigned char) 0x80; #endif } data.left_phase = data.right_phase = 0; data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ err = Pa_Initialize(); if( err != paNoError ) goto error; err = Pa_OpenStream( &stream, paNoDevice,/* default input device */ 0, /* no input */ TEST_FORMAT, NULL, Pa_GetDefaultOutputDeviceID(), /* default output device */ 2, /* stereo output */ TEST_FORMAT, NULL, SAMPLE_RATE, 256, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ 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; /* Watch until sound is halfway finished. */ while( Pa_StreamTime( stream ) < (totalSamps/2) ) Pa_Sleep(10); /* Stop sound until ENTER hit. */ err = Pa_StopStream( stream ); if( err != paNoError ) goto error; printf("Pause for 2 seconds.\n"); Pa_Sleep( 2000 ); err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Waiting for sound to finish.\n"); while( Pa_StreamActive( stream ) ) Pa_Sleep(10); 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; }
int main(void) { PaStreamParameters outputParameters; PaStream *stream; PaError err; paTestData data; #ifdef __APPLE__ PaMacCoreStreamInfo macInfo; const SInt32 channelMap[4] = { -1, -1, 0, 1 }; #endif int i; printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); printf("Output will be mapped to channels 2 and 3 instead of 0 and 1.\n"); /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } data.left_phase = data.right_phase = 0; err = Pa_Initialize(); if( err != paNoError ) goto error; /** setup host specific info */ #ifdef __APPLE__ PaMacCore_SetupStreamInfo( &macInfo, paMacCorePlayNice ); PaMacCore_SetupChannelMap( &macInfo, channelMap, 4 ); for( i=0; i<4; ++i ) printf( "channel %d name: %s\n", i, PaMacCore_GetChannelName( Pa_GetDefaultOutputDevice(), i, false ) ); #else printf( "Channel mapping not supported on this platform. Reverting to normal sine test.\n" ); #endif 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; #ifdef __APPLE__ outputParameters.hostApiSpecificStreamInfo = &macInfo; #else outputParameters.hostApiSpecificStreamInfo = NULL; #endif 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("Play for %d seconds.\n", NUM_SECONDS ); Pa_Sleep( NUM_SECONDS * 1000 ); 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; }
PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("ReadStream()\n")); while( frames > 0 ) { long avail; long toRead; do { avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ); /* printf( "Read Buffer is %%%g full: %ld of %ld.\n", 100 * (float)avail / (float) blio->inputRingBuffer.bufferSize, avail, blio->inputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /**block when empty*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( ret ) return ret; while( blio->isInputEmpty ) { ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toRead = MIN( avail, frames * blio->inputSampleSizeActual * blio->inChan ); toRead -= toRead % blio->inputSampleSizeActual * blio->inChan ; PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, toRead ); cbuf += toRead; frames -= toRead / ( blio->inputSampleSizeActual * blio->inChan ); if( toRead == avail ) { #ifdef PA_MAC_BLIO_MUTEX /* we just emptied the buffer, so we need to mark it as empty. */ ret = blioSetIsInputEmpty( blio, true ); if( ret ) return ret; /* of course, in the meantime, the callback may have put some sats in, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) { blioSetIsInputEmpty( blio, false ); if( ret ) return ret; } #endif } } /* Report either paNoError or paInputOverflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paInputOverflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags ); ret = paInputOverflowed; } return ret; }
PaError TestRecording( paTestData *dataPtr ) { PortAudioStream *stream; PaError err; int i; /* Record some audio. */ err = Pa_OpenStream( &stream, Pa_GetDefaultInputDeviceID(), dataPtr->samplesPerFrame, /* stereo input */ PA_SAMPLE_TYPE, NULL, paNoDevice, 0, PA_SAMPLE_TYPE, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ paClipOff, /* we won't output out of range samples so don't bother clipping them */ recordCallback, dataPtr ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Now recording!\n"); fflush(stdout); for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) { if( Pa_StreamActive( stream ) <= 0) { printf("Stream inactive!\n"); break; } if( dataPtr->maxFrameIndex <= dataPtr->frameIndex ) { printf("Buffer recording complete.\n"); break; } Pa_Sleep(100); printf("index = %d\n", dataPtr->frameIndex ); fflush(stdout); } printf("Finished loop. Close stream.\n"); fflush(stdout); err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; printf("Done.\n"); fflush(stdout); { SAMPLE max = 0; SAMPLE posVal; int i; for( i=0; i<dataPtr->numSamples; i++ ) { posVal = dataPtr->recordedSamples[i]; if( posVal < 0 ) posVal = -posVal; if( posVal > max ) max = posVal; } printf("Largest recorded sample = %d\n", max ); } /* Write recorded data to a file. */ #if 0 { FILE *fid; fid = fopen("recorded.raw", "wb"); if( fid == NULL ) { printf("Could not open file."); } else { fwrite( dataPtr->recordedSamples, dataPtr->samplesPerFrame * sizeof(SAMPLE), totalFrames, fid ); fclose( fid ); printf("Wrote data to 'recorded.raw'\n"); } } #endif error: return err; }
PaError ReadStream( PaStream* stream, void *buffer, unsigned long framesRequested ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("ReadStream()\n")); while( framesRequested > 0 ) { ring_buffer_size_t framesAvailable; ring_buffer_size_t framesToTransfer; ring_buffer_size_t framesTransferred; do { framesAvailable = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ); /* printf( "Read Buffer is %%%g full: %ld of %ld.\n", 100 * (float)avail / (float) blio->inputRingBuffer.bufferSize, framesAvailable, blio->inputRingBuffer.bufferSize ); */ if( framesAvailable == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /**block when empty*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( ret ) return ret; while( blio->isInputEmpty ) { ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( framesAvailable == 0 ); framesToTransfer = (ring_buffer_size_t) MIN( framesAvailable, framesRequested ); framesTransferred = PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, framesToTransfer ); cbuf += framesTransferred * blio->inputSampleSizeActual * blio->inChan; framesRequested -= framesTransferred; if( framesToTransfer == framesAvailable ) { #ifdef PA_MAC_BLIO_MUTEX /* we just emptied the buffer, so we need to mark it as empty. */ ret = blioSetIsInputEmpty( blio, true ); if( ret ) return ret; /* of course, in the meantime, the callback may have put some sats in, so so check for that, too, to avoid a race condition. */ /* FIXME - this does not seem to fix any race condition. */ if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) { blioSetIsInputEmpty( blio, false ); /* FIXME - why check? ret has not been set? */ if( ret ) return ret; } #endif } } /* Report either paNoError or paInputOverflowed. */ /* may also want to report other errors, but this is non-standard. */ /* FIXME should not clobber ret, use if(blio->statusFlags & paInputOverflow) */ ret = blio->statusFlags & paInputOverflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags ); ret = paInputOverflowed; } return ret; }
static void wait_for_restart_signal() { Pa_Sleep(5000); }
int main(void) { PaStreamParameters inputParameters, outputParameters; PaStream* stream; PaError err = paNoError; paTestData data; int i; int totalFrames; int numSamples; int numBytes; SAMPLE max, val; double average; printf("patest_record.c\n"); fflush(stdout); data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */ data.frameIndex = 0; numSamples = totalFrames * NUM_CHANNELS; numBytes = numSamples * sizeof(SAMPLE); data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */ if( data.recordedSamples == NULL ) { printf("Could not allocate record array.\n"); goto done; } for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0; err = Pa_Initialize(); if( err != paNoError ) goto done; inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ inputParameters.channelCount = 2; /* stereo input */ inputParameters.sampleFormat = PA_SAMPLE_TYPE; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; /* Record some audio. -------------------------------------------- */ err = Pa_OpenStream( &stream, &inputParameters, NULL, /* &outputParameters, */ SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, /* we won't output out of range samples so don't bother clipping them */ recordCallback, &data ); if( err != paNoError ) goto done; err = Pa_StartStream( stream ); if( err != paNoError ) goto done; printf("Now recording!!\n"); fflush(stdout); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) { Pa_Sleep(1000); printf("index = %d\n", data.frameIndex ); fflush(stdout); } if( err < 0 ) goto done; err = Pa_CloseStream( stream ); if( err != paNoError ) goto done; /* Measure maximum peak amplitude. */ max = 0; average = 0.0; for( i=0; i<numSamples; i++ ) { val = data.recordedSamples[i]; if( val < 0 ) val = -val; /* ABS */ if( val > max ) { max = val; } average += val; } average = average / (double)numSamples; printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max ); printf("sample average = %lf\n", average ); /* Write recorded data to a file. */ #if 0 { FILE *fid; fid = fopen("recorded.raw", "wb"); if( fid == NULL ) { printf("Could not open file."); } else { fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid ); fclose( fid ); printf("Wrote data to 'recorded.raw'\n"); } } #endif /* Playback recorded data. -------------------------------------------- */ data.frameIndex = 0; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ outputParameters.channelCount = 2; /* stereo output */ outputParameters.sampleFormat = PA_SAMPLE_TYPE; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; printf("Begin playback.\n"); fflush(stdout); 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 */ playCallback, &data ); if( err != paNoError ) goto done; if( stream ) { err = Pa_StartStream( stream ); if( err != paNoError ) goto done; printf("Waiting for playback to finish.\n"); fflush(stdout); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100); if( err < 0 ) goto done; err = Pa_CloseStream( stream ); if( err != paNoError ) goto done; printf("Done.\n"); fflush(stdout); } done: Pa_Terminate(); if( data.recordedSamples ) /* Sure it is NULL or valid. */ free( data.recordedSamples ); if( err != paNoError ) { 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 ) ); err = 1; /* Always return 0 or 1, but no other return codes. */ } return err; }
int main(int argc, char *argv[]) { int exit_code = 0; slimproto_t slimproto; slimaudio_t slimaudio; PaDeviceIndex output_device_id = PA_DEFAULT_DEVICE; char *output_device_name = NULL; char *hostapi_name = NULL; unsigned int output_predelay = 0; unsigned int output_predelay_amplitude = 0; #ifdef EMPEG bool power_bypass = false, power_last = false; bool geteq = false; long key, ir; #endif #ifdef EMPEG slimaudio_volume_t volume_control = VOLUME_DRIVER; #else slimaudio_volume_t volume_control = VOLUME_SOFTWARE; #endif unsigned int retry_interval = RETRY_DEFAULT; char macaddress[6] = { 0, 0, 0, 0, 0, 1 }; int keepalive_interval = -1; bool listdevs = false; bool listservers = false; bool discover_server = false; unsigned int json_port; #ifdef ZONES bool default_macaddress = true; unsigned int zone = 0; unsigned int num_zones = 1; #endif #ifdef DAEMONIZE bool should_daemonize = false; char *logfile = NULL; #endif char slimserver_address[INET_FQDNSTRLEN] = "127.0.0.1"; char getopt_options[OPTLEN] = "a:FId:Y:e:f:hk:Lm:n:o:P:p:Rr:TO:Vv:"; static struct option long_options[] = { {"predelay_amplitude", required_argument, 0, 'a'}, {"discover", no_argument, 0, 'F'}, {"debug", required_argument, 0, 'd'}, {"debuglog", required_argument, 0, 'Y'}, {"help", no_argument, 0, 'h'}, {"keepalive", required_argument, 0, 'k'}, {"list", no_argument, 0, 'L'}, {"findservers", no_argument, 0, 'I'}, {"mac", required_argument, 0, 'm'}, {"name", required_argument, 0, 'n'}, {"output", required_argument, 0, 'o'}, {"playerid", required_argument, 0, 'e'}, {"firmware", required_argument, 0, 'f'}, {"port", required_argument, 0, 'P'}, {"predelay", required_argument, 0, 'p'}, {"threshold_override", no_argument, 0, 'T'}, {"output_threshold", required_argument, 0, 'O'}, #ifdef EMPEG {"puteq", no_argument, 0, 'Q'}, {"geteq", no_argument, 0, 'q'}, #endif {"retry", no_argument, 0, 'R'}, {"intretry", required_argument, 0, 'r'}, {"version", no_argument, 0, 'V'}, {"volume", required_argument, 0, 'v'}, {"zone", required_argument, 0, 'z'}, #ifdef PORTAUDIO_DEV {"latency", required_argument, 0, 'y'}, {"audiotype", required_argument, 0, 't'}, #else {"paframes", required_argument, 0, 'g'}, {"pabuffers", required_argument, 0, 'j'}, #endif #ifdef DAEMONIZE {"daemonize", required_argument, 0, 'M'}, #endif #ifdef __WIN32__ {"highpriority", no_argument, 0, 'H'}, #ifdef PADEV_WASAPI {"shared", no_argument, 0, 'S'}, #endif #endif #ifdef INTERACTIVE {"lircrc", required_argument, 0, 'c'}, {"lirc", no_argument, 0, 'i'}, {"lcd", no_argument, 0, 'l'}, {"lcdc", no_argument, 0, 'C'}, {"display", no_argument, 0, 'D'}, {"width", required_argument, 0, 'w'}, #endif #ifdef RENICE {"renice", no_argument, 0, 'N'}, #endif #ifdef ZONES {"zone", required_argument, 0, 'z'}, #endif {0, 0, 0, 0} }; #ifdef INTERACTIVE fd_set read_fds; fd_set write_fds; int key = 0; unsigned long ir = 0; int maxfd = 0; char *home; struct timeval timeout; timeout.tv_usec = 0; #ifdef __WIN32__ int WSAerrno; int ptw32_processInitialize (void); ptw32_processInitialize(); #endif /* __WIN32__ */ /* default lircrc file ($HOME/.lircrc) */ home = getenv("HOME"); if (home == NULL) home = ""; lircrc = (char *)malloc((strlen(home) + strlen("/.lircrc") + 1) * sizeof(char)); strcpy(lircrc,home); strcat(lircrc,"/.lircrc"); #endif /* INTERACTIVE */ #ifdef EMPEG strcat (getopt_options, "Qq"); #endif #ifdef PORTAUDIO_DEV strcat (getopt_options, "y:t:"); #else strcat (getopt_options, "g:j:"); #endif #ifdef DAEMONIZE strcat (getopt_options, "M:"); #endif #ifdef INTERACTIVE strcat (getopt_options, "c:CDilw:"); #endif #ifdef __WIN32__ strcat (getopt_options, "H"); #ifdef PADEV_WASAPI strcat (getopt_options, "S"); #endif #endif #ifdef RENICE strcat (getopt_options, "N"); #endif #ifdef ZONES strcat (getopt_options, "z:"); #endif #ifdef EMPEG empeg_getmac(macaddress); #endif while (true) { const char shortopt = getopt_long_only(argc, argv, getopt_options, long_options, NULL); if (shortopt == (char) -1) { break; } switch (shortopt) { case 'a': output_predelay_amplitude = strtoul(optarg, NULL, 0); break; case 'F': discover_server = true; break; case 'd': #ifdef SLIMPROTO_DEBUG if (strcmp(optarg, "all") == 0) { slimproto_debug = true; slimaudio_debug = true; slimaudio_buffer_debug = true; slimaudio_buffer_debug_v = true; slimaudio_decoder_debug = true; slimaudio_decoder_debug_r = true; slimaudio_decoder_debug_v = true; slimaudio_http_debug = true; slimaudio_http_debug_v = true; slimaudio_output_debug = true; slimaudio_output_debug_v = true; } else if (strcmp(optarg, "slimproto") == 0) slimproto_debug = true; else if (strcmp(optarg, "slimaudio") == 0) slimaudio_debug = true; else if (strcmp(optarg, "slimaudio_buffer") == 0) slimaudio_buffer_debug = true; else if (strcmp(optarg, "slimaudio_buffer_v") == 0) slimaudio_buffer_debug_v = true; else if (strcmp(optarg, "slimaudio_decoder") == 0) slimaudio_decoder_debug = true; else if (strcmp(optarg, "slimaudio_decoder_r") == 0) slimaudio_decoder_debug_r = true; else if (strcmp(optarg, "slimaudio_decoder_v") == 0) slimaudio_decoder_debug_v = true; else if (strcmp(optarg, "slimaudio_http") == 0) slimaudio_http_debug = true; else if (strcmp(optarg, "slimaudio_http_v") == 0) slimaudio_http_debug_v = true; else if (strcmp(optarg, "slimaudio_output") == 0) slimaudio_output_debug = true; else if (strcmp(optarg, "slimaudio_output_v") == 0) slimaudio_output_debug_v = true; else fprintf(stderr, "%s: Unknown debug option %s\n", argv[0], optarg); #else fprintf(stderr, "%s: Recompile with -DSLIMPROTO_DEBUG to enable debugging.\n", argv[0]); #endif break; case 'Y': #ifdef SLIMPROTO_DEBUG if ( optarg == NULL ) { fprintf(stderr, "%s: Cannot parse debug log filename %s\n", argv[0], optarg); exit(-1); } else { debuglog = freopen( optarg, "a", stderr); if ( debuglog ) debug_logfile = true; else fprintf(stderr, "%s: Redirection of stderr to %s failed.\n", argv[0], optarg); } #endif break; /* From server/Slim/Networking/Slimproto.pm from 7.5r28596 ** squeezebox(2) ** softsqueeze(3) ** squeezebox2(4) ** transporter(5) ** softsqueeze3(6) ** receiver(7) ** squeezeslave(8) ** controller(9) ** boom(10) ** softboom(11) ** squeezeplay(12) ** radio(13) ** touch(14) */ case 'e': player_type = strtoul(optarg, NULL, 0); if ( (player_type < 2) || (player_type > 14) ) { player_type = PLAYER_TYPE; fprintf(stderr, "%s: Unknown player type, using (%d)\n", argv[0], player_type); } break; case 'f': firmware = strtoul(optarg, NULL, 0); if ( (firmware < 0) || (firmware > 254) ) { firmware = FIRMWARE_VERSION; fprintf(stderr, "%s: Invalid firmware value, using (%d)\n", argv[0], firmware); } break; case 'h': print_help(); exit(0); case 'k': keepalive_interval = strtoul(optarg, NULL, 0); break; case 'T': threshold_override = true; break; case 'O': output_threshold = strtoul(optarg, NULL, 0); if ( (output_threshold < 0) || (output_threshold > 1000000) ) { output_threshold = OUTPUT_THRESHOLD; fprintf(stderr, "%s: Invalid output threshold, using (%d)\n", argv[0], output_threshold); } break; case 'm': if (parse_macaddress(macaddress, optarg) != 0) { fprintf(stderr, "%s: Cannot parse mac address %s\n", argv[0], optarg); exit(-1); } #ifdef ZONES default_macaddress = false; #endif break; #ifdef DAEMONIZE case 'M': if ( optarg == NULL ) { fprintf(stderr, "%s: Cannot parse log filename %s\n", argv[0], optarg); exit(-1); } else { logfile = optarg; } should_daemonize = true; break; #endif #ifdef __WIN32__ case 'H': /* Change Window process priority class to HIGH */ if ( !SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) { int dwError = GetLastError(); fprintf(stderr, "%s: Failed to set priority (%d), using default.\n", argv[0], dwError); } break; #ifdef PADEV_WASAPI case 'S': wasapi_exclusive = false; break; #endif #endif #ifdef RENICE case 'N': renice = true; break; #endif case 'n': output_device_name = optarg; output_change = true; break; case 'o': output_device_id = strtoul(optarg, NULL, 0); output_change = true; break; case 'p': output_predelay = strtoul(optarg, NULL, 0); break; case 'P': port = strtoul(optarg, NULL, 0); if ( (port < 0) || (port > 65535) ) { port = SLIMPROTOCOL_PORT; fprintf(stderr, "%s: Invalid port number, using %d.\n", argv[0], port); } break; break; #ifdef EMPEG case 'Q': empeg_puteq_tofile(); exit(0); break; case 'q': geteq = true; break; #endif case 'R': retry_connection = true; break; case 'r': retry_connection = true; retry_interval = strtoul(optarg, NULL, 0); if ( ( retry_interval < 1 ) || ( retry_interval > 120 ) ) { retry_interval = RETRY_DEFAULT; fprintf (stderr, "Invalid retry interval, using %d seconds.\n", retry_interval ); } break; #ifdef INTERACTIVE case 'c': free(lircrc); lircrc = optarg; break; #ifndef __WIN32__ case 'i': using_lirc = true; break; case 'l': use_lcdd_menu = true; break; case 'C': use_lcdd_menu = true; lcdd_compat = true; break; #endif case 'D': using_curses = 1; break; case 'w': linelen = strtoul(optarg, NULL, 0); break; #endif case 'L': listdevs = true; break; case 'I': listservers = true; break; case 'V': print_version(); exit(0); break; case 'v': if (strcmp(optarg, "sw") == 0) { volume_control = VOLUME_SOFTWARE; } #ifndef PORTAUDIO_DEV else if (strcmp(optarg, "on") == 0 ) { volume_control = VOLUME_DRIVER; } #endif else if (strcmp(optarg, "off") == 0 ) { volume_control = VOLUME_NONE; } break; #ifdef PORTAUDIO_DEV case 'y': modify_latency = true; user_latency = strtoul(optarg, NULL, 0); if ( user_latency > 1000 ) { fprintf (stderr, "Suggested latency invalid, using device default.\n"); modify_latency = false; } break; case 't': hostapi_name = optarg; break; #else case 'g': pa_framesPerBuffer = strtoul(optarg, NULL, 0); if ( (pa_framesPerBuffer > 65536) || (pa_framesPerBuffer < 64) ) { fprintf (stderr, "Portaudio frames per buffer invalid, using default (%d).\n", PA_FRAMES_PER_BUFFER); pa_framesPerBuffer = PA_FRAMES_PER_BUFFER ; } break; case 'j': pa_numberOfBuffers = strtoul(optarg, NULL, 0); if ( (pa_numberOfBuffers > 64) || (pa_numberOfBuffers < 0) ) { fprintf (stderr, "Number of Portaudio buffers invalid, using default (%d).\n", PA_NUM_BUFFERS); pa_numberOfBuffers = PA_NUM_BUFFERS; } break; #endif #ifdef ZONES case 'z': if (sscanf(optarg, "%u/%u", &zone, &num_zones) != 2) { fprintf (stderr, "Invalid zone specification, using default.\n"); } if (num_zones > MAX_ZONES) { fprintf(stderr, "Number of zones > %d not supported\n", MAX_ZONES); zone=0; num_zones=1; } if (num_zones <= zone) { fprintf (stderr, "Invalid zone specification, using default.\n"); zone = 0; num_zones = 1; } break; #endif default: break; } } if (listdevs) { GetAudioDevices(output_device_id, output_device_name, hostapi_name, output_change, true); exit(0); } if (listservers) { slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json_port, true); exit(0); } if (optind < argc) strncpy(slimserver_address, argv[optind], sizeof(slimserver_address)); #ifdef DAEMONIZE if ( should_daemonize ) { #ifdef INTERACTIVE if ( using_curses || use_lcdd_menu ) { fprintf(stderr, "Daemonize not supported with display modes.\n"); exit(-1); } else #endif init_daemonize(); } #endif signal(SIGTERM, &exit_handler); signal(SIGINT, &exit_handler); install_restart_handler(); #ifdef INTERACTIVE install_toggle_handler(); /*SIGUSR2 to toggle IR/LCD on and off */ #endif if (slimproto_init(&slimproto) < 0) { fprintf(stderr, "Failed to initialize slimproto\n"); exit(-1); } #ifdef ZONES if (slimaudio_init(&slimaudio, &slimproto, output_device_id, output_device_name, hostapi_name, output_change, zone, num_zones) < 0) #else if (slimaudio_init(&slimaudio, &slimproto, output_device_id, output_device_name, hostapi_name, output_change) < 0) #endif { fprintf(stderr, "Failed to initialize slimaudio\n"); exit(-1); } #ifdef ZONES if (default_macaddress) macaddress[5] += zone; #endif slimproto_add_connect_callback(&slimproto, connect_callback, macaddress); #ifdef INTERACTIVE /* Process VFD (display) commands */ if ( using_curses || using_lirc || use_lcdd_menu ) slimproto_add_command_callback(&slimproto, "vfdc", vfd_callback, macaddress); #endif #ifdef EMPEG slimproto_add_command_callback(&slimproto, "grfe", empeg_vfd_callback, macaddress); slimproto_add_command_callback(&slimproto, "grfb", empeg_vfdbrt_callback, macaddress); slimproto_add_command_callback(&slimproto, "aude", empeg_aude_callback, macaddress); #endif slimaudio_set_volume_control(&slimaudio, volume_control); slimaudio_set_output_predelay(&slimaudio, output_predelay, output_predelay_amplitude); if (keepalive_interval >= 0) { slimaudio_set_keepalive_interval(&slimaudio, keepalive_interval); } #ifdef INTERACTIVE init_lcd(); #endif #ifdef EMPEG empeg_init(); if (geteq) empeg_geteq_fromfile(); power_last = empeg_state.power_on; empeg_state.power_on = false; #endif if (slimaudio_open(&slimaudio) < 0) { fprintf(stderr, "Failed to open slimaudio\n"); exit_code = -1; goto exit; } #ifdef SLIMPROTO_DEBUG if (slimaudio_debug) fprintf ( stderr, "Using audio device index: %d\n", slimaudio.output_device_id ); #endif #ifdef INTERACTIVE init_lirc(); setlocale(LC_ALL, ""); initcurses(); #endif #ifdef DAEMONIZE if ( should_daemonize ) { daemonize(logfile); } #endif /* When retry_connection is true, retry connecting to Squeezebox Server ** until we succeed, unless the signal handler tells us to give up. */ do { if (signal_restart_flag) { #ifdef INTERACTIVE exitcurses(); #endif fprintf(stderr,"Retry in %d seconds.\n", retry_interval); Pa_Sleep(1000 * retry_interval); #ifdef INTERACTIVE initcurses(); #endif } #ifdef EMPEG if (discover_server && empeg_state.last_server[0] != '\0') { strcpy(slimserver_address, (char *)empeg_state.last_server); empeg_state.last_server[0] = '\0'; } else #endif if (discover_server && slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json_port, false) < 0) { fprintf(stderr,"Discover failed.\n"); if (!retry_connection) { exit_code = -1; goto exit; } signal_restart_flag = true; continue; } if (slimproto_connect( &slimproto, slimserver_address, port) < 0) { fprintf(stderr, "Connection to Squeezebox Server %s failed.\n", slimserver_address); if (!retry_connection) { exit_code = -1; goto exit; } signal_restart_flag = true; continue; } signal_restart_flag = false; discover_server = false; #ifdef EMPEG strcpy((char *)empeg_state.last_server, slimserver_address); if (power_last) while (!empeg_state.power_on) { Pa_Sleep(100); slimproto_ir(&slimproto, 1, 1, 0x76898F70); } #endif while (!signal_exit_flag && !signal_restart_flag) { #ifdef EMPEG int rc = empeg_idle(); if (power_bypass) { if (rc == 0 || !empeg_state.power_on) { power_last = false; power_bypass = false; } } else if (rc == -1) { fprintf(stderr, "Power loss detected.\n"); power_last = empeg_state.power_on; slimproto_ir(&slimproto, 1, 1, 0x76898778); while (empeg_state.power_on) Pa_Sleep(250); } else if (rc == -2 && empeg_state.power_on) { fprintf(stderr, "Manual override, aborting power down.\n"); power_bypass = true; } else if (rc == -3) { fprintf(stderr, "Power restored.\n"); if (power_last) slimproto_ir(&slimproto, 1, 1, 0x76898F70); } else if (rc == -4) { fprintf(stderr, "Powering down.\n"); slimproto_goodbye(&slimproto, 0x00); Pa_Sleep(400); slimproto_close(&slimproto); empeg_state.power_on = power_last; empeg_poweroff(); signal_restart_flag = true; } #endif #ifdef INTERACTIVE if (using_curses == 1 || use_lcdd_menu || using_lirc) { FD_ZERO(&read_fds); FD_ZERO(&write_fds); if (using_curses == 1) FD_SET(0, &read_fds); /* watch stdin */ if (use_lcdd_menu) { FD_SET(lcd_fd, &read_fds); maxfd = lcd_fd; } if (using_lirc) { FD_SET(lirc_fd, &read_fds); if (lirc_fd > maxfd) maxfd = lirc_fd; } timeout.tv_sec = 5; if(select(maxfd + 1, &read_fds, NULL, NULL, &timeout) == -1) { #ifndef __WIN32__ if (errno != EINTR) { fprintf(stderr,"Select Error:%d\n", errno); #else WSAerrno = WSAGetLastError(); if ( (WSAerrno != WSAEINTR) && (WSAerrno != WSAENOTSOCK) ) { fprintf(stderr,"Select Error:%d\n", WSAerrno); #endif abort(); } #ifdef __WIN32__ else WaitForSingleObject( GetStdHandle(STD_INPUT_HANDLE), 5000 ); #endif } if (FD_ISSET(0, &read_fds)) { while ((key = getch()) != ERR) { ir = getircode(key); if (ir == (unsigned long) 0x01) { signal_exit_flag = 1; }else{ if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } } } if (using_lirc && FD_ISSET(lirc_fd, &read_fds)) { while((key = read_lirc()) != 0 ) { ir = getircode(key); if (ir == 0x01) { signal_exit_flag = 1; } else { if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } } } if (use_lcdd_menu && FD_ISSET(lcd_fd, &read_fds)) { while(read_lcd()); } } else { wait_for_restart_signal(); } #else #ifdef EMPEG while ((key = empeg_getkey()) != -1) { ir = empeg_getircode(key); if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } #else wait_for_restart_signal(); #endif #endif } #ifdef INTERACTIVE FD_ZERO(&read_fds); FD_ZERO(&write_fds); #endif } while (signal_restart_flag && !signal_exit_flag); exit: slimaudio_close(&slimaudio); slimproto_goodbye(&slimproto, 0x00); /* Wait 200ms for BYE! message send to complete */ Pa_Sleep(200); slimproto_close(&slimproto); #ifdef INTERACTIVE exitcurses(); close_lirc(); #endif #if defined(EMPEG) || defined(INTERACTIVE) close_lcd(); #endif #ifdef SLIMPROTO_DEBUG if (debug_logfile) { fclose (debuglog); } #endif slimproto_destroy(&slimproto); slimaudio_destroy(&slimaudio); return exit_code; }
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 */ 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; printf("Establishing load conditions...\n" ); /* Determine number of sines required to get to 50% */ do { Pa_Sleep( 100 ); load = Pa_GetStreamCpuLoad( stream ); printf("sineCount = %d, CPU load = %f\n", data.sineCount, load ); if( load < 0.3 ) { data.sineCount += 10; } else if( load < 0.4 ) { data.sineCount += 2; } else { data.sineCount += 1; } } 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+=4 ) { 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; float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */ float sine[TABLE_SIZE]; /* sine wavetable */ int left_phase = 0; int right_phase = 0; int left_inc = 1; int right_inc = 3; /* higher pitch so we can distinguish left and right. */ int i, j, k; int bufferCount; 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++ ) { sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } err = Pa_Initialize(); if( err != paNoError ) goto error; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ 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, FRAMES_PER_BUFFER, paClipOff, /* we won't output out of range samples so don't bother clipping them */ NULL, /* no callback, use blocking API */ NULL ); /* no callback, so no callback userData */ if( err != paNoError ) goto error; printf( "Play 3 times, higher each time.\n" ); for( k=0; k < 3; ++k ) { err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Play for %d seconds.\n", NUM_SECONDS ); bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER); for( i=0; i < bufferCount; i++ ) { for( j=0; j < FRAMES_PER_BUFFER; j++ ) { buffer[j][0] = sine[left_phase]; /* left */ buffer[j][1] = sine[right_phase]; /* right */ left_phase += left_inc; if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE; right_phase += right_inc; if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE; } err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER ); if( err != paNoError ) goto error; } err = Pa_StopStream( stream ); if( err != paNoError ) goto error; ++left_inc; ++right_inc; Pa_Sleep( 1000 ); } 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; }
PaError TestRecording( paTestData *dataPtr ) { PaError err; int i; int lastIndex = 0; /* Open input stream if not already open. */ if( dataPtr->inputStream == NULL ) { /* Record some audio. */ err = Pa_OpenStream( &dataPtr->inputStream, Pa_GetDefaultInputDeviceID(), dataPtr->samplesPerFrame, /* stereo input */ PA_SAMPLE_TYPE, NULL, paNoDevice, 0, PA_SAMPLE_TYPE, NULL, SAMPLE_RATE, FRAMES_PER_BUFFER, /* frames per buffer */ NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ paClipOff, /* we won't output out of range samples so don't bother clipping them */ recordCallback, dataPtr ); if( err != paNoError ) goto error; } dataPtr->frameIndex = 0; err = Pa_StartStream( dataPtr->inputStream ); if( err != paNoError ) goto error; printf("Now recording!\n"); fflush(stdout); for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) { int frameIndex, delta; Pa_Sleep(SLEEP_DUR_MSEC); frameIndex = dataPtr->frameIndex; if( Pa_StreamActive( dataPtr->inputStream ) <= 0) { printf("Stream inactive!\n"); break; } if( dataPtr->maxFrameIndex <= frameIndex ) { printf("Buffer recording complete.\n"); break; } delta = frameIndex - lastIndex; lastIndex = frameIndex; printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout); } err = Pa_StopStream( dataPtr->inputStream ); if( err != paNoError ) goto error; printf("Done.\n"); fflush(stdout); error: return err; }
static void *WatchdogFunc( void *userData ) { PaError result = paNoError, *pres = NULL; int err; PaAlsaThreading *th = (PaAlsaThreading *) userData; unsigned intervalMsec = 500; const PaTime maxSeconds = 3.; /* Max seconds between callbacks */ PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed; double cpuLoad, avgCpuLoad = 0.; int throttled = 0; assert( th ); /* Execute OnWatchdogExit when exiting */ pthread_cleanup_push( &OnWatchdogExit, th ); /* Boost priority of callback thread */ PA_ENSURE( result = BoostPriority( th ) ); if( !result ) { /* Boost failed, might as well exit */ pthread_exit( NULL ); } cpuTimeThen = th->callbackCpuTime; { int policy; struct sched_param spm = { 0 }; pthread_getschedparam( pthread_self(), &policy, &spm ); PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority )); } while( 1 ) { double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff; /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */ pthread_testcancel(); Pa_Sleep( intervalMsec ); pthread_testcancel(); if( PaUtil_GetTime() - th->callbackTime > maxSeconds ) { PA_DEBUG(( "Watchdog: Terminating callback thread\n" )); /* Tell thread to terminate */ err = pthread_kill( th->callbackThread, SIGKILL ); pthread_exit( NULL ); } PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) )); /* Check if we should throttle, or unthrottle :P */ cpuTimeNow = th->callbackCpuTime; cpuTimeElapsed = cpuTimeNow - cpuTimeThen; cpuTimeThen = cpuTimeNow; timeNow = PaUtil_GetTime(); timeElapsed = timeNow - timeThen; timeThen = timeNow; cpuLoad = cpuTimeElapsed / timeElapsed; avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1; /* if( throttled ) PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed )); */ if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 ) { static int policy; static struct sched_param spm = { 0 }; static const struct sched_param defaultSpm = { 0 }; PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority )); pthread_getschedparam( th->callbackThread, &policy, &spm ); if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) ) { throttled = 1; } else PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) )); /* Give other processes a go, before raising priority again */ PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime )); Pa_Sleep( th->throttledSleepTime ); /* Reset callback priority */ if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 ) { PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) )); } if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 ) intervalMsec = 50; else intervalMsec = 100; /* lowpassCoeff = .97; lowpassCoeff1 = .99999 - lowpassCoeff; */ } else if( throttled && avgCpuLoad < .8 ) { intervalMsec = 500; throttled = 0; /* lowpassCoeff = .9; lowpassCoeff1 = .99999 - lowpassCoeff; */ } } pthread_cleanup_pop( 1 ); /* Execute cleanup on exit */ error: /* Shouldn't get here in the normal case */ /* Pass on error code */ pres = malloc( sizeof (PaError) ); *pres = result; pthread_exit( pres ); }
int main(void) { PaStream *stream; PaStreamParameters outputParameters; PaError err; paTestData data; int i; int timeout; printf("Play different tone sine waves that alternate between left and right channel.\n"); printf("The low tone should be on the left channel.\n"); /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } data.left_phase = data.right_phase = data.toggle = 0; data.countDown = SAMPLE_RATE; 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, /* As above. */ 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("Play for several seconds.\n"); timeout = NUM_SECONDS * 4; while( timeout > 0 ) { Pa_Sleep( 300 ); /*(Irix very much likes sleeps <= 1000 ms.)*/ timeout -= 1; } 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; }
int main(int argc, char* argv[]) { PaStreamParameters outputParameters; PaWinMmeStreamInfo wmmeStreamInfo; PaStream *stream; PaError err; paTestData data; int i; int deviceIndex; printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT); err = Pa_Initialize(); if( err != paNoError ) goto error; deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paMME ) )->defaultOutputDevice; if( argc == 2 ){ sscanf( argv[1], "%d", &deviceIndex ); } printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name ); /* initialise sinusoidal wavetable */ for( i=0; i<TABLE_SIZE; i++ ) { data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } data.phase = 0; outputParameters.device = deviceIndex; outputParameters.channelCount = CHANNEL_COUNT; outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */ outputParameters.suggestedLatency = 0; /*Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;*/ outputParameters.hostApiSpecificStreamInfo = NULL; wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo); wmmeStreamInfo.hostApiType = paMME; wmmeStreamInfo.version = 1; wmmeStreamInfo.flags = paWinMmeUseLowLevelLatencyParameters | paWinMmeDontThrottleOverloadedProcessingThread; wmmeStreamInfo.framesPerBuffer = WMME_FRAMES_PER_BUFFER; wmmeStreamInfo.bufferCount = WMME_BUFFER_COUNT; outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo; if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){ printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT ); }else{ printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT ); } 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("Play for %d seconds.\n", NUM_SECONDS ); Pa_Sleep( NUM_SECONDS * 1000 ); 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; }