PaError CloseAudioStream(PABLIO_Stream * aStream) { int bytesEmpty; int byteSize; int c = 0; if (aStream->has_out) { for (c = 0; c < aStream->channelCount; c++) { byteSize = aStream->outFIFOs[c].bufferSize; /* If we are writing data, make sure we play everything written. */ if (byteSize > 0) { bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]); while (bytesEmpty < byteSize) { Pa_Sleep(10); bytesEmpty = PaUtil_GetRingBufferWriteAvailable(&aStream->outFIFOs[c]); } } } } if (aStream->do_dual) { if (aStream->has_in && aStream->istream) { if (Pa_IsStreamActive(aStream->istream)) { Pa_StopStream(aStream->istream); } Pa_CloseStream(aStream->istream); aStream->istream = NULL; } if (aStream->has_out && aStream->ostream) { if (Pa_IsStreamActive(aStream->ostream)) { Pa_StopStream(aStream->ostream); } Pa_CloseStream(aStream->ostream); aStream->ostream = NULL; } } else { if (aStream->iostream) { if (Pa_IsStreamActive(aStream->iostream)) { Pa_StopStream(aStream->iostream); } Pa_CloseStream(aStream->iostream); aStream->iostream = NULL; } } if (aStream->has_in) { for (c = 0; c < aStream->channelCount; c++) { PABLIO_TermFIFO(&aStream->inFIFOs[c]); } } if (aStream->has_out) { for (c = 0; c < aStream->channelCount; c++) { PABLIO_TermFIFO(&aStream->outFIFOs[c]); } } free(aStream); switch_yield(500000); return paNoError; }
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 */ 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, 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 */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto done; } 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; }
static int wave_open_sound() { ENTER("wave_open_sound"); PaError err=paNoError; PaError active; #if USE_PORTAUDIO == 18 active = Pa_StreamActive(pa_stream); #else active = Pa_IsStreamActive(pa_stream); #endif if(active == 1) { SHOW_TIME("wave_open_sound > already active"); return(0); } if(active < 0) { out_channels = 1; #if USE_PORTAUDIO == 18 // err = Pa_OpenDefaultStream(&pa_stream,0,1,paInt16,wave_samplerate,FRAMES_PER_BUFFER,N_WAV_BUF,pa_callback,(void *)userdata); PaDeviceID playbackDevice = Pa_GetDefaultOutputDeviceID(); PaError err = Pa_OpenStream( &pa_stream, /* capture parameters */ paNoDevice, 0, paInt16, NULL, /* playback parameters */ playbackDevice, out_channels, paInt16, NULL, /* general parameters */ wave_samplerate, FRAMES_PER_BUFFER, 0, //paClipOff | paDitherOff, paNoFlag, pa_callback, (void *)userdata); SHOW("wave_open_sound > Pa_OpenDefaultStream(1): err=%d (%s)\n",err, Pa_GetErrorText(err)); if(err == paInvalidChannelCount) { SHOW_TIME("wave_open_sound > try stereo"); // failed to open with mono, try stereo out_channels = 2; // myOutputParameters.channelCount = out_channels; PaError err = Pa_OpenStream( &pa_stream, /* capture parameters */ paNoDevice, 0, paInt16, NULL, /* playback parameters */ playbackDevice, out_channels, paInt16, NULL, /* general parameters */ wave_samplerate, FRAMES_PER_BUFFER, 0, //paClipOff | paDitherOff, paNoFlag, pa_callback, (void *)userdata); // err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16, // wave_samplerate, // FRAMES_PER_BUFFER, // N_WAV_BUF,pa_callback,(void *)userdata); SHOW("wave_open_sound > Pa_OpenDefaultStream(2): err=%d (%s)\n",err, Pa_GetErrorText(err)); err=0; // avoid warning } mInCallbackFinishedState = false; // v18 only #else myOutputParameters.channelCount = out_channels; unsigned long framesPerBuffer = paFramesPerBufferUnspecified; err = Pa_OpenStream( &pa_stream, NULL, /* no input */ &myOutputParameters, wave_samplerate, framesPerBuffer, paNoFlag, // paClipOff | paDitherOff, pa_callback, (void *)userdata); if ((err!=paNoError) && (err!=paInvalidChannelCount)) //err==paUnanticipatedHostError { fprintf(stderr, "wave_open_sound > Pa_OpenStream : err=%d (%s)\n",err,Pa_GetErrorText(err)); framesPerBuffer = FRAMES_PER_BUFFER; err = Pa_OpenStream( &pa_stream, NULL, /* no input */ &myOutputParameters, wave_samplerate, framesPerBuffer, paNoFlag, // paClipOff | paDitherOff, pa_callback, (void *)userdata); } if(err == paInvalidChannelCount) { SHOW_TIME("wave_open_sound > try stereo"); // failed to open with mono, try stereo out_channels = 2; myOutputParameters.channelCount = out_channels; err = Pa_OpenStream( &pa_stream, NULL, /* no input */ &myOutputParameters, wave_samplerate, framesPerBuffer, paNoFlag, // paClipOff | paDitherOff, pa_callback, (void *)userdata); // err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,(double)wave_samplerate,FRAMES_PER_BUFFER,pa_callback,(void *)userdata); } mInCallbackFinishedState = false; #endif } SHOW("wave_open_sound > %s\n","LEAVE"); return (err != paNoError); }
static int output_data(char *buf, int32 nbytes) { unsigned int i; int32 samplesToGo; char *bufepoint; if(pa_active == 0) return -1; while((pa_active==1) && (pa_data.samplesToGo > bytesPerInBuffer)){ Pa_Sleep(1);}; // if(pa_data.samplesToGo > DATA_BLOCK_SIZE){ // Sleep( (pa_data.samplesToGo - DATA_BLOCK_SIZE)/dpm.rate/4 ); // } samplesToGo=pa_data.samplesToGo; bufepoint=pa_data.bufepoint; if (pa_data.buf+bytesPerInBuffer*2 >= bufepoint + nbytes){ memcpy(bufepoint, buf, nbytes); bufepoint += nbytes; //buf += nbytes; }else{ int32 send = pa_data.buf+bytesPerInBuffer*2 - bufepoint; if (send != 0) memcpy(bufepoint, buf, send); buf += send; memcpy(pa_data.buf, buf, nbytes - send); bufepoint = pa_data.buf + nbytes - send; //buf += nbytes-send; } samplesToGo += nbytes; pa_data.samplesToGo=samplesToGo; pa_data.bufepoint=bufepoint; /* if(firsttime==1){ err = Pa_StartStream( stream ); if( err != paNoError ) goto error; firsttime=0; } */ #if PORTAUDIO_V19 if( 0==Pa_IsStreamActive(stream)){ #else if( 0==Pa_StreamActive(stream)){ #endif err = Pa_StartStream( stream ); if( err != paNoError ) goto error; } // if(ctl->id_character != 'r' && ctl->id_character != 'A' && ctl->id_character != 'W' && ctl->id_character != 'P') // while((pa_active==1) && (pa_data.samplesToGo > bytesPerInBuffer)){ Pa_Sleep(1);}; // Pa_Sleep( (pa_data.samplesToGo - bytesPerInBuffer)/dpm.rate * 1000); return 0; error: Pa_Terminate(); pa_active=0; ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "PortAudio error: %s\n", Pa_GetErrorText( err ) ); return -1; } static void close_output(void) { if( pa_active==0) return; #ifdef PORTAUDIO_V19 if(Pa_IsStreamActive(stream)){ #else if(Pa_StreamActive(stream)){ #endif Pa_Sleep( bytesPerInBuffer/dpm.rate*1000 ); } err = Pa_AbortStream( stream ); if( (err!=paStreamIsStopped) && (err!=paNoError) ) goto error; err = Pa_CloseStream( stream ); // if( err != paNoError ) goto error; Pa_Terminate(); pa_active=0; #ifdef AU_PORTAUDIO_DLL #ifndef PORTAUDIO_V19 free_portaudio_dll(); #endif #endif return; error: Pa_Terminate(); pa_active=0; #ifdef AU_PORTAUDIO_DLL #ifndef PORTAUDIO_V19 free_portaudio_dll(); #endif #endif ctl->cmsg( CMSG_ERROR, VERB_NORMAL, "PortAudio error: %s\n", Pa_GetErrorText( err ) ); return; } static int acntl(int request, void *arg) { switch(request) { case PM_REQ_GETQSIZ: *(int *)arg = bytesPerInBuffer*2; return 0; //break; case PM_REQ_GETFILLABLE: *(int *)arg = bytesPerInBuffer*2-pa_data.samplesToGo; return 0; //break; case PM_REQ_GETFILLED: *(int *)arg = pa_data.samplesToGo; return 0; //break; case PM_REQ_DISCARD: case PM_REQ_FLUSH: pa_data.samplesToGo=0; pa_data.bufpoint=pa_data.bufepoint; err = Pa_AbortStream( stream ); if( (err!=paStreamIsStopped) && (err!=paNoError) ) goto error; err = Pa_StartStream( stream ); if(err!=paNoError) goto error; return 0; //break; case PM_REQ_RATE: { int i; double sampleRateBack; i = *(int *)arg; //* sample rate in and out * close_output(); sampleRateBack=dpm.rate; dpm.rate=i; if(0==open_output()){ return 0; }else{ dpm.rate=sampleRateBack; open_output(); return -1; } } //break; // case PM_REQ_RATE: // return -1; case PM_REQ_PLAY_START: //* Called just before playing * case PM_REQ_PLAY_END: //* Called just after playing * return 0; default: return -1; } return -1; error: /* Pa_Terminate(); pa_active=0; #ifdef AU_PORTAUDIO_DLL free_portaudio_dll(); #endif */ ctl->cmsg( CMSG_ERROR, VERB_NORMAL, "PortAudio error in acntl : %s\n", Pa_GetErrorText( err ) ); return -1; } static void print_device_list(void){ PaDeviceIndex maxDeviceIndex, i; PaHostApiIndex HostApiIndex; const PaDeviceInfo* DeviceInfo; #if PORTAUDIO_V19 HostApiIndex=Pa_HostApiTypeIdToHostApiIndex(HostApiTypeId); #endif maxDeviceIndex=Pa_GetDeviceCount(); for( i = 0; i < maxDeviceIndex; i++){ DeviceInfo=Pa_GetDeviceInfo(i); #if PORTAUDIO_V19 if( DeviceInfo->hostApi == HostApiIndex){ #endif if( DeviceInfo->maxOutputChannels > 0){ ctl->cmsg( CMSG_ERROR, VERB_NORMAL, "%2d %s",i,DeviceInfo->name); } #if PORTAUDIO_V19 } #endif } }
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"); ; } for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0; err = Pa_Initialize(); if( err != paNoError ) {}; inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default input device.\n"); ; } inputParameters.channelCount = NUM_CHANNELS; 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 ) {}; // // err = Pa_StartStream( stream ); // if( err != paNoError ) {}; // printf("\n=== Sprawdzam poziom szumów. Nie mów nic. ===\n"); fflush(stdout); // // while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) // { // Pa_Sleep(1000); // printf("index = %d\n", data.frameIndex ); fflush(stdout); // } // if( err < 0 ){}; // // err = Pa_CloseStream( stream ); // if( err != paNoError ) {}; data.frameIndex = 0; 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 ) {}; err = Pa_StartStream( stream ); if( err != paNoError ) {}; printf("\n=== Teraz nagrywam powiedź coś. ===\n"); fflush(stdout); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) { Pa_Sleep(1000); printf("index = %d\n", data.frameIndex ); fflush(stdout); } if( err < 0 ){}; err = Pa_CloseStream( stream ); if( err != paNoError ) {}; /* 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("maksymalna amplituda = "PRINTF_S_FORMAT"\n", max ); printf("srednia = %lf\n", average ); zapiszWykres(numSamples, data); zapiszHistogram(numSamples, data); //przejsciaPrzezZero(numSamples, data, 0); przejsciaPrzezZero(numSamples, data, average); /* Playback recorded data. -------------------------------------------- */ data.frameIndex = 0; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); } outputParameters.channelCount = NUM_CHANNELS; /* stereo output */ outputParameters.sampleFormat = PA_SAMPLE_TYPE; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; printf("\n=== Now playing back. ===\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 ) {}; if( stream ) { err = Pa_StartStream( stream ); if( err != paNoError ) {}; printf("Waiting for playback to finish.\n"); fflush(stdout); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100); if( err < 0 ) {}; err = Pa_CloseStream( stream ); if( err != paNoError ) {}; printf("Done.\n"); fflush(stdout); } 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(void) { PaStreamParameters outputParameters; PaStream* stream; PaError err = paNoError; paTestData data; int totalFrames; int numSamples; int numBytes; 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; } if( err != paNoError ) goto done; FILE * pFile; long lSize; size_t result; pFile = fopen ( "recorded.raw" , "rb" ); if (pFile==NULL) { fputs ("Error opening file!",stderr); exit (1); } // obtain file size: fseek (pFile , 0 , SEEK_END); lSize = ftell (pFile); rewind (pFile); // copy the file into the buffer: result = fread( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), lSize / (NUM_CHANNELS * sizeof(SAMPLE)), pFile ); if (result != lSize / (NUM_CHANNELS * sizeof(SAMPLE))) { fputs ("Reading error, file may be corrupted\n",stderr); exit (3); } fclose (pFile); /* Playback recorded data. -------------------------------------------- */ data.frameIndex = 0; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto done; } outputParameters.channelCount = 2; /* stereo output */ outputParameters.sampleFormat = PA_SAMPLE_TYPE; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; printf("\n=== Now playing back. ===\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[]) { PaStream *stream; PaError err; patest1data data; int i; PaStreamParameters inputParameters, outputParameters; const PaHostErrorInfo* herr; printf("patest1.c\n"); fflush(stdout); printf("Ring modulate input for 20 seconds.\n"); fflush(stdout); /* initialise sinusoidal wavetable */ for( i=0; i<100; i++ ) data.sine[i] = sin( ((double)i/100.) * M_PI * 2. ); data.phase = 0; data.sampsToGo = SAMPLE_RATE * 20; /* 20 seconds. */ /* initialise portaudio subsytem */ err = Pa_Initialize(); inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: No input default device.\n"); goto done; } inputParameters.channelCount = 2; /* stereo input */ inputParameters.sampleFormat = paFloat32; /* 32 bit floating point input */ inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ if (outputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default output device.\n"); goto done; } outputParameters.channelCount = 2; /* stereo output */ outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &stream, &inputParameters, &outputParameters, (double)SAMPLE_RATE, /* Samplerate in Hertz. */ 512, /* Small buffers */ paClipOff, /* We won't output out of range samples so don't bother clipping them. */ patest1Callback, &data ); if( err != paNoError ) goto done; err = Pa_StartStream( stream ); if( err != paNoError ) goto done; printf( "Press any key to end.\n" ); fflush(stdout); getc( stdin ); /* wait for input before exiting */ err = Pa_AbortStream( stream ); if( err != paNoError ) goto done; printf( "Waiting for stream to complete...\n" ); /* sleep until playback has finished */ while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(1000); if( err < 0 ) goto done; err = Pa_CloseStream( stream ); if( err != paNoError ) goto done; done: Pa_Terminate(); if( err != paNoError ) { fprintf( stderr, "An error occured while using portaudio\n" ); if( err == paUnanticipatedHostError ) { fprintf( stderr, " unanticipated host error.\n"); herr = Pa_GetLastHostErrorInfo(); if (herr) { fprintf( stderr, " Error number: %ld\n", herr->errorCode ); if (herr->errorText) fprintf( stderr, " Error text: %s\n", herr->errorText ); } else fprintf( stderr, " Pa_GetLastHostErrorInfo() failed!\n" ); } else { fprintf( stderr, " Error number: %d\n", err ); fprintf( stderr, " Error text: %s\n", Pa_GetErrorText( err ) ); } err = 1; /* Always return 0 or 1, but no other return codes. */ } printf( "bye\n" ); return err; }
int pa_wavplayrec(SAMPLE *buffer, int buflen, int bufchannels, SAMPLE *recbuffer, int recbuffirstchannel, int recbufflastchannel, int recbuflen, int deviceID, int recdevID, int samplerate) { //mexPrintf("buflen=%i bufchannels=%i samplerate=%i\n", buflen, bufchannels, samplerate); // Make our wavData object, to pass to OpenStream. This gets given to us again in the // callback. I guess you could just have a global variable instead... paWavData wav; wav.buffer = buffer; wav.recbuffer = recbuffer; wav.buflen = buflen; wav.recbuflen = recbuflen; wav.bufchannels = bufchannels; wav.recbuffirstchan = recbuffirstchannel; wav.recbufflastchan = recbufflastchannel; wav.bufpos = 0; wav.recbufpos = 0; if (recbuffer == NULL) if (buffer == NULL) mexErrMsgTxt("recbuffer && buffer NULL in pa_wavplay"); else { mexPrintf("Playing on device %i\n", deviceID); wav.recmode = play; } else if (buffer == NULL) { mexPrintf("Recording on device %i\n", recdevID); wav.recmode = record; } else { mexPrintf("Recording on device %i\n", recdevID); mexPrintf("Playing on device %i\n", deviceID); wav.recmode = playrecord; } PaStream *stream; PaError err; err = Pa_Initialize(); if( err != paNoError ) goto error; int dev_type_indx = -1; const PaHostApiInfo* Api_Info; int num_APIs = (int )Pa_GetHostApiCount(); for (int i=0; i<num_APIs; i++) { Api_Info = Pa_GetHostApiInfo(i); if (strcmp(Api_Info->name,API_NAME)==0) dev_type_indx = i; } if (dev_type_indx == -1) { goto error; } Api_Info = Pa_GetHostApiInfo(dev_type_indx); if (recdevID != -1) recdevID = Pa_HostApiDeviceIndexToDeviceIndex(dev_type_indx, recdevID); if (deviceID != -1) deviceID = Pa_HostApiDeviceIndexToDeviceIndex(dev_type_indx, deviceID); // Open an audio I/O stream. PaWasapiStreamInfo api_info; api_info.size = sizeof(PaWasapiStreamInfo); api_info.version = 1; api_info.hostApiType = paWASAPI; api_info.flags = paWinWasapiExclusive; void *p_api_info; if ((strcmp(API_NAME, "Windows WASAPI")== 0)) { p_api_info = &api_info; } else { p_api_info = NULL; } PaStreamParameters inputParameters; // Parameters governing portaudio input stream PaStreamParameters outputParameters; // Parameters governing portaudio output stream inputParameters.channelCount = recbufflastchannel; inputParameters.device = recdevID; inputParameters.hostApiSpecificStreamInfo = p_api_info; inputParameters.sampleFormat = paFloat32; // Input data returned as floating point if (recdevID != -1) inputParameters.suggestedLatency = Pa_GetDeviceInfo(recdevID)->defaultLowInputLatency ; outputParameters.channelCount = bufchannels; outputParameters.device = deviceID; outputParameters.hostApiSpecificStreamInfo = p_api_info; outputParameters.sampleFormat = paFloat32; // Output data returned as floating point if (deviceID != -1) outputParameters.suggestedLatency = Pa_GetDeviceInfo(deviceID)->defaultLowInputLatency ; err = Pa_IsFormatSupported(NULL, &outputParameters, (double )samplerate); if (recbuffer == NULL) err = Pa_OpenStream( &stream, NULL, &outputParameters, samplerate, // stream sample rate BLOCK, // frames per buffer paNoFlag, // stream flag (PaStreamCallback (__cdecl *))paWavCallback, // callback function &wav); // user data else if (buffer == NULL) err = Pa_OpenStream( &stream, &inputParameters, NULL, samplerate, // stream sample rate BLOCK, // frames per buffer paNoFlag, // stream flag (PaStreamCallback (__cdecl *))paWavCallback, // callback function &wav); // user data else err = Pa_OpenStream( &stream, &inputParameters, &outputParameters, samplerate, // stream sample rate BLOCK, // frames per buffer paNoFlag, // stream flag (PaStreamCallback (__cdecl *))paWavCallback, // callback function &wav); // user data if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; // sleep while stream's active while( Pa_IsStreamActive(stream) ) Pa_Sleep( 50 ); if (err = Pa_IsStreamStopped( stream ) == 0) { err = Pa_StopStream( stream ); if( err != paNoError ) goto error; } else if (err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); return err; // wtf? A goto? Yeah, that's leftover from the portaudio example code error: Pa_Terminate(); mexPrintf( "An error occured while using the portaudio stream\n" ); mexPrintf( "Error number: %d\n", err ); mexPrintf( "Error message: %s\n", Pa_GetErrorText( err ) ); return err; }
int main(void) { PaStreamParameters outputParameters; PaStream* stream; PaError err; paTestData data; PaTime streamOpened; int i, 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; 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 = TEST_FORMAT; outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &stream, NULL, /* No input. */ &outputParameters, SAMPLE_RATE, 256, /* 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; streamOpened = Pa_GetStreamTime( stream ); /* Time in seconds when stream was opened (approx). */ err = Pa_StartStream( stream ); if( err != paNoError ) goto error; /* Watch until sound is halfway finished. */ /* (Was ( Pa_StreamTime( stream ) < (totalSamps/2) ) in V18. */ while( (Pa_GetStreamTime( stream ) - streamOpened) < (PaTime)NUM_SECONDS / 2.0 ) Pa_Sleep(10); /* Stop sound. */ printf("Stopping Stream.\n"); err = Pa_StopStream( stream ); if( err != paNoError ) goto error; printf("Pause for 2 seconds.\n"); Pa_Sleep( 2000 ); printf("Starting again.\n"); err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Waiting for sound to finish.\n"); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100); if( err < 0 ) 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 selectDevice() { int i, numDevices, defaultDisplayed; const PaDeviceInfo *deviceInfo; PaStreamParameters inputParameters, outputParameters; PaStream* stream; PaError err; paTestData data; int totalFrames; int numSamples; int numBytes; char devSelection[4]; int devSelectInt; err = Pa_Initialize(); if( err != paNoError ) { printf( "ERROR: Pa_Initialize returned 0x%x\n", err ); goto error; } printf( "PortAudio version: 0x%08X\n", Pa_GetVersion()); printf( "Version text: '%s'\n", Pa_GetVersionInfo()->versionText ); numDevices = Pa_GetDeviceCount(); if( numDevices < 0 ) { printf( "ERROR: Pa_GetDeviceCount returned 0x%x\n", numDevices ); err = numDevices; goto error; } printf( "Number of devices = %d\n", numDevices ); for( i=0; i<numDevices; i++ ) { deviceInfo = Pa_GetDeviceInfo( i ); printf( "--------------------------------------- device #%d\n", i ); /* Mark global and API specific default devices */ defaultDisplayed = 0; if( i == Pa_GetDefaultInputDevice() ) { printf( "[ Default Input" ); defaultDisplayed = 1; } else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice ) { const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi ); printf( "[ Default %s Input", hostInfo->name ); defaultDisplayed = 1; } if( i == Pa_GetDefaultOutputDevice() ) { printf( (defaultDisplayed ? "," : "[") ); printf( " Default Output" ); defaultDisplayed = 1; } else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice ) { const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi ); printf( (defaultDisplayed ? "," : "[") ); printf( " Default %s Output", hostInfo->name ); defaultDisplayed = 1; } if( defaultDisplayed ) printf( " ]\n" ); /* print device info fields */ #ifdef WIN32 { /* Use wide char on windows, so we can show UTF-8 encoded device names */ wchar_t wideName[MAX_PATH]; MultiByteToWideChar(CP_UTF8, 0, deviceInfo->name, -1, wideName, MAX_PATH-1); wprintf( L"Name = %s\n", wideName ); } #else printf( "Name = %s\n", deviceInfo->name ); #endif printf( "Host API = %s\n", Pa_GetHostApiInfo( deviceInfo->hostApi )->name ); printf( "Max inputs = %d", deviceInfo->maxInputChannels ); printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels ); printf( "Default low input latency = %8.4f\n", deviceInfo->defaultLowInputLatency ); printf( "Default low output latency = %8.4f\n", deviceInfo->defaultLowOutputLatency ); printf( "Default high input latency = %8.4f\n", deviceInfo->defaultHighInputLatency ); printf( "Default high output latency = %8.4f\n", deviceInfo->defaultHighOutputLatency ); #ifdef WIN32 #if PA_USE_ASIO /* ASIO specific latency information */ if( Pa_GetHostApiInfo( deviceInfo->hostApi )->type == paASIO ){ long minLatency, maxLatency, preferredLatency, granularity; err = PaAsio_GetAvailableLatencyValues( i, &minLatency, &maxLatency, &preferredLatency, &granularity ); printf( "ASIO minimum buffer size = %ld\n", minLatency ); printf( "ASIO maximum buffer size = %ld\n", maxLatency ); printf( "ASIO preferred buffer size = %ld\n", preferredLatency ); if( granularity == -1 ) printf( "ASIO buffer granularity = power of 2\n" ); else printf( "ASIO buffer granularity = %ld\n", granularity ); } #endif /* PA_USE_ASIO */ #endif /* WIN32 */ printf( "Default sample rate = %8.2f\n", deviceInfo->defaultSampleRate ); /* poll for standard sample rates */ inputParameters.device = i; inputParameters.channelCount = deviceInfo->maxInputChannels; inputParameters.sampleFormat = paInt16; inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ inputParameters.hostApiSpecificStreamInfo = NULL; outputParameters.device = i; outputParameters.channelCount = deviceInfo->maxOutputChannels; outputParameters.sampleFormat = paInt16; outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */ outputParameters.hostApiSpecificStreamInfo = NULL; if( inputParameters.channelCount > 0 ) { printf("Supported standard sample rates\n for half-duplex 16 bit %d channel input = \n", inputParameters.channelCount ); PrintSupportedStandardSampleRates( &inputParameters, NULL ); } if( outputParameters.channelCount > 0 ) { printf("Supported standard sample rates\n for half-duplex 16 bit %d channel output = \n", outputParameters.channelCount ); PrintSupportedStandardSampleRates( NULL, &outputParameters ); } if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 ) { printf("Supported standard sample rates\n for full-duplex 16 bit %d channel input, %d channel output = \n", inputParameters.channelCount, outputParameters.channelCount ); PrintSupportedStandardSampleRates( &inputParameters, &outputParameters ); } } /* for numDevices */ printf("What input device would you like to use? "); fgets(devSelection, 4, stdin); devSelectInt = atoi(devSelection); if(devSelectInt < numDevices) { printf("Hooray! You chose device %s, which is within bounds.\n", devSelection); inputParameters.device = devSelectInt; if(inputParameters.device == paNoDevice) { fprintf(stderr,"Error: input device at that device number.\n"); goto error; } // if - no device 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 error; } for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0; 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 error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) { Pa_Sleep(100); printf("index = %d; amplitude = %f\n", data.frameIndex, data.recordedSamples[data.frameIndex] ); fflush(stdout); } if( err < 0 ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; } // if - device number within bounds Pa_Terminate(); printf("----------------------------------------------\n"); return 0; error: Pa_Terminate(); fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); return err; } /* selectDevice */
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 */ if (inputParameters.device == paNoDevice) { fprintf(stderr, "Error: No default input device.\n"); goto done; } inputParameters.channelCount = 1; /* stereo input */ inputParameters.sampleFormat = PA_SAMPLE_TYPE; inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; //set a keyboard hit to start recording. Added by Yao Canwu printf("Press any key to start recording\n"); while (!kbhit()){} /* 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("\n=== Now start recording!!\n"); fflush(stdout); /* Pa_IsStreamActive: Determine whether the stream is active. A stream is active after a successful call to Pa_StartStream(), until it becomes inactive either as a result of a call to Pa_StopStream() or Pa_AbortStream(), or as a result of a return value other than paContinue from the stream callback. In the latter case, the stream is considered inactive after the last buffer has finished playing. */ 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; //Write wave to file in wav formate. Added by Yao Canwu printf("Waiting to save into file...\n"); char *path = "audio.wav"; WriteWave(path, data.recordedSamples, data.maxFrameIndex, SAMPLE_RATE); printf("Save successfully!\n"); /* Write recorded data to a file. */ #if WRITE_TO_FILE { 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 */ if (outputParameters.device == paNoDevice) { fprintf(stderr, "Error: No default output device.\n"); goto done; } outputParameters.channelCount = 1; /* stereo output */ outputParameters.sampleFormat = PA_SAMPLE_TYPE; outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; printf("\n=== Now playing back. ===\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. */ } system("pause"); return err; }
void playSynthesizedVoice (dsd_opts * opts, dsd_state * state) { ssize_t result; if (state->audio_out_idx > opts->delay) { // output synthesized speech to sound card if(opts->audio_out_type == 2) { #ifdef USE_PORTAUDIO PaError err = paNoError; do { long available = Pa_GetStreamWriteAvailable( opts->audio_out_pa_stream ); if(available < 0) err = available; //printf("Frames available: %d\n", available); if( err != paNoError ) break; if(available > SAMPLE_RATE_OUT * PA_LATENCY_OUT) { //It looks like this might not be needed for very small latencies. However, it's definitely needed for a bit larger ones. //When PA_LATENCY_OUT == 0.500 I get output buffer underruns if I don't use this. With PA_LATENCY_OUT <= 0.100 I don't see those happen. //But with PA_LATENCY_OUT < 0.100 I run the risk of choppy audio and stream errors. printf("\nSyncing voice output stream\n"); err = Pa_StopStream( opts->audio_out_pa_stream ); if( err != paNoError ) break; } err = Pa_IsStreamActive( opts->audio_out_pa_stream ); if(err == 0) { printf("Start voice output stream\n"); err = Pa_StartStream( opts->audio_out_pa_stream ); } else if(err == 1) { err = paNoError; } if( err != paNoError ) break; //printf("write stream %d\n", state->audio_out_idx); err = Pa_WriteStream( opts->audio_out_pa_stream, (state->audio_out_buf_p - state->audio_out_idx), state->audio_out_idx ); if( err != paNoError ) break; } while(0); if( err != paNoError ) { fprintf( stderr, "An error occured while using the portaudio output stream\n" ); fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); } #endif } else if (opts->audio_out_fd == -1) { memcpy(state->output_buffer + state->output_offset, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2)); state->output_offset += state->audio_out_idx; } else { result = write (opts->audio_out_fd, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2)); } state->audio_out_idx = 0; } if (state->audio_out_idx2 >= 800000) { state->audio_out_float_buf_p = state->audio_out_float_buf + 100; state->audio_out_buf_p = state->audio_out_buf + 100; memset (state->audio_out_float_buf, 0, 100 * sizeof (float)); memset (state->audio_out_buf, 0, 100 * sizeof (short)); state->audio_out_idx2 = 0; } }
JNIEXPORT jboolean JNICALL Java_org_jpab_PortAudio_isStreamActive(JNIEnv *env, jclass paClass, jlong stream_id) { PaError error = (UINT32) Pa_IsStreamActive((PaStream *) stream_id); if (error < 0) org_jpab_throw_exception(env, (PaError *) &error); return error == 1 ? JNI_TRUE : JNI_FALSE; }
bool PortAudioHelper::isRecording() const { return Pa_IsStreamActive( stream ); }
int AudioDevice_isActive(AudioDevice *self) { return AudioDevice_isOpen(self) ? Pa_IsStreamActive( self->stream ) : 0; }
int patestMain(void) { PaError err; PaStream *stream; paTestData data; // int totalFrames; int numSamples; int totalBytes; int i; PaStreamParameters inputParameters; int targetDevId = 0; float currEnergy = 0.0; FILE *fid; fid = fopen("recorded.raw", "ab"); if( fid == NULL ) { fprintf(stderr, "Could not open file.\n"); return 3; } // preparing the buffer data.maxFrameIndex = numSamples = BUF_SECONDS * SAMPLE_RATE; // totalBytes = numSamples * sizeof(C_DATA_TYPE); data.recordedSamples = (C_DATA_TYPE *) malloc (numSamples * sizeof(C_DATA_TYPE)); for (i = 0; i < numSamples; i++) { data.recordedSamples[i] = 0; } // check device // targetDevId = patestCheckDevice(); targetDevId = Pa_GetDefaultInputDevice(); fprintf(stderr, "Using device ID %d\n", targetDevId); // preparing the parameters inputParameters.device = targetDevId; inputParameters.channelCount = NUM_CHANNELS; inputParameters.sampleFormat = PA_DATA_TYPE; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; fprintf(stderr, "\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stderr); while (1) { data.frameIndex = 0; // Opens stream err = Pa_OpenStream( &stream, &inputParameters, NULL, /* &outputParameters, */ SAMPLE_RATE, // FRAMES_PER_BUFFER, paFramesPerBufferUnspecified, paClipOff, /* we won't output out of range samples so don't bother clipping them */ recordCallback, &data ); if (err != paNoError) { fprintf(stderr, "Error: %s\n", Pa_GetErrorText(err)); } // start the stream err = Pa_StartStream( stream ); if (Pa_IsStreamActive(stream) != 1) { fprintf(stderr, "Stream not active ... \n"); } while((err = Pa_IsStreamActive(stream)) == 1) { Pa_Sleep(100); fprintf(stderr, "index = %d\n", data.frameIndex ); fflush(stderr); } // write the recorded audio to file fwrite(data.recordedSamples, sizeof(C_DATA_TYPE), data.maxFrameIndex, fid); fprintf(stderr, "Wrote %d bytes to 'recorded.raw'\n", data.maxFrameIndex * sizeof(C_DATA_TYPE)); // compute the energy of each frame // for (i = 0; i < numSamples; i+=100) { // float frameEnergy(C_DATA_TYPE *samples, long sampleLen, long frameIdx, int frameSpan) { // currEnergy = frameEnergy(data.recordedSamples, numSamples, i, 10); // fprintf(stderr, "Energy at frame %d: %f\n", i, currEnergy); // } } fclose( fid ); err = Pa_StopStream(stream); err = Pa_CloseStream(stream); free(data.recordedSamples); return 0; }
static int wave_open_sound() { PaError err = paNoError; PaError active; #if USE_PORTAUDIO == 18 active = Pa_StreamActive(pa_stream); #else active = Pa_IsStreamActive(pa_stream); #endif if (active == 1) return 0; if (active < 0) { out_channels = 1; #if USE_PORTAUDIO == 18 err = Pa_OpenStream(&pa_stream, // capture parameters paNoDevice, 0, paInt16, NULL, // playback parameters myOutputDevice, out_channels, paInt16, NULL, // general parameters wave_samplerate, FRAMES_PER_BUFFER, 0, paNoFlag, pa_callback, (void *)userdata); if (err == paInvalidChannelCount) { // failed to open with mono, try stereo out_channels = 2; err = Pa_OpenStream(&pa_stream, // capture parameters paNoDevice, 0, paInt16, NULL, // playback parameters myOutputDevice, out_channels, paInt16, NULL, // general parameters wave_samplerate, FRAMES_PER_BUFFER, 0, paNoFlag, pa_callback, (void *)userdata); } mInCallbackFinishedState = false; // v18 only #else myOutputParameters.channelCount = out_channels; unsigned long framesPerBuffer = paFramesPerBufferUnspecified; err = Pa_OpenStream(&pa_stream, NULL, // no input &myOutputParameters, wave_samplerate, framesPerBuffer, paNoFlag, pa_callback, (void *)userdata); if ((err != paNoError) && (err != paInvalidChannelCount)) { fprintf(stderr, "wave_open_sound > Pa_OpenStream : err=%d (%s)\n", err, Pa_GetErrorText(err)); framesPerBuffer = FRAMES_PER_BUFFER; err = Pa_OpenStream(&pa_stream, NULL, // no input &myOutputParameters, wave_samplerate, framesPerBuffer, paNoFlag, pa_callback, (void *)userdata); } if (err == paInvalidChannelCount) { // failed to open with mono, try stereo out_channels = 2; myOutputParameters.channelCount = out_channels; err = Pa_OpenStream(&pa_stream, NULL, // no input &myOutputParameters, wave_samplerate, framesPerBuffer, paNoFlag, pa_callback, (void *)userdata); } mInCallbackFinishedState = false; #endif } return err != paNoError; }
int main(int argc, char* argv[]) { PaStream *stream; PaError err; patest1data data; int i; int inputDevice = Pa_GetDefaultInputDevice(); int outputDevice = Pa_GetDefaultOutputDevice(); /* initialise sinusoidal wavetable */ for( i=0; i<100; i++ ) data.sine[i] = sin( ((double)i/100.) * M_PI * 2. ); data.phase = 0; data.sampsToGo = 44100 * 20; // 20 seconds /* initialise portaudio subsytem */ Pa_Initialize(); err = Pa_OpenStream( &stream, inputDevice, 2, /* stereo input */ paFloat32, /* 32 bit floating point input */ NULL, outputDevice, 2, /* stereo output */ paFloat32, /* 32 bit floating point output */ NULL, 44100., 512, /* small buffers */ 0, /* let PA determine number of buffers */ paClipOff, /* we won't output out of range samples so don't bother clipping them */ patest1Callback, &data ); if( err == paNoError ) { err = Pa_StartStream( stream ); printf( "Press any key to end.\n" ); getc( stdin ); //wait for input before exiting Pa_AbortStream( stream ); printf( "Waiting for stream to complete...\n" ); while( Pa_IsStreamActive( stream ) ) Pa_Sleep(1000); /* sleep until playback has finished */ err = Pa_CloseStream( stream ); } else { fprintf( stderr, "An error occured while opening the portaudio stream\n" ); if( err == paHostError ) { fprintf( stderr, "Host error number: %d\n", Pa_GetHostError() ); } else { fprintf( stderr, "Error number: %d\n", err ); fprintf( stderr, "Error text: %s\n", Pa_GetErrorText( err ) ); } } Pa_Terminate(); printf( "bye\n" ); return 0; }
int main(void) { PaStreamParameters inputParameters, outputParameters; PaStream* stream; PaError err = paNoError; paTestData data; int totalFrames; int numSamples; int numBytes; SAMPLE max, val; double average; struct sockaddr_in myaddr, remaddr; int fd, i, slen=sizeof(remaddr); char buf[BUFLEN]; /* message buffer */ int recvlen; /* # bytes in acknowledgement message */ char *server = "127.0.0.1"; /* change this to use a different server */ /* create a socket */ if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) printf("socket created\n"); /* bind it to all local addresses and pick any port number */ memset((char *)&myaddr, 0, sizeof(myaddr)); myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = htonl(INADDR_ANY); myaddr.sin_port = htons(0); if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { perror("bind failed"); return 0; } /* now define remaddr, the address to whom we want to send messages */ /* For convenience, the host address is expressed as a numeric IP address */ /* that we will convert to a binary format via inet_aton */ memset((char *) &remaddr, 0, sizeof(remaddr)); remaddr.sin_family = AF_INET; remaddr.sin_port = htons(SERVICE_PORT); if (inet_aton(server, &remaddr.sin_addr)==0) { fprintf(stderr, "inet_aton() failed\n"); exit(1); } data.fd = fd; data.remaddr = (struct sockaddr *) &remaddr; data.slen = slen; err = Pa_Initialize(); if( err != paNoError ) exit(1); inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default input device.\n"); exit(1); } 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 */ sendCallback, &data ); if( err != paNoError ) exit(1); err = Pa_StartStream( stream ); if( err != paNoError ) exit(1); printf("\n=== Now listenning!! Please speak into the microphone. ===\n"); fflush(stdout); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) { Pa_Sleep(1000); printf("index = \n"); fflush(stdout); } if( err < 0 ) exit(1); err = Pa_CloseStream( stream ); if( err != paNoError ) exit(1); /* now let's send the messages */ //close(fd); return 0; }
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 *instream, *outstream; PaStreamParameters inputParameters, outputParameters; // PaStreamInfo *streamInfo; int nSampleRate = *nfsample; int ndevice_in = *ndevin; int ndevice_out = *ndevout; double dSampleRate = (double) *nfsample; PaError err_init, err_open_in, err_open_out, err_start_in, err_start_out; PaError err = 0; 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 = nSampleRate; data.trperiod = TRPeriod; err_init = Pa_Initialize(); // Initialize PortAudio if(err_init) { printf("Error initializing PortAudio.\n"); printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_init), err_init); Pa_Terminate(); // I don't think we need this but... return(-1); } // printf("Opening device %d for input, %d for output...\n",ndevice_in,ndevice_out); inputParameters.device = ndevice_in; inputParameters.channelCount = 2; inputParameters.sampleFormat = paInt16; inputParameters.suggestedLatency = 1.0; inputParameters.hostApiSpecificStreamInfo = NULL; // Test if this configuration actually works, so we do not run into an ugly assertion err_open_in = Pa_IsFormatSupported(&inputParameters, NULL, dSampleRate); if (err_open_in == 0) { err_open_in = Pa_OpenStream( &instream, //address of stream &inputParameters, NULL, dSampleRate, //Sample rate 2048, //Frames per buffer paNoFlag, (PaStreamCallback *)SoundIn, //Callback routine (void *)&data); //address of data structure if(err_open_in) { // We should have no error here usually printf("Error opening input audio stream:\n"); printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), err_open_in); err = 1; } else { // printf("Successfully opened audio input.\n"); } } else { printf("Error opening input audio stream.\n"); printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_in), err_open_in); err = 1; } outputParameters.device = ndevice_out; outputParameters.channelCount = 2; outputParameters.sampleFormat = paInt16; outputParameters.suggestedLatency = 1.0; outputParameters.hostApiSpecificStreamInfo = NULL; // Test if this configuration actually works, so we do not run into an ugly assertion err_open_out = Pa_IsFormatSupported(NULL, &outputParameters, dSampleRate); if (err_open_out == 0) { err_open_out = Pa_OpenStream( &outstream, //address of stream NULL, &outputParameters, dSampleRate, //Sample rate 2048, //Frames per buffer paNoFlag, (PaStreamCallback *)SoundOut, //Callback routine (void *)&data); //address of data structure if(err_open_out) { // We should have no error here usually printf("Error opening output audio stream!\n"); printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), err_open_out); err += 2; } else { // printf("Successfully opened audio output.\n"); } } else { printf("Error opening output audio stream.\n"); printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_open_out), err_open_out); err += 2; } // if there was no error in opening both streams start them if (err == 0) { err_start_in = Pa_StartStream(instream); //Start input stream if(err_start_in) { printf("Error starting input audio stream!\n"); printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_in), err_start_in); err += 4; } err_start_out = Pa_StartStream(outstream); //Start output stream if(err_start_out) { printf("Error starting output audio stream!\n"); printf("\tErrortext: %s\n\tNumber: %d\n",Pa_GetErrorText(err_start_out), err_start_out); err += 8; } } if (err == 0) printf("Audio streams running normally.\n******************************************************************\n"); while( Pa_IsStreamActive(instream) && (*ngo != 0) && (err == 0) ) { // printf("CPU: %.1f\%\n",100*Pa_GetStreamCpuLoad(instream)); Pa_Sleep(200); } Pa_AbortStream(instream); // Abort stream Pa_CloseStream(instream); // Close stream, we're done. Pa_AbortStream(outstream); // Abort stream Pa_CloseStream(outstream); // Close stream, we're done. Pa_Terminate(); return(err); }
static void *output_thread(void *ptr) { int err; int output_buffer_size; #ifndef PORTAUDIO_DEV int num_mixers, nbVolumes, volumeIdx; #endif struct timeval now; struct timespec timeout; slimaudio_t *audio = (slimaudio_t *) ptr; audio->output_STMs = false; audio->output_STMu = false; err = Pa_Initialize(); if (err != paNoError) { printf("PortAudio error4: %s Could not open any audio devices.\n", Pa_GetErrorText(err) ); exit(-1); } if ( audio->renice ) if ( slimproto_renice_thread (-5) ) /* Increase priority */ fprintf(stderr, "output_thread: renice failed. Got Root?\n"); #ifndef PORTAUDIO_DEV DEBUGF("output_thread: output_device_id : %i\n", audio->output_device_id ); DEBUGF("output_thread: pa_framesPerBuffer: %lu\n", pa_framesPerBuffer ); DEBUGF("output_thread: pa_numberOfBuffers: %lu\n", pa_numberOfBuffers ); err = Pa_OpenStream( &audio->pa_stream, /* stream */ paNoDevice, /* input device */ 0, /* input channels */ 0, /* input sample format */ NULL, /* input driver info */ audio->output_device_id,/* output device */ 2, /* output channels */ paInt16, /* output sample format */ NULL, /* output driver info */ 44100.0, /* sample rate */ pa_framesPerBuffer, /* frames per buffer */ pa_numberOfBuffers, /* number of buffers */ paNoFlag, /* stream flags */ pa_callback, /* callback */ audio); /* user data */ #else PaStreamParameters outputParameters; const PaDeviceInfo * paDeviceInfo; float newLatency; #ifdef PADEV_WASAPI PaWasapiStreamInfo streamInfo; const PaHostApiInfo *paHostApiInfo; #endif paDeviceInfo = Pa_GetDeviceInfo(audio->output_device_id); /* Device is not stereo or better, abort */ if (paDeviceInfo->maxOutputChannels < 2) { printf("output_thread: PortAudio device does not support 44.1KHz, 16-bit, stereo audio.\n"); printf("output_thread: Use -L for a list of supported audio devices, then use -o followed\n"); printf("output_thread: by the device number listed before the colon. See -h for details.\n"); exit(-2); } outputParameters.device = audio->output_device_id; #ifdef SLIMPROTO_ZONES outputParameters.channelCount = 2 * audio->output_num_zones; #else outputParameters.channelCount = 2; #endif outputParameters.sampleFormat = paInt16; outputParameters.suggestedLatency = paDeviceInfo->defaultHighOutputLatency; if ( audio->modify_latency ) { newLatency = (float) audio->user_latency / 1000.0; if ( ( newLatency > 1.0 ) || ( newLatency <= paDeviceInfo->defaultLowOutputLatency ) ) { fprintf (stderr, "User defined latency %f out of range %f-1.0, using default.\n", newLatency, paDeviceInfo->defaultLowOutputLatency ); newLatency = paDeviceInfo->defaultHighOutputLatency; } outputParameters.suggestedLatency = newLatency ; } #ifdef PADEV_WASAPI /* Use exclusive mode for WASAPI device, default is shared */ paHostApiInfo = Pa_GetHostApiInfo ( paDeviceInfo->hostApi ); if ( paHostApiInfo != NULL ) { if ( paHostApiInfo->type == paWASAPI ) { /* Use exclusive mode for WasApi device, default is shared */ if (wasapi_exclusive) { streamInfo.size = sizeof(PaWasapiStreamInfo); streamInfo.hostApiType = paWASAPI; streamInfo.version = 1; streamInfo.flags = paWinWasapiExclusive; outputParameters.hostApiSpecificStreamInfo = &streamInfo; DEBUGF("WASAPI: Exclusive\n"); } else { outputParameters.hostApiSpecificStreamInfo = NULL; DEBUGF("WASAPI: Shared\n"); } } } #else outputParameters.hostApiSpecificStreamInfo = NULL; #endif DEBUGF("paDeviceInfo->deviceid %d\n", outputParameters.device); DEBUGF("paDeviceInfo->maxOutputChannels %i\n", paDeviceInfo->maxOutputChannels); DEBUGF("outputParameters.suggestedLatency %f\n", outputParameters.suggestedLatency); DEBUGF("paDeviceInfo->defaultHighOutputLatency %f\n", (float) paDeviceInfo->defaultHighOutputLatency); DEBUGF("paDeviceInfo->defaultLowOutputLatency %f\n", (float) paDeviceInfo->defaultLowOutputLatency); DEBUGF("paDeviceInfo->defaultSampleRate %f\n", paDeviceInfo->defaultSampleRate); err = Pa_OpenStream ( &audio->pa_stream, /* stream */ NULL, /* inputParameters */ &outputParameters, /* outputParameters */ 44100.0, /* sample rate */ paFramesPerBufferUnspecified, /* framesPerBuffer */ paPrimeOutputBuffersUsingStreamCallback, /* streamFlags */ pa_callback, /* streamCallback */ audio); /* userData */ #endif #ifdef BSD_THREAD_LOCKING pthread_mutex_lock(&audio->output_mutex); #endif if (err != paNoError) { printf("output_thread: PortAudio error1: %s\n", Pa_GetErrorText(err) ); exit(-1); } #ifndef PORTAUDIO_DEV num_mixers = Px_GetNumMixers(audio->pa_stream); while (--num_mixers >= 0) { DEBUGF("Mixer: %s\n", Px_GetMixerName(audio->pa_stream, num_mixers)); } if (audio->volume_control == VOLUME_DRIVER) { DEBUGF("Opening mixer.\n" ); audio->px_mixer = Px_OpenMixer(audio->pa_stream, 0); } if (audio->px_mixer != NULL) { DEBUGF("Px_mixer = %p\n", audio->px_mixer); DEBUGF("PCM volume supported: %d.\n", Px_SupportsPCMOutputVolume(audio->px_mixer)); nbVolumes = Px_GetNumOutputVolumes(audio->px_mixer); DEBUGF("Nb volumes supported: %d.\n", nbVolumes); for (volumeIdx=0; volumeIdx<nbVolumes; ++volumeIdx) { DEBUGF("Volume %d: %s\n", volumeIdx, Px_GetOutputVolumeName(audio->px_mixer, volumeIdx)); } } #endif while (audio->output_state != QUIT) { switch (audio->output_state) { case STOPPED: audio->decode_num_tracks_started = 0L; audio->stream_samples = 0UL; audio->pa_streamtime_offset = audio->stream_samples; DEBUGF("output_thread STOPPED: %llu\n",audio->pa_streamtime_offset); slimaudio_buffer_set_readopt(audio->output_buffer, BUFFER_BLOCKING); case PAUSED: /* We report ourselves to the server every few seconds ** as a keep-alive. This is required for Squeezebox Server ** v6.5.x although technically, "stat" is not a valid event ** code for the STAT Client->Server message. This was ** lifted by observing how a Squeezebox3 reports itself to ** the server using Squeezebox Server's d_slimproto and ** d_slimproto_v tracing services. Note that Squeezebox3 ** seems to report every 1 second or so, but the server only ** drops the connection after 15-20 seconds of inactivity. */ DEBUGF("output_thread PAUSED: %llu\n",audio->pa_streamtime_offset); if (audio->keepalive_interval <= 0) { pthread_cond_wait(&audio->output_cond, &audio->output_mutex); } else { gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec + audio->keepalive_interval; timeout.tv_nsec = now.tv_usec * 1000; err = pthread_cond_timedwait(&audio->output_cond, &audio->output_mutex, &timeout); if (err == ETIMEDOUT) { DEBUGF("Sending keepalive. Interval=%ds.\n", audio->keepalive_interval); output_thread_stat(audio, "stat"); } } break; case PLAY: audio->output_predelay_frames = audio->output_predelay_msec * 44.100; DEBUGF("output_thread PLAY: output_predelay_frames: %i\n", audio->output_predelay_frames); output_buffer_size = slimaudio_buffer_available(audio->output_buffer); DEBUGF("output_thread BUFFERING: output_buffer_size: %i output_threshold: %i", output_buffer_size, audio->output_threshold); DEBUGF(" buffering_timeout: %i\n", audio->buffering_timeout); if ( (output_buffer_size < audio->output_threshold) && (audio->buffering_timeout > 0) ) { pthread_mutex_unlock(&audio->output_mutex); pthread_cond_broadcast(&audio->output_cond); Pa_Sleep(100); pthread_mutex_lock(&audio->output_mutex); audio->buffering_timeout--; } else { DEBUGF("output_thread PLAY: start stream: %llu\n", audio->pa_streamtime_offset); audio->buffering_timeout = BUFFERING_TIMEOUT; err = Pa_StartStream(audio->pa_stream); if (err != paNoError) { printf("output_thread: PortAudio error2: %s\n", Pa_GetErrorText(err)); exit(-1); } audio->output_state = PLAYING; pthread_cond_broadcast(&audio->output_cond); } break; case BUFFERING: DEBUGF("output_thread BUFFERING: %llu\n",audio->pa_streamtime_offset); case PLAYING: gettimeofday(&now, NULL); timeout.tv_sec = now.tv_sec + 1; timeout.tv_nsec = now.tv_usec * 1000; err = pthread_cond_timedwait(&audio->output_cond, &audio->output_mutex, &timeout); if (err == ETIMEDOUT) { DEBUGF("output_thread ETIMEDOUT-PLAYING: %llu\n",audio->pa_streamtime_offset); output_thread_stat(audio, "STMt"); } /* Track started */ if (audio->output_STMs) { audio->output_STMs = false; audio->decode_num_tracks_started++; audio->replay_gain = audio->start_replay_gain; slimaudio_output_vol_adjust(audio); audio->pa_streamtime_offset = audio->stream_samples; DEBUGF("output_thread STMs-PLAYING: %llu\n",audio->pa_streamtime_offset); output_thread_stat(audio, "STMs"); } /* Data underrun ** On buffer underrun causes the server to switch to the next track. */ if (audio->output_STMu) { audio->output_STMu = false; audio->output_state = STOP; DEBUGF("output_thread STMu-PLAYING: %llu\n",audio->pa_streamtime_offset); output_thread_stat(audio, "STMu"); pthread_cond_broadcast(&audio->output_cond); } break; case STOP: #ifndef PORTAUDIO_DEV if ( (err = Pa_StreamActive(audio->pa_stream) ) > 0) { err = Pa_StopStream(audio->pa_stream); if (err != paNoError) { printf("output_thread: PortAudio error3: %s\n", Pa_GetErrorText(err) ); exit(-1); } } else { if ( err != paNoError) { printf("output_thread: PortAudio error9: %s\n", Pa_GetErrorText(err) ); exit(-1); } } #else if ( (err = Pa_IsStreamActive(audio->pa_stream)) > 0) { err = Pa_StopStream(audio->pa_stream); if (err != paNoError) { printf("output_thread[STOP]: PortAudio error3: %s\n", Pa_GetErrorText(err) ); exit(-1); } } else if ( err != paNoError) { printf("output_thread[STOP ISACTIVE]: PortAudio error3: %s\n", Pa_GetErrorText(err) ); exit(-1); } #endif audio->output_state = STOPPED; DEBUGF("output_thread STOP: %llu\n",audio->pa_streamtime_offset); pthread_cond_broadcast(&audio->output_cond); break; case PAUSE: #ifndef PORTAUDIO_DEV if ( (err = Pa_StreamActive(audio->pa_stream) ) > 0) { err = Pa_StopStream(audio->pa_stream); if (err != paNoError) { printf("output_thread: PortAudio error10: %s\n", Pa_GetErrorText(err)); exit(-1); } } else { if ( err != paNoError) { printf("output_thread: PortAudio error11: %s\n", Pa_GetErrorText(err) ); exit(-1); } } #else if ( (err = Pa_IsStreamActive(audio->pa_stream)) > 0) { err = Pa_StopStream(audio->pa_stream); if (err != paNoError) { printf("output_thread[PAUSE]: PortAudio error3: %s\n", Pa_GetErrorText(err) ); exit(-1); } } else if ( err != paNoError) { printf("output_thread[PAUSE ISACTIVE]: PortAudio error3: %s\n", Pa_GetErrorText(err) ); exit(-1); } #endif audio->output_state = PAUSED; DEBUGF("output_thread PAUSE: %llu\n",audio->pa_streamtime_offset); pthread_cond_broadcast(&audio->output_cond); break; case QUIT: DEBUGF("output_thread QUIT: %llu\n",audio->pa_streamtime_offset); break; } } pthread_mutex_unlock(&audio->output_mutex); #ifndef PORTAUDIO_DEV if (audio->px_mixer != NULL) { Px_CloseMixer(audio->px_mixer); audio->px_mixer = NULL; } #endif err = Pa_CloseStream(audio->pa_stream); if (err != paNoError) { printf("output_thread[exit]: PortAudio error3: %s\n", Pa_GetErrorText(err) ); exit(-1); } audio->pa_stream = NULL; Pa_Terminate(); DEBUGF("output_thread: PortAudio terminated\n"); return 0; }
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 run_filter(AudioOptions audio_options) { PaStreamParameters input_parameters, output_parameters; PaStream *input_stream = NULL, *output_stream = NULL; PaError err = paNoError; CircularBuffer * output_buffer = CircularBuffer_create(audio_options.buffer_size); CircularBuffer * input_buffer = NULL; CircularBuffer * decoder_input = NULL; DecodingBuffer * decoder_buffer = NULL; int live_stream = !audio_options.wav_path || !strlen(audio_options.wav_path); OSFilter * filter = OSFilter_create( audio_options.filters, audio_options.num_filters, 2, audio_options.filter_size, audio_options.conv_multiple * (audio_options.filter_size - 1), audio_options.input_scale ); if (!filter) { goto done; } if ((err = Pa_Initialize()) != paNoError) { goto done; } int step_size = audio_options.filter_size - 1; RecordCallbackMetadata record_data = { NULL, 0, 0, audio_options.number_of_channels, audio_options.enabled_channels, 0 }; { int num_enabled_channels = 0; for (int i = 0; i < audio_options.number_of_channels; ++i) { if (audio_options.enabled_channels & (1 << i)) { num_enabled_channels++; } } if (num_enabled_channels != audio_options.enabled_channels) { record_data.stripe_input = 1; } if (num_enabled_channels == 0) { record_data.stripe_input = 0; } } if (record_data.stripe_input) { printf("striping record_data: %d channels with %d enabled flag\n", record_data.number_of_channels, record_data.enabled_channels ); } else { printf("NOT striping record_data: %d channels with %d enabled flag\n", record_data.number_of_channels, record_data.enabled_channels ); } if (live_stream) { input_buffer = CircularBuffer_create(audio_options.buffer_size); if (audio_options.decode_input) { decoder_input = CircularBuffer_create(audio_options.buffer_size); decoder_buffer = Decoding_new(decoder_input, input_buffer); record_data.buffer = decoder_input; if (!Decoding_start_ac3(decoder_buffer)) { printf("Failed to start ac3 decoder thread.\n"); goto done; } } else { record_data.buffer = input_buffer; } input_parameters.device = audio_options.input_device; input_parameters.channelCount = 2; input_parameters.sampleFormat = PA_SAMPLE_TYPE; input_parameters.suggestedLatency = Pa_GetDeviceInfo(input_parameters.device)->defaultHighInputLatency; input_parameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &input_stream, &input_parameters, NULL, audio_options.sample_rate, step_size, paNoFlag, recordCallback, &record_data ); if (err != paNoError) { goto done; } record_data.start_time = currentTimeMillis(); #ifdef LINUX_ALSA PaAlsa_EnableRealtimeScheduling(input_stream, 1); #endif if ((err = Pa_StartStream(input_stream)) != paNoError) { goto done; } } else { input_buffer = __read_audio_file(audio_options); } output_parameters.device = audio_options.output_device; if (audio_options.output_channels >= 6) { output_parameters.channelCount = audio_options.output_channels + 2; } else { output_parameters.channelCount = audio_options.output_channels; } output_parameters.sampleFormat = PA_SAMPLE_TYPE; output_parameters.suggestedLatency = Pa_GetDeviceInfo(output_parameters.device)->defaultLowOutputLatency; output_parameters.hostApiSpecificStreamInfo = NULL; PlaybackCallbackData playback_data = { output_buffer, output_parameters.channelCount }; printf("output channels: %d\n", output_parameters.channelCount); err = Pa_OpenStream( &output_stream, NULL, &output_parameters, audio_options.sample_rate, step_size, paNoFlag, playCallback, &playback_data ); if (err != paNoError) { goto done; } #ifdef LINUX_ALSA PaAlsa_EnableRealtimeScheduling(output_stream, 1); #endif if ((err = Pa_StartStream(output_stream)) != paNoError) { goto done; } int output_scale = output_parameters.channelCount / 2; int frame_print_interval = DEBUG_PRINT_INTERVAL_MILLIS * audio_options.sample_rate / 1000; int current_frame = 0; while (true) { if ((err = Pa_IsStreamActive(output_stream)) != 1) { break; } if (input_stream && (err = Pa_IsStreamActive(input_stream)) != 1) { break; } current_frame += OSFilter_execute(filter, input_buffer, output_buffer); if (audio_options.print_debug && current_frame > frame_print_interval) { current_frame -= frame_print_interval; if (!is_parent_running(audio_options.parent_thread_ident)) { printf("Parent thread is dead. Shutting down now.\n"); fflush(stdout); goto done; } if (!audio_options.print_debug) { continue; } long frame_difference = (CircularBuffer_lag(input_buffer) + CircularBuffer_lag(output_buffer) / output_scale) / 2; float lag = (float)(frame_difference) / audio_options.sample_rate * 1000; printf("%lu\t%lu\t%lu\t%fms\n", input_buffer->offset_producer, output_buffer->offset_consumer / output_scale, frame_difference, lag ); if (live_stream && (lag > audio_options.lag_reset_limit * 1000)) { printf("Resetting to latest due to high lag.\n"); CircularBuffer_fastforward(input_buffer, audio_options.filter_size * 2); CircularBuffer_fastforward(output_buffer, 0); } fflush(stdout); } } if (err < 0) { goto done; } done: if (output_stream) { Pa_CloseStream(output_stream); } if (input_stream) { Pa_CloseStream(input_stream); } Pa_Terminate(); if (input_buffer) { CircularBuffer_destroy(input_buffer); } CircularBuffer_destroy(output_buffer); if (decoder_input) { CircularBuffer_destroy(decoder_input); } if (decoder_buffer) { Decoding_free(decoder_buffer); } OSFilter_destroy(filter); if (err != paNoError) { fprintf(stdout, "An error occured while using the portaudio stream\n"); fprintf(stdout, "Error number: %d\n", err); fprintf(stdout, "Error message: %s\n", Pa_GetErrorText(err)); fflush(stdout); err = 1; } return err; }
bool isPlayed() { return (Pa_IsStreamActive(stream) == 1); }
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; }
void PA_AudioIO::terminate(){ if( Pa_IsStreamActive(m_Stream) ) Pa_StopStream(m_Stream); Pa_Terminate(); std::cout << "PA terminated" << std::endl; }
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); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // 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; }
PA_AudioIO::~PA_AudioIO(){ if( Pa_IsStreamActive(m_Stream) ) Pa_StopStream(m_Stream); Pa_Terminate(); }
int main (int argc, char ** argv) { int buffersize; int stereo; int samplerate; int numBytes; int numSample; int maxnumchannel_input; // state of keypress int state, oldstate; // vars for portaudio char * portaudiodevice; int exact=0; PaStreamParameters inputParameters; PaStream * stream; PaError pa_ret; const PaDeviceInfo *devinfo; // vars for networking char * ipaddrtxtin; int udpport; struct sockaddr_in * udp_aiaddr_in = NULL; struct sockaddr_in6 * udp_aiaddr_in6 = NULL; struct sockaddr * sendto_aiaddr = NULL; // structure used for sendto int sendto_sizeaiaddr=0; // size of structed used for sendto int udpsd; int udp_family; char ipaddrtxt[INET6_ADDRSTRLEN]; // vars for getaddrinfo struct addrinfo * hint; struct addrinfo * info; // for SAMPLE RATE CONVERSION SRC_STATE *src=NULL; SRC_DATA src_data; int src_error; // vars for codec2 void *codec2; unsigned char *c2_buff; int mode, nc2byte; // vars for audio int16_t * audiobuffer; float * inaudiobuffer_f = NULL; float * outaudiobuffer_f = NULL; // other vars int ret; // structure for c2encap data c2encap c2_voice; c2encap c2_begin, c2_end; // "audio in" posix thread pthread_t thr_keypress; // init data stereo=-1; global.transmit=0; // We need at least 3 arguments: IP-address, udpport and samplerate if (argc < 4) { fprintf(stderr,"Error: at least 3 arguments needed. \n"); fprintf(stderr,"Usage: %s <ip-addr> <udp port> <samplerate> [ <audiodevice> [exact] ] \n",argv[0]); fprintf(stderr,"Note: allowed audio samplerate are 8000, 44100 or 48000 samples/second.\n"); fprintf(stderr,"Note: use device \"\" to get list of devices.\n"); exit(-1); }; // end if ipaddrtxtin=argv[1]; udpport=atoi(argv[2]); samplerate=atoi(argv[3]); // if 1st argument exists, use it as capture device if (argc >= 5) { portaudiodevice = argv[4]; // is there the "exact" statement? if (argc >= 6) { if (!strcmp(argv[5],"exact")) { exact=1; } else { fprintf(stderr,"Error: parameter \"exact\" expected. Got %s. Ignoring! \n",argv[5]); }; // end else - if }; // end if } else { // no argument given portaudiodevice = NULL; }; // end else - if // create network structure if ((udpport < 0) || (udpport > 65535)) { fprintf(stderr,"Error: UDPport number must be between 0 and 65535! \n"); exit(-1); }; // end if if ((IPV4ONLY) && (IPV6ONLY)) { fprintf(stderr,"Error: internal configuration error: ipv4only and ipv6only are mutually exclusive! \n"); exit(-1); }; // end if // sample rates below 8Ksamples/sec or above 48Ksamples/sec do not make sence if (samplerate == 8000) { numSample = 320; } else if (samplerate == 44100) { numSample = 1764; } else if (samplerate == 48000) { numSample = 1920; } else { fprintf(stderr,"Error: audio samplerate should be 8000, 44100 or 48000 samples/sec! \n"); exit(-1); }; // end if // DO DNS query for ipaddress hint=malloc(sizeof(struct addrinfo)); if (!hint) { fprintf(stderr,"Error: could not allocate memory for hint!\n"); exit(-1); }; // end if // clear hint memset(hint,0,sizeof(hint)); hint->ai_socktype = SOCK_DGRAM; // resolve hostname, use function "getaddrinfo" // set address family of hint if ipv4only or ipv6only if (IPV4ONLY) { hint->ai_family = AF_INET; } else if (IPV6ONLY) { hint->ai_family = AF_INET6; } else { hint->ai_family = AF_UNSPEC; }; // end else - elsif - if // do DNS-query, use getaddrinfo for both ipv4 and ipv6 support ret=getaddrinfo(ipaddrtxtin, NULL, hint, &info); if (ret < 0) { fprintf(stderr,"Error: resolving hostname %s failed: (%s)\n",ipaddrtxtin,gai_strerror(ret)); exit(-1); }; // end if udp_family=info->ai_family; // open UDP socket + set udp port if (udp_family == AF_INET) { udpsd=socket(AF_INET,SOCK_DGRAM,0); // getaddrinfo returns pointer to generic "struct sockaddr" structure. // Cast to "struct sockaddr_in" to be able to fill in destination port udp_aiaddr_in=(struct sockaddr_in *)info->ai_addr; udp_aiaddr_in->sin_port=htons((unsigned short int) udpport); // set pointer to be used for "sendto" ipv4 structure // sendto uses generic "struct sockaddr" just like the information // returned from getaddrinfo, so no casting needed here sendto_aiaddr=info->ai_addr; sendto_sizeaiaddr=sizeof(struct sockaddr); // get textual version of returned ip-address inet_ntop(AF_INET,&udp_aiaddr_in->sin_addr,ipaddrtxt,INET6_ADDRSTRLEN); } else if (udp_family == AF_INET6) { udpsd=socket(AF_INET6,SOCK_DGRAM,0); // getaddrinfo returns pointer to generic "struct sockaddr" structure. // Cast to "struct sockaddr_in6" to be able to fill in destination port udp_aiaddr_in6=(struct sockaddr_in6 *)info->ai_addr; udp_aiaddr_in6->sin6_port=htons((unsigned short int) udpport); // set pointer to be used for "sendto" ipv4 structure // sendto uses generic "struct sockaddr" just like the information // returned from getaddrinfo, so no casting needed here sendto_aiaddr=info->ai_addr; sendto_sizeaiaddr=sizeof(struct sockaddr_in6); // get textual version of returned ip-address inet_ntop(AF_INET6,&udp_aiaddr_in6->sin6_addr,ipaddrtxt,INET6_ADDRSTRLEN); } else { fprintf(stderr,"Error: DNS query for %s returned an unknown network-family: %d \n",ipaddrtxtin,udp_family); exit(-1); }; // end if // getaddrinfo can return multiple results, we only use the first one // give warning is more then one result found. // Data is returned in info as a linked list // If the "next" pointer is not NULL, there is more then one // element in the chain if (info->ai_next != NULL) { fprintf(stderr,"Warning. getaddrinfo returned multiple entries. Using %s\n",ipaddrtxt); }; // end if if (udpsd < 0) { fprintf(stderr,"Error: could not create socket for UDP! \n"); exit(-1); }; // end if // init c2encap structures memcpy(c2_begin.header,C2ENCAP_HEAD,sizeof(C2ENCAP_HEAD)); c2_begin.header[3]=C2ENCAP_MARK_BEGIN; memcpy(c2_begin.c2data.c2data_text3,"BEG",3); memcpy(c2_end.header,C2ENCAP_HEAD,sizeof(C2ENCAP_HEAD)); c2_end.header[3]=C2ENCAP_MARK_END; memcpy(c2_end.c2data.c2data_text3,"END",3); memcpy(c2_voice.header,C2ENCAP_HEAD,sizeof(C2ENCAP_HEAD)); c2_voice.header[3]=C2ENCAP_DATA_VOICE1400; // PORTAUDIO STUFF fprintf(stderr,"INITIALISING PORTAUDIO (this can take some time, please ignore any errors below) .... \n"); // open portaudio device pa_ret=Pa_Initialize(); fprintf(stderr,".... DONE\n"); if (pa_ret != paNoError) { Pa_Terminate(); fprintf(stderr,"Error: Could not initialise Portaudio: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret); exit(-1); }; // end if if (portaudiodevice == NULL) { // portaudio device = NULL -> use portaudio "get default input device" inputParameters.device = Pa_GetDefaultInputDevice(); if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: no portaudio default input device!\n"); exit(-1); }; // end if if (inputParameters.device >= Pa_GetDeviceCount()) { fprintf(stderr,"Internal Error: portaudio \"GetDefaultInputDevice\" returns device number %d while possible devices go from 0 to %d \n,",inputParameters.device, (Pa_GetDeviceCount() -1) ); exit(-1); }; // end if // check if device supports samplerate: inputParameters.sampleFormat = paInt16; inputParameters.suggestedLatency = 0; // not used in Pa_IsFormatSupported inputParameters.hostApiSpecificStreamInfo = NULL; devinfo = Pa_GetDeviceInfo (inputParameters.device); maxnumchannel_input = devinfo->maxInputChannels; printf("Audio device = %d (%s %s)\n",inputParameters.device,Pa_GetHostApiInfo(devinfo->hostApi)->name,devinfo->name); if (maxnumchannel_input >= 1) { // first check if samplerate is supported in mono inputParameters.channelCount = 1; pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate); if (pa_ret == paFormatIsSupported) { printf("Samplerate %d supported in mono.\n",samplerate); stereo=0; } else { // try again using stereo inputParameters.channelCount = 2; if (maxnumchannel_input >= 2) { pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate); if (pa_ret == paFormatIsSupported) { printf("Samplerate %d supported in stereo.\n",samplerate); stereo=1; } else { printf("Error: Samplerate %d not supported in mono or stereo!\n",samplerate); exit(-1); }; // end if } else { // stereo not supported on this device printf("Error: Samplerate %d not supported in mono. Stereo not supported on this device!\n",samplerate); exit(-1); }; // end if }; // end else - if } else { printf("Error: input not supported on this device!\n"); exit(-1); }; // end if printf("\n"); fflush(stdout); } else { // CLI option "device" contains text, look throu list of all devices if there are // devices that match that name and support the particular requested samplingrate int loop; int numdevice; int numdevicefound=0; int devicenr=0; int devicestereo=0; // init some vars numdevice=Pa_GetDeviceCount(); inputParameters.sampleFormat = paInt16; inputParameters.suggestedLatency = 0; // not used in Pa_IsFormatSupported inputParameters.hostApiSpecificStreamInfo = NULL; for (loop=0; loop<numdevice;loop++) { int devnamematch=0; // get name of device devinfo = Pa_GetDeviceInfo (loop); // only do check if searchstring is smaller or equal is size of device name if (strlen(devinfo->name) >= strlen(portaudiodevice)) { int numcheck; int devnamesize; int loop; char *p; // init pointer to beginning of string p=(char *)devinfo->name; devnamesize = strlen(portaudiodevice); if (exact) { // exact match, only check once: at the beginning numcheck=1; } else { numcheck=strlen(p) - strlen(portaudiodevice) +1; }; // end if // loop until text found or end-of-string for (loop=0; (loop<numcheck && devnamematch == 0); loop++) { if (strncmp(portaudiodevice,p,devnamesize) ==0) { devnamematch=1; }; // end if // move up pointer p++; }; }; // end if if (devnamematch) { printf("Audio device: %d (API: %s ,NAME: %s)\n",loop,Pa_GetHostApiInfo(devinfo->hostApi)->name,devinfo->name); maxnumchannel_input = devinfo->maxInputChannels; if (maxnumchannel_input >= 1) { // next step: check if this device supports the particular requested samplerate inputParameters.device = loop; inputParameters.channelCount = 1; pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate); if (pa_ret == paFormatIsSupported) { printf("Samplerate %d supported in mono.\n",samplerate); numdevicefound++; devicenr=loop; devicestereo=0; } else { if (maxnumchannel_input >= 2) { inputParameters.channelCount = 2; pa_ret = Pa_IsFormatSupported(NULL,&inputParameters,(double) samplerate); if (pa_ret == paFormatIsSupported) { printf("Samplerate %d supported in stereo.\n",samplerate); numdevicefound++; devicenr=loop; devicestereo=1; } else { printf("Error: Samplerate %d not supported in mono or stereo.\n",samplerate); }; // end else - if } else { // stereo not supported on this device printf("Error: Samplerate %d not supported in mono. Stereo not supported on this device!\n",samplerate); }; // end if }; // end else - if } else { printf("Error: Input not supported on device.\n"); }; // end if printf("\n"); fflush(stdout); };// end if }; // end for // did we find any device if (numdevicefound == 0) { fprintf(stderr,"Error: did not find any audio-device supporting that audio samplerate\n"); fprintf(stderr," Try again with other samplerate of devicename \"\" to get list of all devices\n"); exit(-1); } else if (numdevicefound > 1) { fprintf(stderr,"Error: Found multiple devices matching devicename supporting that audio samplerate\n"); fprintf(stderr," Try again with a more strict devicename or use \"exact\" clause!\n"); exit(-1); } else { // OK, we have exactly one device: copy its parameters inputParameters.device=devicenr; stereo=devicestereo; if (devicestereo) { inputParameters.channelCount = 2; } else { inputParameters.channelCount = 1; }; // end else - if // get name info from device devinfo = Pa_GetDeviceInfo (inputParameters.device); fprintf(stderr,"Selected Audio device = (API: %s ,NAME: %s)\n",Pa_GetHostApiInfo(devinfo->hostApi)->name,devinfo->name); }; }; // end else - if // set other parameters of inputParameters structure inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency; // configure portaudio global data if (samplerate == 8000) { numSample = 320; } else if (samplerate == 44100) { numSample = 1764; } else if (samplerate == 48000) { numSample = 1920; } else { fprintf(stderr,"Error: invalid value for samplerate in funct_audioout: %d !\n",samplerate); exit(-1); }; // end if // configure portaudio global data if (stereo) { numBytes = (numSample << 2); } else { numBytes = (numSample << 1); }; // end if // create memory for audiobuffer audiobuffer = malloc(numBytes); // allow memory for buffer 0 if (!audiobuffer) { // memory could not be allocated fprintf(stderr,"Error: could not allocate memory for portaudio buffer 0!\n"); exit(-1); }; // end if // some network debug info fprintf(stderr,"Sending CODEC2 DV stream to ip-address %s udp port %d\n",ipaddrtxt,udpport); // open PortAudio stream // do not start stream yet, will be done further down pa_ret = Pa_OpenStream ( &stream, &inputParameters, NULL, // output Parameters, not used here samplerate, // sample rate numSample, // frames per buffer: 40 ms @ 8000 samples/sec paClipOff, // we won't output out of range samples, // so don't bother clipping them NULL, // no callback function, syncronous read &global // parameters passed to callback function (not used here) ); if (pa_ret != paNoError) { Pa_Terminate(); fprintf(stderr,"Error in Pa_OpenStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret); exit(-1); }; // end if // init codec2 mode = CODEC2_MODE_1400; codec2 = codec2_create (mode); nc2byte = (codec2_bits_per_frame(codec2) + 7) >> 3; // ">>3" is same as "/8" if (nc2byte != 7) { fprintf(stderr,"Error: number of bytes for codec2 frames should be 7. We got %d \n",nc2byte); }; // end if if (codec2_samples_per_frame(codec2) != 320) { fprintf(stderr,"Error: number of samples for codec2 frames should be 320. We got %d \n",codec2_samples_per_frame(codec2)); }; // end if c2_buff = (unsigned char *)&c2_voice.c2data.c2data_data7; // allocate audiobuffer if (stereo) { buffersize= numSample << 2; // = number of samples * 4 (stereo and 16 bit/sample) } else { // mono buffersize= numSample << 1; // = number of samples * 2 (16 bit/sample) }; // end else - if audiobuffer=malloc(buffersize); if (!audiobuffer) { fprintf(stderr,"Error: malloc audiobuffer: %s",strerror(errno)); exit(-1); }; // end if // init samplerate conversion if (samplerate != 8000) { // allocate memory for audio sample buffers (only needed when audio rate conversion is used) inaudiobuffer_f=malloc(numSample * sizeof(float)); if (!inaudiobuffer_f) { fprintf(stderr,"Error in malloc for inaudiobuffer_f! \n"); exit(-1); }; // end if outaudiobuffer_f=malloc(320 * sizeof(float)); // output buffer is 320 samples (40 ms @ 8000 samples/sec) if (!outaudiobuffer_f) { fprintf(stderr,"Error in malloc for outaudiobuffer_f! \n"); exit(-1); }; // end if src = src_new(SRC_SINC_FASTEST,1,&src_error); if (!src) { fprintf(stderr,"src_new failed! \n"); exit(-1); }; // end if src_data.data_in = inaudiobuffer_f; src_data.data_out = outaudiobuffer_f; src_data.input_frames = numSample; src_data.output_frames = 320; // 40 ms @ 8000 samples / sec src_data.end_of_input = 0; // no further data, every 40 ms frame is concidered to be a seperate unit if (samplerate == 48000) { src_data.src_ratio = (float) 8000/48000; } else { src_data.src_ratio = (float) 8000/44100; }; // end else - if }; // end if // start thread to read detect keypress (used to switch transmitting) pthread_create (&thr_keypress, NULL, funct_keypress, (void *) &global); // Start stream pa_ret=Pa_StartStream(stream); if (pa_ret != paNoError) { Pa_Terminate(); fprintf(stderr,"Error in Pa_StartStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret); exit(-1); }; // end if // init some vars; oldstate=0; while (( pa_ret = Pa_IsStreamActive (stream)) == 1) { // get audio pa_ret = Pa_ReadStream(stream, audiobuffer, numSample); if (pa_ret != paNoError) { Pa_Terminate(); fprintf(stderr,"Error in Pa_ReadStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret); exit(-1); }; // end if // get state from subthread state=global.transmit; if (state) { // State = 1: write audio // first check old state, if we go from oldstate=0 to state=1, this is // the beginning of a new stream; so send start packe if (oldstate == 0) { // start "start" marker // fwrite((void *) &c2_begin,C2ENCAP_SIZE_MARK,1,stdout); // fflush(stdout); // send start 3 times, just to be sure sendto(udpsd,&c2_begin,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr); sendto(udpsd,&c2_begin,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr); sendto(udpsd,&c2_begin,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr); // putc('B',stderr); } // if stereo, only use left channel if (stereo) { int loop; int16_t *p1, *p2; // start at 2th element (in stereo format); which is 3th (in mono format) p1=&audiobuffer[1]; p2=&audiobuffer[2]; for (loop=1; loop < numSample; loop++) { *p1=*p2; p1++; p2 += 2; }; // end for }; // end if // if not 8000 samples / second: convert if (samplerate != 8000) { fprintf(stderr,"2!!! \n"); if (!inaudiobuffer_f) { fprintf(stderr,"Internal Error: inaudiobuffer_f not initialised \n"); exit(-1); }; // end if if (!outaudiobuffer_f) { fprintf(stderr,"Internal Error: outaudiobuffer_f not initialised \n"); exit(-1); }; // end if // convert int16 to float src_short_to_float_array(audiobuffer,inaudiobuffer_f,numSample); // convert ret=src_process(src,&src_data); if (ret) { fprintf(stderr,"Warning: samplerate conversion error %d (%s)\n",ret,src_strerror(ret)); }; // end if // some error checking if (src_data.output_frames_gen != 320) { fprintf(stderr,"Warning: number of frames generated by samplerateconvert should be %d, got %ld. \n",numSample,src_data.output_frames_gen); }; // end if // convert back from float to int src_float_to_short_array(outaudiobuffer_f,audiobuffer,320); // 40 ms @ 8000 samples/sec = 320 samples fprintf(stderr,"3!!! \n"); }; // end if // do codec2 encoding codec2_encode(codec2, c2_buff, audiobuffer); //fwrite((void *)&c2_voice,C2ENCAP_SIZE_VOICE1400,1,stdout); //fflush(stdout); sendto(udpsd,&c2_voice,C2ENCAP_SIZE_VOICE1400,0,sendto_aiaddr, sendto_sizeaiaddr); // putc('T',stderr); } else { // state = 0, do not send // however, if we go from "oldstate = 1 - > state = 0", this is // the end of a stream if (oldstate) { // send "end" marker //fwrite((void *)&c2_end,C2ENCAP_SIZE_MARK,1,stdout); //fflush(stdout); // send end 3 times, just to be sure sendto(udpsd,&c2_end,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr); sendto(udpsd,&c2_end,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr); sendto(udpsd,&c2_end,C2ENCAP_SIZE_MARK,0,sendto_aiaddr, sendto_sizeaiaddr); // putc('E',stderr); }; // end if }; // end else - if oldstate=state; }; // end while // dropped out of endless loop. Should not happen if (pa_ret < 0) { Pa_Terminate(); fprintf(stderr,"Error in Pa_isStreamActive: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret); exit(-1); }; // end if fprintf(stderr,"Error: audiocap dropped out of audiocapturing loop. Should not happen!\n"); pa_ret=Pa_CloseStream(stream); if (pa_ret != paNoError) { Pa_Terminate(); fprintf(stderr,"Error in Pa_CloseStream: %s(%d) \n",Pa_GetErrorText(pa_ret),pa_ret); exit(-1); }; // end if // Done!!! Pa_Terminate(); exit(0); }; // end main applicion
void* AudioThread::Entry() { GlobalConfig* config = GlobalConfig::getInstance(); config->Log( "AudioThread::Entry();" ); m_Done = false; m_PaStreamIsActive = false; int cnt=0; while( not m_Done ) { // Check Audio-Device-State every 100 ms switch( m_AudioState ) { case STATE_CLOSED: { config->Log( "Audiothread-STATE: CLOSED" ); // closed ?!? Then try to configure it... Configure(); break; } case STATE_OPEN: { config->Log( "Audiothread-STATE: OPEN" ); // Open, but not running? Then start it by all means... int err=Pa_StartStream( m_PaStream ); int cnt=0; while( err != paNoError && cnt<5 ) { err = Pa_StartStream( m_PaStream ); cnt++; } if( err == paNoError ) { m_PaStreamIsActive = true; config->Log( "Audiothread-STATE: OPEN and Portaudio-Stream successfully started." ); config->Log( " Portaudio-Error-Code: %i ", err ); config->Log( " Portaudio-Error-Text: %s ", Pa_GetErrorText( err ) ); m_AudioState = STATE_RUNNING; } else { m_AudioState = STATE_ERROR; config->Log( "Audiothread-STATE: OPEN and Portaudio-Stream *NOT* successfully started." ); config->Log( " Portaudio-Error-Code: %i ", err ); config->Log( " Portaudio-Error-Text: %s ", Pa_GetErrorText( err ) ); } // change audio-state to running... break; } case STATE_ERROR: { // close all active streams ... if( m_PaStreamIsActive ) { Pa_CloseStream( m_PaStream ); m_PaStreamIsActive = false; } // send an event, so the user can notice that there is something // going wrong badly... //wxWindow* statusWindow = Config->getStatusWindow(); //wxCommandEvent event(wxEVT_COMMAND_MIXER_ERROR); //statusWindow->AddPendingEvent( event ); // now wait here(!) until the user changes the configuration // again while( m_AudioState == STATE_ERROR ) { config->Log( "Audiothread-STATE: *** ERROR ***" ); // Check for reconfiguration-request... m_ReconfigureLock.Lock(); if( m_ReconfigureFlag ) { // reset flag m_ReconfigureFlag = false; // change AudioState m_AudioState = STATE_CLOSED; } m_ReconfigureLock.Unlock(); Sleep( 1000 ); // wait a second } break; } case STATE_RUNNING: default: { // do nothing but wait for reconfigure-flag... and check that // all audio-streams are up and running... cnt = (cnt+1)%80; if( cnt==0 ) { double cpuLoad = Pa_GetStreamCpuLoad( m_PaStream ); config->Log( "Audiothread-STATE: RUNNING (%f)", floor(cpuLoad*1000.0+0.5)/10.0 ); } // Check for reconfiguration-request... m_ReconfigureLock.Lock(); if( m_ReconfigureFlag ) { // close all active streams and change state... if( m_PaStreamIsActive ) { Pa_CloseStream( m_PaStream ); m_PaStreamIsActive = false; } // reset flag m_ReconfigureFlag = false; // change AudioState m_AudioState = STATE_CLOSED; } m_ReconfigureLock.Unlock(); // Check that everything is OK with the streams... if( m_PaStreamIsActive ) { if( Pa_IsStreamActive( m_PaStream ) != 1 ) { // flag error m_AudioState = STATE_ERROR; // try to get some information on the // error... const PaHostErrorInfo* errorInfo = Pa_GetLastHostErrorInfo(); config->Log( "PaGetLastErrorInfo: %i %i %s", (int)errorInfo->hostApiType, errorInfo->errorCode, errorInfo->errorText ); } } } } Sleep( 100 ); // wait for 100 ms } // close all active streams ... if( m_PaStreamIsActive ) { Pa_StopStream( m_PaStream ); Pa_CloseStream( m_PaStream ); m_PaStreamIsActive = false; } // all finished here... return( 0 ); }