/* * comb.c * Comb filter the input and send it to the output. * * Author: Christopher Dobrian * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * */ #include #include #include "portaudio.h" #define NUM_SECONDS (10) #define SAMPLE_RATE (44100) #define BUFFER_SIZE (256) #define PIPE_SIZE (512) typedef struct { int saved_current_address; float leftpipe[PIPE_SIZE]; float rightpipe[PIPE_SIZE]; int left_delaysamps; int right_delaysamps; } paAudioData; /* This routine will be called by the PortAudio engine when audio is needed. */ static int combCallback( void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *userData ) { /* Cast data passed through stream to the format of the local structure. */ paAudioData *data = (paAudioData*)userData; float *in = (float*)inputBuffer; float *out = (float*)outputBuffer; unsigned int i; int current_address; int left_delayedaddress; int right_delayedaddress; current_address = data->saved_current_address; // get saved current address from data structure left_delayedaddress = current_address - data->left_delaysamps; while ( left_delayedaddress < 0 ) left_delayedaddress += PIPE_SIZE; right_delayedaddress = current_address - data->right_delaysamps; while ( right_delayedaddress < 0 ) right_delayedaddress += PIPE_SIZE; for( i = 0 ; i < framesPerBuffer ; i++ ) { current_address = (current_address+1)%PIPE_SIZE; left_delayedaddress = (left_delayedaddress+1)%PIPE_SIZE; right_delayedaddress = (right_delayedaddress+1)%PIPE_SIZE; data->leftpipe[current_address] = *in++; data->rightpipe[current_address] = *in++; *out++ = ((data->leftpipe[current_address])+(data->leftpipe[left_delayedaddress]))*0.5; /* left */ *out++ = ((data->rightpipe[current_address])+(data->rightpipe[right_delayedaddress]))*0.5; /* right */ } data->saved_current_address = current_address; // save the current address for use in the next callback return 0; } /*******************************************************************/ static paAudioData data; int main(void); int main(void) { PortAudioStream *stream; PaError err; unsigned int i; printf("PortAudio: Simple Comb Filter.\n"); /* Initialize data for use by callback. */ data.saved_current_address = 0; data.left_delaysamps = SAMPLE_RATE*0.002; data.right_delaysamps = SAMPLE_RATE*0.0025; for ( i = 0 ; i < PIPE_SIZE ; i++ ) { data.leftpipe[i] = 0.0; data.rightpipe[i] = 0.0; } /* Initialize library before making any other calls. */ err = Pa_Initialize(); if( err != paNoError ) goto error; /* Open an audio I/O stream. */ err = Pa_OpenDefaultStream( &stream, 2, /* two input channels */ 2, /* stereo output */ paFloat32, /* 32 bit floating point output */ SAMPLE_RATE, BUFFER_SIZE, /* frames per buffer */ 0, /* number of buffers, if zero then use default minimum */ combCallback, &data ); if( err != paNoError ) goto error; err = Pa_StartStream( stream ); if( err != paNoError ) goto error; /* Sleep for several seconds. */ Pa_Sleep(NUM_SECONDS*1000); err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); printf("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; }