rendered paste body#include <stdio.h>
#include <math.h>
#include <portaudio.h>
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dsound.lib")
#include <pa_lib.c>
#include <pa_host.h>
/*#include <dsound_wrapper.c>
#include <pa_dsound.c>*/
#include <pa_win_wmme.c>
//#include <biquad.cpp>
//#include <biquad.h>
#include <bq2.h>
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
#define SAMPLE_RATE (44100)
#define NUM_SECONDS (5)
#define NUM_CHANNELS (2)
/* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/
#define FRAMES_PER_BUFFER (1024)
/* Select sample format. */
#if 1
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#elif 0
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#elif 0
#define PA_SAMPLE_TYPE paInt8
typedef char SAMPLE;
#define SAMPLE_SILENCE (0)
#else
#define PA_SAMPLE_TYPE paUInt8
typedef unsigned char SAMPLE;
#define SAMPLE_SILENCE (128)
#endif
typedef struct
{
int frameIndex; /* Index into sample array. */
int maxFrameIndex;
SAMPLE *recordedSamples;
}
paTestData;
/* This routine will be called by the PortAudio engine when audio is needed.
** It may be called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int recordCallback( void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
PaTimestamp outTime, void *userData )
{
paTestData *data = (paTestData*)userData;
SAMPLE *rptr = (SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToRecord;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
int samplesToRecord;
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) outTime;
if( framesLeft < framesPerBuffer )
{
framesToRecord = framesLeft;
finished = 1;
}
else
{
framesToRecord = framesPerBuffer;
finished = 0;
}
samplesToRecord = framesToRecord * NUM_CHANNELS;
if( inputBuffer == NULL )
{
for( i=0; i<samplesToRecord; i++ )
{
*wptr++ = SAMPLE_SILENCE;
}
}
else
{
for( i=0; i<samplesToRecord; i++ )
{
*wptr++ = *rptr++;
}
}
data->frameIndex += framesToRecord;
return finished;
}
/* This routine will be called by the PortAudio engine when audio is needed.
** It may be called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int playCallback( void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
PaTimestamp outTime, void *userData )
{
paTestData *data = (paTestData*)userData;
SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
SAMPLE *wptr = (SAMPLE*)outputBuffer;
unsigned int i;
int finished;
unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
(void) inputBuffer; /* Prevent unused variable warnings. */
(void) outTime;
int framesToPlay, samplesToPlay, samplesPerBuffer;
if( framesLeft < framesPerBuffer )
{
framesToPlay = framesLeft;
finished = 1;
}
else
{
framesToPlay = framesPerBuffer;
finished = 0;
}
samplesToPlay = framesToPlay * NUM_CHANNELS;
samplesPerBuffer = framesPerBuffer * NUM_CHANNELS;
for( i=0; i<samplesToPlay; i++ )
{
*wptr++ = *rptr++;
}
for( ; i<framesPerBuffer; i++ )
{
*wptr++ = 0; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = 0; /* right */
}
data->frameIndex += framesToPlay;
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
//Biquad foo(fmodeBP, 1000, .03, 44100);
CFxRbjFilter foo;
CFxRbjFilter foo2;
foo.calc_filter_coeffs(3, 1000, 44100, 30, 1, 0);
foo2.calc_filter_coeffs(3, 1000, 44100, 30, 1, 0);
PortAudioStream *stream;
PortAudioStream *stream2;
PaError err;
PaError err2;
paTestData data;
paTestData data2;
int i;
int i2;
int totalFrames;
int totalFrames2;
int numSamples;
int numSamples2;
int numBytes;
int numBytes2;
SAMPLE max, average, val;
SAMPLE max2, average2, val2;
printf("patest_record.c\n"); fflush(stdout);
data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
data2.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE;
data.frameIndex = 0;
data2.frameIndex = 0;
numSamples = totalFrames * NUM_CHANNELS;
numSamples2 = totalFrames2 * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
numBytes2 = numSamples2 * sizeof(SAMPLE);
data.recordedSamples = (SAMPLE *) malloc( numBytes );
data2.recordedSamples = (SAMPLE *) malloc( numBytes2 );
if( data.recordedSamples == NULL )
{
printf("Could not allocate record array for 1.\n");
exit(1);
}
if( data2.recordedSamples == NULL )
{
printf("Could not allocate record array for 2.\n");
exit(1);
}
for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
for( i=0; i<numSamples; i++ ) data2.recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
2,
NUM_CHANNELS,
PA_SAMPLE_TYPE,
NULL,
paNoDevice,
0,
PA_SAMPLE_TYPE,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER, /* frames per buffer */
0, /* number of buffers, if zero then use default minimum */
0, /* paDitherOff, // flags */
recordCallback,
&data );
if( err != paNoError ) goto error;
err2 = Pa_OpenStream(
&stream2,
3,
NUM_CHANNELS,
PA_SAMPLE_TYPE,
NULL,
paNoDevice,
0,
PA_SAMPLE_TYPE,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER, /* frames per buffer */
0, /* number of buffers, if zero then use default minimum */
0, /* paDitherOff, // flags */
recordCallback,
&data2 );
if( err2 != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
err2 = Pa_StartStream( stream2 );
if( err2 != paNoError ) goto error;
printf("Now recording on:\n"); fflush(stdout);
const PaDeviceInfo *pdi;
pdi = Pa_GetDeviceInfo( 2 );
printf("---------------------------------------------- #%d", 2 );
if( 2 == Pa_GetDefaultInputDeviceID() ) printf(" DefaultInput");
if( 2 == Pa_GetDefaultOutputDeviceID() ) printf(" DefaultOutput");
printf("\nName = %s\n", pdi->name );
printf("Max Inputs = %d", pdi->maxInputChannels );
printf(", Max Outputs = %d\n", pdi->maxOutputChannels );
if( pdi->numSampleRates == -1 )
{
printf("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1] );
}
else
{
printf("Sample Rates =");
int j;
for( j=0; j<pdi->numSampleRates; j++ )
{
printf(" %8.2f,", pdi->sampleRates[j] );
}
printf("\n");
}
printf("Native Sample Formats = ");
if( pdi->nativeSampleFormats & paInt8 ) printf("paInt8, ");
if( pdi->nativeSampleFormats & paUInt8 ) printf("paUInt8, ");
if( pdi->nativeSampleFormats & paInt16 ) printf("paInt16, ");
if( pdi->nativeSampleFormats & paInt32 ) printf("paInt32, ");
if( pdi->nativeSampleFormats & paFloat32 ) printf("paFloat32, ");
if( pdi->nativeSampleFormats & paInt24 ) printf("paInt24, ");
if( pdi->nativeSampleFormats & paPackedInt24 ) printf("paPackedInt24, ");
printf("\n");
while( Pa_StreamActive( stream ) )
{
Pa_Sleep(1000);
printf("index = %d\n", data.frameIndex ); fflush(stdout);
printf("index = %d\n", data2.frameIndex ); fflush(stdout);
}
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
err2 = Pa_CloseStream( stream2 );
if( err2 != paNoError ) goto error;
/* Measure maximum peak amplitude. */
max = 0;
average = 0;
printf("Processing through bandpass...\n"); fflush(stdout);
float myvar;
float myvar2;
for( i=0; i<numSamples; i++ )
{
val = data.recordedSamples[i];
if( val < 0 ) val = -val; /* ABS */
if( val > max )
{
max = val;
}
average += val;
//printf ("floats: %f\n", val);fflush(stdout);
myvar=foo.filter(data.recordedSamples[i],.999,2000,44100);/* &data.recordedSamples[i]); */
//myvar=foo.filtera(myvar);
//printf ("floats: %f\n", myvar);fflush(stdout);
data.recordedSamples[i]=myvar;
myvar2=foo2.filter(data2.recordedSamples[i],.999,2000,44100);
data2.recordedSamples[i]=myvar2;
}
average = average / numSamples;
if( PA_SAMPLE_TYPE == paFloat32 ) /* This should be done at compile-time with "#if" ?? */
{ /* MIPS-compiler warns at the int-version below. */
printf("sample max amplitude = %f\n", max );
printf("sample average = %f\n", average );
}
else
{
printf("sample max amplitude = %d\n", max ); /* <-- This IS compiled anyhow. */
printf("sample average = %d\n", average );
}
/* Write recorded data to a file. */
#if 0
{
FILE *fid;
fid = fopen("recorded.raw", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
#endif
/* Playback recorded data. -------------------------------------------- */
data.frameIndex = 0;
data2.frameIndex = 0;
printf("Begin playback of device 1.\n"); fflush(stdout);
err = Pa_OpenStream(
&stream,
paNoDevice,
0, /* NO input */
PA_SAMPLE_TYPE,
NULL,
Pa_GetDefaultOutputDeviceID(),
NUM_CHANNELS,
PA_SAMPLE_TYPE,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER, /* frames per buffer */
0, /* number of buffers, if zero then use default minimum */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
playCallback,
&data );
if( err != paNoError ) goto error;
if( stream )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Waiting for playback to finish.\n"); fflush(stdout);
while( Pa_StreamActive( stream ) ) Pa_Sleep(100);
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
printf("Done.\n"); fflush(stdout);
}
free( data.recordedSamples );
err = Pa_OpenStream(
&stream2,
paNoDevice,
0, /* NO input */
PA_SAMPLE_TYPE,
NULL,
Pa_GetDefaultOutputDeviceID(),
NUM_CHANNELS,
PA_SAMPLE_TYPE,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER, /* frames per buffer */
0, /* number of buffers, if zero then use default minimum */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
playCallback,
&data2 );
if( err != paNoError ) goto error;
if( stream2 )
{
err = Pa_StartStream( stream2 );
if( err != paNoError ) goto error;
printf("Waiting for playback to finish.\n"); fflush(stdout);
while( Pa_StreamActive( stream2 ) ) Pa_Sleep(100);
err = Pa_CloseStream( stream2 );
if( err != paNoError ) goto error;
printf("Done.\n"); fflush(stdout);
}
free( data2.recordedSamples );
Pa_Terminate();
return 0;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return -1;
}