From: philburk Date: Sun, 27 Feb 2011 00:06:07 +0000 (+0000) Subject: Cleanup tests. Lots of small tweaks. X-Git-Tag: pa_stable_v19_20110326_r1647~38 X-Git-Url: https://andrewgundersen.net/repos?a=commitdiff_plain;h=7ffd3f5374c4a3b303843cb74cfee4596911a767;p=portaudio Cleanup tests. Lots of small tweaks. Delete the debug_ tests because they are V18 and are not needed. We can just hack a V19 test if we need to debug. --- diff --git a/qa/loopback/src/audio_analyzer.c b/qa/loopback/src/audio_analyzer.c index 1cddaab..aff93d0 100644 --- a/qa/loopback/src/audio_analyzer.c +++ b/qa/loopback/src/audio_analyzer.c @@ -391,6 +391,7 @@ int PaQa_MeasureLatency( PaQaRecording *recording, PaQaTestTone *testTone, PaQaA double tolerance = 0.1; analysisResult->latency = PaQa_FindFirstMatch( recording, buffer, cycleSize, tolerance ); + QA_ASSERT_TRUE( "Could not find the start of the signal.", (analysisResult->latency >= 0) ); analysisResult->amplitudeRatio = PaQa_CompareAmplitudes( recording, analysisResult->latency, buffer, cycleSize ); return 0; error: diff --git a/qa/loopback/src/paqa.c b/qa/loopback/src/paqa.c index 3732b64..b3cb171 100644 --- a/qa/loopback/src/paqa.c +++ b/qa/loopback/src/paqa.c @@ -56,6 +56,13 @@ int g_testsFailed = 0; #define MAX_NUM_RECORDINGS (8) #define LOOPBACK_DETECTION_DURATION_SECONDS (0.5) +// Use two separate streams instead of one full duplex stream. +#define PAQA_FLAG_TWO_STREAMS (1<<0) +// Use bloching read/write for loopback. +#define PAQA_FLAG_USE_BLOCKING_IO (1<<1) + +#define DEFAULT_FRAMES_PER_BUFFER (256) + /** Parameters that describe a single test run. */ typedef struct TestParameters_s { @@ -67,6 +74,7 @@ typedef struct TestParameters_s int maxFrames; double baseFrequency; double amplitude; + int flags; } TestParameters; typedef struct LoopbackContext_s @@ -93,6 +101,9 @@ typedef struct UserOptions_s PaDeviceIndex outputDevice; } UserOptions; +#define BIG_BUFFER_SIZE (sizeof(float) * 2 * 2048) +static unsigned char g_BigBuffer[BIG_BUFFER_SIZE]; + /*******************************************************************/ static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, @@ -102,43 +113,108 @@ static int RecordAndPlaySinesCallback( const void *inputBuffer, void *outputBuff { float *in = (float *)inputBuffer; float *out = (float *)outputBuffer; - int done = 0; + int done = paContinue; LoopbackContext *loopbackContext = (LoopbackContext *) userData; loopbackContext->callbackCount += 1; - /* This may get called with NULL inputBuffer during initial setup. */ - if( in == NULL) return 0; + /* This may get called with NULL inputBuffer during initial setup. + * We may also use the same callback with output only streams. + */ + if( in != NULL) + { + for( int i=0; itest->inputParameters.channelCount; i++ ) + { + done |= PaQa_WriteRecording( &loopbackContext->recordings[i], in + i, framesPerBuffer, loopbackContext->test->inputParameters.channelCount ); + } + } - for( int i=0; itest->inputParameters.channelCount; i++ ) + if( out != NULL ) { - done |= PaQa_WriteRecording( &loopbackContext->recordings[i], in + i, framesPerBuffer, loopbackContext->test->inputParameters.channelCount ); + PaQa_EraseBuffer( out, framesPerBuffer, loopbackContext->test->outputParameters.channelCount ); + + for( int i=0; itest->outputParameters.channelCount; i++ ) + { + PaQa_MixSine( &loopbackContext->generators[i], out + i, framesPerBuffer, loopbackContext->test->outputParameters.channelCount ); + } } + return done ? paComplete : paContinue; +} + +/*******************************************************************/ +/** + * Open a full duplex audio stream. + * Generate sine waves on the output channels and record the input channels. + * Then close the stream. + * @return 0 if OK or negative error. + */ +int PaQa_RunLoopbackFullDuplex( LoopbackContext *loopbackContext ) +{ + PaStream *stream = NULL; + PaError err = 0; + TestParameters *test = loopbackContext->test; - PaQa_EraseBuffer( out, framesPerBuffer, loopbackContext->test->outputParameters.channelCount ); + // Use one full duplex stream. + err = Pa_OpenStream( + &stream, + &test->inputParameters, + &test->outputParameters, + test->sampleRate, + test->framesPerBuffer, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + RecordAndPlaySinesCallback, + loopbackContext ); + if( err != paNoError ) goto error; - for( int i=0; itest->outputParameters.channelCount; i++ ) + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + // Wait for stream to finish. + while( Pa_IsStreamActive( stream ) ) { - PaQa_MixSine( &loopbackContext->generators[i], out + i, framesPerBuffer, loopbackContext->test->outputParameters.channelCount ); + Pa_Sleep(50); } - return done ? paComplete : paContinue; + err = Pa_StopStream( stream ); + if( err != paNoError ) goto error; + + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + + return 0; + +error: + return err; } /*******************************************************************/ /** - * Open an audio stream. + * Open two audio streams, one for input and one for output. * Generate sine waves on the output channels and record the input channels. * Then close the stream. * @return 0 if OK or negative error. */ -int PaQa_RunLoopback( LoopbackContext *loopbackContext ) +int PaQa_RunLoopbackHalfDuplex( LoopbackContext *loopbackContext ) { - PaStream *stream = NULL; + PaStream *inStream = NULL; + PaStream *outStream = NULL; + PaError err = 0; TestParameters *test = loopbackContext->test; - PaError err = Pa_OpenStream( - &stream, + + // Use two half duplex streams. + err = Pa_OpenStream( + &inStream, &test->inputParameters, + NULL, + test->sampleRate, + test->framesPerBuffer, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + RecordAndPlaySinesCallback, + loopbackContext ); + if( err != paNoError ) goto error; + err = Pa_OpenStream( + &outStream, + NULL, &test->outputParameters, test->sampleRate, test->framesPerBuffer, @@ -146,22 +222,30 @@ int PaQa_RunLoopback( LoopbackContext *loopbackContext ) RecordAndPlaySinesCallback, loopbackContext ); if( err != paNoError ) goto error; + + err = Pa_StartStream( inStream ); + if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); + // Start output later so we catch the beginning of the waveform. + err = Pa_StartStream( outStream ); if( err != paNoError ) goto error; // Wait for stream to finish. - while( Pa_IsStreamActive( stream ) ) + while( Pa_IsStreamActive( inStream ) ) { Pa_Sleep(50); - //printf("loopback count = %d\n", loopbackContext->callbackCount ); - //printf("recording position = %d\n", loopbackContext->recordings[0].numFrames ); } - err = Pa_StopStream( stream ); + err = Pa_StopStream( inStream ); if( err != paNoError ) goto error; - - err = Pa_CloseStream( stream ); + + err = Pa_StopStream( outStream ); + if( err != paNoError ) goto error; + + err = Pa_CloseStream( inStream ); + if( err != paNoError ) goto error; + + err = Pa_CloseStream( outStream ); if( err != paNoError ) goto error; return 0; @@ -170,6 +254,232 @@ error: return err; } + + +/*******************************************************************/ +static int RecordAndPlayBlockingIO( PaStream *inStream, + PaStream *outStream, + LoopbackContext *loopbackContext + ) +{ + float *in = (float *)g_BigBuffer; + float *out = (float *)g_BigBuffer; + PaError err; + int done = 0; + long available; + const long maxPerBuffer = 64; + TestParameters *test = loopbackContext->test; + long framesPerBuffer = test->framesPerBuffer; + if( framesPerBuffer <= 0 ) + { + framesPerBuffer = 64; // bigger values might run past end of recording + } + + // Read in audio. + err = Pa_ReadStream( inStream, in, framesPerBuffer ); + // Ignore an overflow on the first read. + //if( !((loopbackContext->callbackCount == 0) && (err == paInputOverflowed)) ) + if( err != paInputOverflowed ) + { + QA_ASSERT_EQUALS( "Pa_ReadStream failed", paNoError, err ); + } + + // Save in a recording. + for( int i=0; itest->inputParameters.channelCount; i++ ) + { + done |= PaQa_WriteRecording( &loopbackContext->recordings[i], in + i, framesPerBuffer, loopbackContext->test->inputParameters.channelCount ); + } + + // Synthesize audio. + available = Pa_GetStreamWriteAvailable( outStream ); + if( available > (2*framesPerBuffer) ) available = (2*framesPerBuffer); + PaQa_EraseBuffer( out, available, loopbackContext->test->outputParameters.channelCount ); + for( int i=0; itest->outputParameters.channelCount; i++ ) + { + PaQa_MixSine( &loopbackContext->generators[i], out + i, available, loopbackContext->test->outputParameters.channelCount ); + } + + // Write out audio. + err = Pa_WriteStream( outStream, out, available ); + // Ignore an underflow on the first write. + //if( !((loopbackContext->callbackCount == 0) && (err == paOutputUnderflowed)) ) + if( err != paOutputUnderflowed ) + { + QA_ASSERT_EQUALS( "Pa_WriteStream failed", paNoError, err ); + } + + loopbackContext->callbackCount += 1; + + return done; +error: + return err; +} + + +/*******************************************************************/ +/** + * Open two audio streams with non-blocking IO. + * Generate sine waves on the output channels and record the input channels. + * Then close the stream. + * @return 0 if OK or negative error. + */ +int PaQa_RunLoopbackHalfDuplexBlockingIO( LoopbackContext *loopbackContext ) +{ + PaStream *inStream = NULL; + PaStream *outStream = NULL; + PaError err = 0; + TestParameters *test = loopbackContext->test; + + // Use two half duplex streams. + err = Pa_OpenStream( + &inStream, + &test->inputParameters, + NULL, + test->sampleRate, + test->framesPerBuffer, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + NULL, // causes non-blocking IO + NULL ); + if( err != paNoError ) goto error1; + err = Pa_OpenStream( + &outStream, + NULL, + &test->outputParameters, + test->sampleRate, + test->framesPerBuffer, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + NULL, // causes non-blocking IO + NULL ); + if( err != paNoError ) goto error2; + + err = Pa_StartStream( outStream ); + if( err != paNoError ) goto error3; + + err = Pa_StartStream( inStream ); + if( err != paNoError ) goto error3; + + while( err == 0 ) + { + err = RecordAndPlayBlockingIO( inStream, outStream, loopbackContext ); + if( err < 0 ) goto error3; + } + + err = Pa_StopStream( inStream ); + if( err != paNoError ) goto error3; + + err = Pa_StopStream( outStream ); + if( err != paNoError ) goto error3; + + err = Pa_CloseStream( outStream ); + if( err != paNoError ) goto error2; + + err = Pa_CloseStream( inStream ); + if( err != paNoError ) goto error1; + + + return 0; + +error3: + Pa_CloseStream( outStream ); +error2: + Pa_CloseStream( inStream ); +error1: + return err; +} + + +/*******************************************************************/ +/** + * Open one audio stream with non-blocking IO. + * Generate sine waves on the output channels and record the input channels. + * Then close the stream. + * @return 0 if OK or negative error. + */ +int PaQa_RunLoopbackFullDuplexBlockingIO( LoopbackContext *loopbackContext ) +{ + PaStream *stream = NULL; + PaError err = 0; + TestParameters *test = loopbackContext->test; + + // Use one full duplex stream. + err = Pa_OpenStream( + &stream, + &test->inputParameters, + &test->outputParameters, + test->sampleRate, + test->framesPerBuffer, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + NULL, // causes non-blocking IO + NULL ); + if( err != paNoError ) goto error1; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error2; + + while( err == 0 ) + { + err = RecordAndPlayBlockingIO( stream, stream, loopbackContext ); + if( err < 0 ) goto error2; + } + + err = Pa_StopStream( stream ); + if( err != paNoError ) goto error2; + + + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error1; + + + return 0; + +error2: + Pa_CloseStream( stream ); +error1: + return err; +} + + +/*******************************************************************/ +/** + * Run some kind of loopback test. + * @return 0 if OK or negative error. + */ +int PaQa_RunLoopback( LoopbackContext *loopbackContext ) +{ + PaError err = 0; + TestParameters *test = loopbackContext->test; + + + if( test->flags & PAQA_FLAG_TWO_STREAMS ) + { + if( test->flags & PAQA_FLAG_USE_BLOCKING_IO ) + { + err = PaQa_RunLoopbackHalfDuplexBlockingIO( loopbackContext ); + } + else + { + err = PaQa_RunLoopbackHalfDuplex( loopbackContext ); + } + } + else + { + if( test->flags & PAQA_FLAG_USE_BLOCKING_IO ) + { + err = PaQa_RunLoopbackFullDuplexBlockingIO( loopbackContext ); + } + else + { + err = PaQa_RunLoopbackFullDuplex( loopbackContext ); + } + } + + if( err != paNoError ) + { + printf("PortAudio error = %s\n", Pa_GetErrorText( err ) ); + } + return err; +} + /*******************************************************************/ static int PaQa_SaveTestResultToWaveFile( UserOptions *userOptions, PaQaRecording *recording ) { @@ -192,7 +502,7 @@ static int PaQa_SetupLoopbackContext( LoopbackContext *loopbackContextPtr, TestP for( int i=0; isamplesPerFrame; i++ ) { int err = PaQa_InitializeRecording( &loopbackContextPtr->recordings[i], testParams->maxFrames, testParams->sampleRate ); - QA_ASSERT_EQUALS( "PaQa_InitializeRecording failed", 0, err ); + QA_ASSERT_EQUALS( "PaQa_InitializeRecording failed", paNoError, err ); } for( int i=0; isamplesPerFrame; i++ ) { @@ -325,7 +635,7 @@ static int PaQa_SingleLoopBackTest( UserOptions *userOptions, TestParameters *te error: PaQa_TeardownLoopbackContext( &loopbackContext ); - return 1; + return err; } /*******************************************************************/ @@ -342,8 +652,9 @@ static void PaQa_SetDefaultTestParameters( TestParameters *testParamsPtr, PaDevi testParamsPtr->amplitude = 0.5; testParamsPtr->sampleRate = 44100; testParamsPtr->maxFrames = (int) (1.0 * testParamsPtr->sampleRate); - testParamsPtr->framesPerBuffer = 256; + testParamsPtr->framesPerBuffer = DEFAULT_FRAMES_PER_BUFFER; testParamsPtr->baseFrequency = 200.0; + testParamsPtr->flags = PAQA_FLAG_TWO_STREAMS; } /*******************************************************************/ @@ -363,12 +674,13 @@ static int PaQa_AnalyzeLoopbackConnection( UserOptions *userOptions, PaDeviceInd printf( "=============== Analysing Loopback %d to %d ====================\n", outputDevice, inputDevice ); printf( " Devices: %s => %s\n", outputDeviceInfo->name, inputDeviceInfo->name); + int flagSettings[] = { 0, 1, 2, 3 }; + int numFlagSettings = (sizeof(flagSettings)/sizeof(int)); + double sampleRates[] = { 8000.0, 11025.0, 16000.0, 22050.0, 32000.0, 44100.0, 48000.0, 96000.0 }; -// double sampleRates[] = { 16000.0, 44100.0 }; int numRates = (sizeof(sampleRates)/sizeof(double)); int framesPerBuffers[] = { 0, 16, 32, 40, 64, 100, 128, 512, 1024 }; -// int framesPerBuffers[] = { 16, 64, 512 }; int numBufferSizes = (sizeof(framesPerBuffers)/sizeof(int)); printf("|-sRate-|-buffer-|-latency-|-channel results--------------------|\n"); @@ -388,27 +700,39 @@ static int PaQa_AnalyzeLoopbackConnection( UserOptions *userOptions, PaDeviceInd testParams.maxFrames = (int) (0.5 * testParams.sampleRate); // Loop though combinations of audio parameters. - for( int iRate=0; iRate 1) ); @@ -573,6 +898,7 @@ void usage( const char *name ) printf(" -w Save bad recordings in a WAV file.\n"); printf(" -dDir Path for Directory for WAV files. Default is current directory.\n"); printf(" -m Just test the DSP Math code and not the audio devices.\n"); + printf(" -v Verbose reports.\n"); } /*******************************************************************/ @@ -626,6 +952,10 @@ int main( int argc, char **argv ) userOptions.waveFilePath = &arg[2]; break; + case 'v': + userOptions.verbose = 1; + break; + case 'h': usage( name ); return(0); diff --git a/test/README.txt b/test/README.txt index f3a0b82..e2566a3 100644 --- a/test/README.txt +++ b/test/README.txt @@ -1,9 +1,11 @@ +TODO - This should be moved into a doxydoc page. + This directory contains various programs to test PortAudio. The files named patest_* are tests, the files named debug_* are just scratch files that may or may not work. All following tests are up to date with the V19 API. They should all compile -(without any warnings on GCC 3.3). Note that this does not necissarily mean that +(without any warnings on GCC 3.3). Note that this does not necessarily mean that the tests pass, just that they compile. x- paqa_devs.c diff --git a/test/debug_convert.c b/test/debug_convert.c deleted file mode 100644 index 8933f1e..0000000 --- a/test/debug_convert.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * $Id$ - * Convert tagged values. - * - * Author: Phil Burk - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include "portaudio.h" -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -//#define OUTPUT_DEVICE (11) -#define NUM_SECONDS (8) -#define SLEEP_DUR (800) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) - -#define NUM_BUFFERS (0) - -typedef struct -{ - unsigned int framesToGo; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may 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 patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - short *out = (short*)outputBuffer; - int i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) finished = 1; - - for( i=0; i -#include -#include "portaudio.h" -#include "pa_host.h" - -/*******************************************************************/ -int main(void); -int main(void) -{ - long max,min; - int i; - - for( i=0; i<10000; i++ ) - { - long dither = PaConvert_TriangularDither(); - // printf("dither = 0x%08X\n", dither ); - if( dither < min ) min = dither; - else if( dither > max ) max = dither; - } - printf("min = 0x%08X = %d, max = 0x%08X = %d\n", min, min, max, max ); -} diff --git a/test/debug_dual.c b/test/debug_dual.c deleted file mode 100644 index e7bfe06..0000000 --- a/test/debug_dual.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * $Id$ - * debug_dual.c - * Try to open TWO streams on separate cards. - * Play a sine sweep using the Portable Audio api for several seconds. - * Hacked test for debugging PA. - * - * Author: Phil Burk - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include "portaudio.h" -#define DEV_ID_1 (13) -#define DEV_ID_2 (15) -#define NUM_SECONDS (8) -#define SLEEP_DUR (800) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#if 0 -#define MIN_LATENCY_MSEC (200) -#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) -#else -#define NUM_BUFFERS (0) -#endif -#define MIN_FREQ (100.0f) -#define MAX_FREQ (4000.0f) -#define FREQ_SCALAR (1.00002f) -#define CalcPhaseIncrement(freq) (freq/SAMPLE_RATE) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (400) -typedef struct -{ - float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation - float phase_increment; - float left_phase; - float right_phase; -} -paTestData; -/* Convert phase between and 1.0 to sine value - * using linear interpolation. - */ -float LookupSine( paTestData *data, float phase ); -float LookupSine( paTestData *data, float phase ) -{ - float fIndex = phase*TABLE_SIZE; - int index = (int) fIndex; - float fract = fIndex - index; - float lo = data->sine[index]; - float hi = data->sine[index+1]; - float val = lo + fract*(hi-lo); - return val; -} -/* This routine will be called by the PortAudio engine when audio is needed. -** It may 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 patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - unsigned long i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - - for( i=0; ileft_phase); /* left */ - *out++ = LookupSine(data, data->right_phase); /* right */ - data->left_phase += data->phase_increment; - if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; - data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ - if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; - /* sweep frequency then start over. */ - data->phase_increment *= FREQ_SCALAR; - if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ); - } - return 0; -} - -PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID, - paTestData *data ); -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream1, *stream2; - PaError err; - paTestData DATA1, DATA2; - printf("PortAudio Test: DUAL sine sweep. ask for %d buffers\n", NUM_BUFFERS ); - err = Pa_Initialize(); - if( err != paNoError ) goto error; - err = TestStart( &stream1, DEV_ID_1, &DATA1 ); - if( err != paNoError ) goto error; - err = TestStart( &stream2, DEV_ID_2, &DATA2 ); - if( err != paNoError ) goto error; - printf("Hit ENTER\n"); - getchar(); - err = Pa_StopStream( stream1 ); - if( err != paNoError ) goto error; - err = Pa_StopStream( stream2 ); - if( err != paNoError ) goto error; - Pa_Terminate(); - printf("Test finished.\n"); - return err; -error: - Pa_Terminate(); - fprintf( stderr, "An error occured while using the portaudio stream\n" ); - fprintf( stderr, "Error number: %d\n", err ); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return err; -} -PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID, paTestData *data ) -{ - PortAudioStream *stream; - PaError err; - int i; - /* initialise sinusoidal wavetable */ - for( i=0; isine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); - } - data->sine[TABLE_SIZE] = data->sine[0]; // set guard point - data->left_phase = data->right_phase = 0.0; - data->phase_increment = CalcPhaseIncrement(MIN_FREQ); - printf("PortAudio Test: output device = %d\n", devID ); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - devID, - 2, /* stereo output */ - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ - paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - data ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - *streamPtr = stream; - return 0; -error: - return err; -} diff --git a/test/debug_multi_in.c b/test/debug_multi_in.c deleted file mode 100644 index 28ea65b..0000000 --- a/test/debug_multi_in.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * $Id$ - * debug_multi_in.c - * Pass output from each of multiple channels - * to a stereo output using the Portable Audio api. - * Hacked test for debugging PA. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include -#include "portaudio.h" -//#define INPUT_DEVICE_NAME ("EWS88 MT Interleaved Rec") -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -//#define OUTPUT_DEVICE (18) -#define SAMPLE_RATE (22050) -#define FRAMES_PER_BUFFER (256) -#define MIN_LATENCY_MSEC (400) -#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -typedef struct -{ - int liveChannel; - int numChannels; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may 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 patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - float *in = (float*)inputBuffer; - int i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( in == NULL ) return 0; - for( i=0; i<(int)framesPerBuffer; i++ ) - { - /* Copy one channel of input to output. */ - *out++ = in[data->liveChannel]; - *out++ = in[data->liveChannel]; - in += data->numChannels; - } - return 0; -} -/*******************************************************************/ -int PaFindDeviceByName( const char *name ) -{ - int i; - int numDevices; - const PaDeviceInfo *pdi; - int len = strlen( name ); - PaDeviceID result = paNoDevice; - numDevices = Pa_CountDevices(); - for( i=0; iname, len ) == 0 ) - { - result = i; - break; - } - } - return result; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - PaDeviceID inputDevice; - const PaDeviceInfo *pdi; - printf("PortAudio Test: input signal from each channel. %d buffers\n", NUM_BUFFERS ); - data.liveChannel = 0; - err = Pa_Initialize(); - if( err != paNoError ) goto error; -#ifdef INPUT_DEVICE_NAME - printf("Try to use device: %s\n", INPUT_DEVICE_NAME ); - inputDevice = PaFindDeviceByName(INPUT_DEVICE_NAME); - if( inputDevice == paNoDevice ) - { - printf("Could not find %s. Using default instead.\n", INPUT_DEVICE_NAME ); - inputDevice = Pa_GetDefaultInputDeviceID(); - } -#else - printf("Using default input device.\n"); - inputDevice = Pa_GetDefaultInputDeviceID(); -#endif - pdi = Pa_GetDeviceInfo( inputDevice ); - if( pdi == NULL ) - { - printf("Could not get device info!\n"); - goto error; - } - data.numChannels = pdi->maxInputChannels; - printf("Input Device name is %s\n", pdi->name ); - printf("Input Device has %d channels.\n", pdi->maxInputChannels); - err = Pa_OpenStream( - &stream, - inputDevice, - pdi->maxInputChannels, - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - 2, - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - data.liveChannel = 0; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - for( i=0; i -#include -#include "portaudio.h" - -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#define FREQ_INCR (300.0 / SAMPLE_RATE) -#define MAX_CHANNELS (64) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -typedef struct -{ - int numChannels; - double phases[MAX_CHANNELS]; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may 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 patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int frameIndex, channelIndex; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) - { - for( channelIndex=0; channelIndexnumChannels; channelIndex++ ) - { - /* Output sine wave on every channel. */ - *out++ = (float) sin(data->phases[channelIndex]); - - /* Play each channel at a higher frequency. */ - data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); - if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); - } - } - - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - const PaDeviceInfo *pdi; - paTestData data = {0}; - printf("PortAudio Test: output sine wave on each channel.\n" ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); - data.numChannels = pdi->maxOutputChannels; - if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; - printf("Number of Channels = %d\n", data.numChannels ); - - err = Pa_OpenStream( - &stream, - paNoDevice, /* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - data.numChannels, - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Hit ENTER to stop sound.\n"); - fflush(stdout); - getchar(); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - Pa_CloseStream( stream ); - 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; -} diff --git a/test/debug_record.c b/test/debug_record.c deleted file mode 100644 index 62cc47c..0000000 --- a/test/debug_record.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - * $Id$ - * debug_record.c - * Record input into an array. - * Save array to a file. - * Based on patest_record.c but with various ugly debug hacks thrown in. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include -#include "portaudio.h" -#define SAMPLE_RATE (22050) -#define NUM_SECONDS (10) -#define SLEEP_DUR_MSEC (200) -#define FRAMES_PER_BUFFER (1<<10) -#define NUM_REC_BUFS (0) - -#if 1 -#define PA_SAMPLE_TYPE paFloat32 -typedef float SAMPLE; -#else -#define PA_SAMPLE_TYPE paInt16 -typedef short SAMPLE; -#endif - -typedef struct -{ - long frameIndex; /* Index into sample array. */ - long maxFrameIndex; - long samplesPerFrame; - long numSamples; - 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 * data->samplesPerFrame]; - long framesToCalc; - unsigned long i; - int finished; - unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; - - (void) outputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - framesToCalc = framesLeft; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - finished = 0; - } - if( inputBuffer == NULL ) - { - for( i=0; iframeIndex += framesToCalc; - 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 * data->samplesPerFrame]; - SAMPLE *wptr = (SAMPLE*)outputBuffer; - unsigned long i; - int finished; - unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; - if( outputBuffer == NULL ) return 0; - (void) inputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - /* final buffer... */ - for( i=0; iframeIndex += framesLeft; - finished = 1; - } - else - { - for( i=0; iframeIndex += framesPerBuffer; - finished = 0; - } - return finished; -} - -/****************************************************************/ -PaError TestRecording( paTestData *dataPtr ) -{ - PortAudioStream *stream; - PaError err; - int i; - - /* Record some audio. */ - err = Pa_OpenStream( - &stream, - Pa_GetDefaultInputDeviceID(), - dataPtr->samplesPerFrame, /* stereo input */ - PA_SAMPLE_TYPE, - NULL, - paNoDevice, - 0, - PA_SAMPLE_TYPE, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - recordCallback, - dataPtr ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Now recording!\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - if( Pa_StreamActive( stream ) <= 0) - { - printf("Stream inactive!\n"); - break; - } - if( dataPtr->maxFrameIndex <= dataPtr->frameIndex ) - { - printf("Buffer recording complete.\n"); - break; - } - Pa_Sleep(100); - printf("index = %d\n", dataPtr->frameIndex ); fflush(stdout); - } - - printf("Finished loop. Close stream.\n"); fflush(stdout); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - - printf("Done.\n"); fflush(stdout); - { - SAMPLE max = 0; - SAMPLE posVal; - int i; - for( i=0; inumSamples; i++ ) - { - posVal = dataPtr->recordedSamples[i]; - if( posVal < 0 ) posVal = -posVal; - if( posVal > max ) max = posVal; - } - printf("Largest recorded sample = %d\n", max ); - } - /* Write recorded data to a file. */ -#if 0 - { - FILE *fid; - fid = fopen("recorded.raw", "wb"); - if( fid == NULL ) - { - printf("Could not open file."); - } - else - { - fwrite( dataPtr->recordedSamples, dataPtr->samplesPerFrame * sizeof(SAMPLE), totalFrames, fid ); - fclose( fid ); - printf("Wrote data to 'recorded.raw'\n"); - } - } -#endif - -error: - return err; -} - -/****************************************************************/ -PaError TestPlayback( paTestData *dataPtr ) -{ - PortAudioStream *stream; - PaError err; - int i; - - /* Playback recorded data. */ - dataPtr->frameIndex = 0; - printf("Begin playback.\n"); fflush(stdout); - err = Pa_OpenStream( - &stream, - paNoDevice, - 0, /* NO input */ - PA_SAMPLE_TYPE, - NULL, - Pa_GetDefaultOutputDeviceID(), - dataPtr->samplesPerFrame, /* stereo output */ - 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, - dataPtr ); - if( err != paNoError ) goto error; - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - printf("Waiting for playback to finish.\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - Pa_Sleep(100); - printf("index = %d\n", dataPtr->frameIndex ); - } - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - -error: - return err; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData data; - long totalFrames; - long numBytes; - long i; - printf("patest_record.c\n"); fflush(stdout); - - data.frameIndex = 0; - data.samplesPerFrame = 2; - data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE; - - printf("totalFrames = %d\n", totalFrames ); fflush(stdout); - data.numSamples = totalFrames * data.samplesPerFrame; - - numBytes = data.numSamples * sizeof(SAMPLE); - data.recordedSamples = (SAMPLE *) malloc( numBytes ); - if( data.recordedSamples == NULL ) - { - printf("Could not allocate record array.\n"); - exit(1); - } - for( i=0; i -#include -#include -#include "portaudio.h" -#define SAMPLE_RATE (22050) -#define NUM_SECONDS (4) -#define SLEEP_DUR_MSEC (200) -#define FRAMES_PER_BUFFER (256) -#define NUM_REC_BUFS (0) - -#if 1 -#define PA_SAMPLE_TYPE paFloat32 -typedef float SAMPLE; -#else -#define PA_SAMPLE_TYPE paInt16 -typedef short SAMPLE; -#endif - -typedef struct -{ - long frameIndex; /* Index into sample array. */ - long maxFrameIndex; - long samplesPerFrame; - long numSamples; - PortAudioStream *outputStream; - PortAudioStream *inputStream; - 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 * data->samplesPerFrame]; - long framesToCalc; - unsigned long i; - int finished; - unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; - - (void) outputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - framesToCalc = framesLeft; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - finished = 0; - } - if( inputBuffer == NULL ) - { - for( i=0; iframeIndex += framesToCalc; - 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 * data->samplesPerFrame]; - SAMPLE *wptr = (SAMPLE*)outputBuffer; - unsigned long i; - int finished; - unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; - if( outputBuffer == NULL ) return 0; - (void) inputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( framesLeft < framesPerBuffer ) - { - /* final buffer... */ - for( i=0; iframeIndex += framesLeft; - finished = 1; - } - else - { - for( i=0; iframeIndex += framesPerBuffer; - finished = 0; - } - return finished; -} - -/****************************************************************/ -PaError TestRecording( paTestData *dataPtr ) -{ - PaError err; - int i; - int lastIndex = 0; - -/* Open input stream if not already open. */ - if( dataPtr->inputStream == NULL ) - { - /* Record some audio. */ - err = Pa_OpenStream( - &dataPtr->inputStream, - Pa_GetDefaultInputDeviceID(), - dataPtr->samplesPerFrame, /* stereo input */ - PA_SAMPLE_TYPE, - NULL, - paNoDevice, - 0, - PA_SAMPLE_TYPE, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - recordCallback, - dataPtr ); - if( err != paNoError ) goto error; - } - - dataPtr->frameIndex = 0; - - err = Pa_StartStream( dataPtr->inputStream ); - if( err != paNoError ) goto error; - - printf("Now recording!\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - int frameIndex, delta; - Pa_Sleep(SLEEP_DUR_MSEC); - - frameIndex = dataPtr->frameIndex; - if( Pa_StreamActive( dataPtr->inputStream ) <= 0) - { - printf("Stream inactive!\n"); - break; - } - if( dataPtr->maxFrameIndex <= frameIndex ) - { - printf("Buffer recording complete.\n"); - break; - } - - delta = frameIndex - lastIndex; - lastIndex = frameIndex; - printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout); - } - - err = Pa_StopStream( dataPtr->inputStream ); - if( err != paNoError ) goto error; - - printf("Done.\n"); fflush(stdout); - -error: - return err; -} - -/****************************************************************/ -PaError TestPlayback( paTestData *dataPtr ) -{ - PaError err; - int i; - int lastIndex = 0; - - /* Playback recorded data. */ - dataPtr->frameIndex = 0; - printf("Begin playback.\n"); fflush(stdout); - -/* Open output stream if not already open. */ - if( dataPtr->outputStream == NULL ) - { - err = Pa_OpenStream( - &dataPtr->outputStream, - paNoDevice, - 0, /* NO input */ - PA_SAMPLE_TYPE, - NULL, - Pa_GetDefaultOutputDeviceID(), - dataPtr->samplesPerFrame, /* stereo output */ - 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, - dataPtr ); - if( err != paNoError ) goto error; - } - - err = Pa_StartStream( dataPtr->outputStream ); - if( err != paNoError ) goto error; - - printf("Waiting for playback to finish.\n"); fflush(stdout); - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - int frameIndex, delta; - Pa_Sleep(SLEEP_DUR_MSEC); - frameIndex = dataPtr->frameIndex; - delta = frameIndex - lastIndex; - lastIndex = frameIndex; - printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout); - } - - err = Pa_StopStream( dataPtr->outputStream ); - if( err != paNoError ) goto error; - -error: - return err; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData data = { 0 }; - long totalFrames; - long numBytes; - long i; - printf("patest_record.c\n"); fflush(stdout); - -/* Set up test data structure and sample array. */ - data.frameIndex = 0; - data.samplesPerFrame = 2; - data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE; - - printf("totalFrames = %d\n", totalFrames ); fflush(stdout); - data.numSamples = totalFrames * data.samplesPerFrame; - - numBytes = data.numSamples * sizeof(SAMPLE); - data.recordedSamples = (SAMPLE *) malloc( numBytes ); - if( data.recordedSamples == NULL ) - { - printf("Could not allocate record array.\n"); - exit(1); - } - for( i=0; i - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include "portaudio.h" -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -//#define OUTPUT_DEVICE (11) -#define NUM_SECONDS (8) -#define SLEEP_DUR (800) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#if 0 -#define MIN_LATENCY_MSEC (200) -#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) -#else -#define NUM_BUFFERS (0) -#endif -#define MIN_FREQ (100.0f) -#define MAX_FREQ (4000.0f) -#define FREQ_SCALAR (1.00002f) -#define CalcPhaseIncrement(freq) (freq/SAMPLE_RATE) -#ifndef M_PI -#define M_PI (3.14159265) -#endif -#define TABLE_SIZE (400) -typedef struct -{ - float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation - float phase_increment; - float left_phase; - float right_phase; - unsigned int framesToGo; -} -paTestData; -/* Convert phase between and 1.0 to sine value - * using linear interpolation. - */ -float LookupSine( paTestData *data, float phase ); -float LookupSine( paTestData *data, float phase ) -{ - float fIndex = phase*TABLE_SIZE; - int index = (int) fIndex; - float fract = fIndex - index; - float lo = data->sine[index]; - float hi = data->sine[index+1]; - float val = lo + fract*(hi-lo); - return val; -} -/* This routine will be called by the PortAudio engine when audio is needed. -** It may 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 patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int framesToCalc; - int i; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) - { - framesToCalc = data->framesToGo; - data->framesToGo = 0; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - data->framesToGo -= framesPerBuffer; - } - - for( i=0; ileft_phase); /* left */ - *out++ = LookupSine(data, data->right_phase); /* right */ - data->left_phase += data->phase_increment; - if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; - data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ - if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; - /* sweep frequency then start over. */ - data->phase_increment *= FREQ_SCALAR; - if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ); - } - /* zero remainder of final buffer */ - for( ; i<(int)framesPerBuffer; i++ ) - { - *out++ = 0; /* left */ - *out++ = 0; /* right */ - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int i; - int totalSamps; - printf("PortAudio Test: output sine sweep. ask for %d buffers\n", NUM_BUFFERS ); - /* initialise sinusoidal wavetable */ - for( i=0; i -#include -#include "portaudio.h" - -#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) -#define FREQ_INCR (300.0 / SAMPLE_RATE) -#define MAX_CHANNELS (64) - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - -typedef struct -{ - int numChannels; - double phases[MAX_CHANNELS]; - float amplitude; -} -paTestData; - -/* This routine will be called by the PortAudio engine when audio is needed. -** It may 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 patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - float *out = (float*)outputBuffer; - int frameIndex, channelIndex; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) - { - for( channelIndex=0; channelIndexnumChannels; channelIndex++ ) - { - /* Output sine wave on every channel. */ - *out++ = (float) ( data->amplitude * sin(data->phases[channelIndex]) ); - - /* Play each channel at a higher frequency. */ - data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); - if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); - } - } - - return 0; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - char pad[256]; - PortAudioStream *stream; - PaError err; - const PaDeviceInfo *pdi; - paTestData data = {0}; - printf("PortAudio Test: output sine wave on each channel.\n" ); - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); - data.numChannels = pdi->maxOutputChannels; - if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; - printf("Number of Channels = %d\n", data.numChannels ); - data.amplitude = 1.0; - - err = Pa_OpenStream( - &stream, - paNoDevice, /* default input device */ - 0, /* no input */ - paFloat32, /* 32 bit floating point input */ - NULL, - OUTPUT_DEVICE, - data.numChannels, - paFloat32, /* 32 bit floating point output */ - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - do - { - printf("Current amplitude = %f\n", data.amplitude ); - printf("Enter new amplitude or 'q' to quit.\n"); - fflush(stdout); - gets( pad ); - if( pad[0] != 'q' ) - { - // I tried to use atof but it seems to be broken on Mac OS X 10.1 - float amp; - sscanf( pad, "%f", & ); - data.amplitude = amp; - } - } while( pad[0] != 'q' ); - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - Pa_CloseStream( stream ); - 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; -} diff --git a/test/debug_sine_formats.c b/test/debug_sine_formats.c deleted file mode 100644 index 61440d7..0000000 --- a/test/debug_sine_formats.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * $Id$ - * patest_sine_formats.c - * Play a sine wave using the Portable Audio api for several seconds. - * Test various data formats. - * - * Author: Phil Burk - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include "portaudio.h" - -#define NUM_SECONDS (10) -#define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (256) - -#define LEFT_FREQ (SAMPLE_RATE/512.0) /* So we hit 1.0 */ -#define RIGHT_FREQ (500.0) - -#define AMPLITUDE (1.0) - -/* Select ONE format for testing. */ -#define TEST_UINT8 (1) -#define TEST_INT8 (0) -#define TEST_INT16 (0) -#define TEST_FLOAT32 (0) - -#if TEST_UINT8 -#define TEST_FORMAT paUInt8 -typedef unsigned char SAMPLE_t; -#define SAMPLE_ZERO (0x80) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) -#define FORMAT_NAME "Unsigned 8 Bit" - -#elif TEST_INT8 -#define TEST_FORMAT paInt8 -typedef char SAMPLE_t; -#define SAMPLE_ZERO (0) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) -#define FORMAT_NAME "Signed 8 Bit" - -#elif TEST_INT16 -#define TEST_FORMAT paInt16 -typedef short SAMPLE_t; -#define SAMPLE_ZERO (0) -#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x))) -#define FORMAT_NAME "Signed 16 Bit" - -#elif TEST_FLOAT32 -#define TEST_FORMAT paFloat32 -typedef float SAMPLE_t; -#define SAMPLE_ZERO (0.0) -#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x)) -#define FORMAT_NAME "Float 32 Bit" -#endif - -#ifndef M_PI -#define M_PI (3.14159265) -#endif - - -typedef struct -{ - double left_phase; - double right_phase; - unsigned int framesToGo; -} -paTestData; -/* This routine will be called by the PortAudio engine when audio is needed. -** It may 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 patestCallback( void *inputBuffer, void *outputBuffer, - unsigned long framesPerBuffer, - PaTimestamp outTime, void *userData ) -{ - paTestData *data = (paTestData*)userData; - SAMPLE_t *out = (SAMPLE_t *)outputBuffer; - SAMPLE_t sample; - int i; - int framesToCalc; - int finished = 0; - (void) outTime; /* Prevent unused variable warnings. */ - (void) inputBuffer; - - if( data->framesToGo < framesPerBuffer ) - { - framesToCalc = data->framesToGo; - data->framesToGo = 0; - finished = 1; - } - else - { - framesToCalc = framesPerBuffer; - data->framesToGo -= framesPerBuffer; - } - - for( i=0; ileft_phase += (LEFT_FREQ / SAMPLE_RATE); - if( data->left_phase > 1.0) data->left_phase -= 1.0; - sample = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. ))); /**/ - *out++ = sample; -/* *out++ = sample; /**/ -/* *out++ = 0; /**/ - - data->right_phase += (RIGHT_FREQ / SAMPLE_RATE); - if( data->right_phase > 1.0) data->right_phase -= 1.0; - *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. ))); /**/ -/* *out++ = 0; /* */ - } - /* zero remainder of final buffer */ - for( ; i<(int)framesPerBuffer; i++ ) - { - *out++ = SAMPLE_ZERO; /* left */ - *out++ = SAMPLE_ZERO; /* right */ - } - return finished; -} -/*******************************************************************/ -int main(void); -int main(void) -{ - PortAudioStream *stream; - PaError err; - paTestData data; - int totalSamps; - - printf("PortAudio Test: output " FORMAT_NAME "\n"); - - - data.left_phase = data.right_phase = 0.0; - data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &stream, - paNoDevice,/* default input device */ - 0, /* no input */ - TEST_FORMAT, - NULL, - Pa_GetDefaultOutputDeviceID(), /* default output device */ - 2, /* stereo output */ - TEST_FORMAT, - NULL, - SAMPLE_RATE, - FRAMES_PER_BUFFER, - 0, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - patestCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS ); - while( Pa_StreamActive( stream ) ) Pa_Sleep(10); - - err = Pa_CloseStream( stream ); - if( err != paNoError ) goto error; - Pa_Terminate(); - - printf("PortAudio Test Finished: " FORMAT_NAME "\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; -} diff --git a/test/debug_srate.c b/test/debug_srate.c deleted file mode 100644 index f2bf509..0000000 --- a/test/debug_srate.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * $Id$ - * debug_record_reuse.c - * Record input into an array. - * Save array to a file. - * Based on patest_record.c but with various ugly debug hacks thrown in. - * Loop twice and reuse same streams. - * - * Author: Phil Burk http://www.softsynth.com - * - * This program uses the PortAudio Portable Audio Library. - * For more information see: http://www.portaudio.com - * Copyright (c) 1999-2000 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include -#include -#include -#include "portaudio.h" - -#define EWS88MT_12_REC (1) -#define EWS88MT_12_PLAY (10) -#define SBLIVE_REC (2) -#define SBLIVE_PLAY (11) - -#if 0 -#define INPUT_DEVICE_ID Pa_GetDefaultInputDeviceID() -#define OUTPUT_DEVICE_ID Pa_GetDefaultOutputDeviceID() -#else -#define INPUT_DEVICE_ID (EWS88MT_12_REC) -#define OUTPUT_DEVICE_ID (SBLIVE_PLAY) -#endif - -#define INPUT_SAMPLE_RATE (22050.0) -#define OUTPUT_SAMPLE_RATE (22050.0) -#define NUM_SECONDS (4) -#define SLEEP_DUR_MSEC (1000) -#define FRAMES_PER_BUFFER (64) -#define NUM_REC_BUFS (0) -#define SAMPLES_PER_FRAME (2) - -#define PA_SAMPLE_TYPE paInt16 -typedef short SAMPLE; - -typedef struct -{ - long frameIndex; /* Index into sample array. */ -} -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; - (void) outputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( inputBuffer != NULL ) - { - data->frameIndex += framesPerBuffer; - } - return 0; -} - -/* 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; - (void) inputBuffer; /* Prevent unused variable warnings. */ - (void) outTime; - - if( outputBuffer != NULL ) - { - data->frameIndex += framesPerBuffer; - } - return 0; -} - -/****************************************************************/ -PaError MeasureStreamRate( PortAudioStream *stream, paTestData *dataPtr, double *ratePtr ) -{ - PaError err; - int i; - int totalFrames = 0; - int totalMSec = 0; - - dataPtr->frameIndex = 0; - - err = Pa_StartStream( stream ); - if( err != paNoError ) goto error; - - for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) - { - int delta, endIndex; - - int startIndex = dataPtr->frameIndex; - Pa_Sleep(SLEEP_DUR_MSEC); - endIndex = dataPtr->frameIndex; - - delta = endIndex - startIndex; - totalFrames += delta; - totalMSec += SLEEP_DUR_MSEC; - - printf("index = %d, delta = %d\n", endIndex, delta ); fflush(stdout); - } - - err = Pa_StopStream( stream ); - if( err != paNoError ) goto error; - - *ratePtr = (totalFrames * 1000.0) / totalMSec; - -error: - return err; -} - -void ReportRate( double measuredRate, double expectedRate ) -{ - double error; - - error = (measuredRate - expectedRate) / expectedRate; - error = (error < 0 ) ? -error : error; - - printf("Measured rate = %6.1f, expected rate = %6.1f\n", - measuredRate, expectedRate ); - if( error > 0.1 ) - { - printf("ERROR: unexpected rate! --------------------- ERROR!\n"); - } - else - { - printf("SUCCESS: rate within tolerance!\n"); - } -} - -/*******************************************************************/ -int main(void); -int main(void) -{ - PaError err; - paTestData data = { 0 }; - long i; - double rate; - const PaDeviceInfo *pdi; - - PortAudioStream *outputStream; - PortAudioStream *inputStream; - - err = Pa_Initialize(); - if( err != paNoError ) goto error; - - - pdi = Pa_GetDeviceInfo( INPUT_DEVICE_ID ); - printf("Input device = %s\n", pdi->name ); - pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE_ID ); - printf("Output device = %s\n", pdi->name ); - -/* Open input stream. */ - err = Pa_OpenStream( - &inputStream, - INPUT_DEVICE_ID, - SAMPLES_PER_FRAME, /* stereo input */ - PA_SAMPLE_TYPE, - NULL, - paNoDevice, - 0, - PA_SAMPLE_TYPE, - NULL, - INPUT_SAMPLE_RATE, - FRAMES_PER_BUFFER, /* frames per buffer */ - NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ - paClipOff, /* we won't output out of range samples so don't bother clipping them */ - recordCallback, - &data ); - if( err != paNoError ) goto error; - - err = Pa_OpenStream( - &outputStream, - paNoDevice, - 0, /* NO input */ - PA_SAMPLE_TYPE, - NULL, - OUTPUT_DEVICE_ID, - SAMPLES_PER_FRAME, /* stereo output */ - PA_SAMPLE_TYPE, - NULL, - OUTPUT_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; - -/* Record and playback multiple times. */ - for( i=0; i<2; i++ ) - { - printf("Measuring INPUT ------------------------- \n"); - err = MeasureStreamRate( inputStream, &data, &rate ); - if( err != paNoError ) goto error; - ReportRate( rate, INPUT_SAMPLE_RATE ); - - printf("Measuring OUTPUT ------------------------- \n"); - err = MeasureStreamRate( outputStream, &data, &rate ); - if( err != paNoError ) goto error; - ReportRate( rate, OUTPUT_SAMPLE_RATE ); - } - -/* Clean up. */ - err = Pa_CloseStream( inputStream ); - if( err != paNoError ) goto error; - - err = Pa_CloseStream( outputStream ); - if( err != paNoError ) goto error; - - if( err != paNoError ) goto error; - - Pa_Terminate(); - - printf("Test complete.\n"); fflush(stdout); - 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 ) ); - if( err == paHostError ) - { - fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() ); - } - return -1; -} diff --git a/test/debug_test1.c b/test/debug_test1.c deleted file mode 100644 index 1321f62..0000000 --- a/test/debug_test1.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * $Id$ - patest1.c - Ring modulate the audio input with a 441hz sine wave for 20 seconds - using the Portable Audio api - Author: Ross Bencina - Modifications: - April 5th, 2001 - PLB - Check for NULL inputBuffer. -*/ -#include -#include -#include "portaudio.h" -#ifndef M_PI -#define M_PI (3.14159265) -#endif -typedef struct -{ - float sine[100]; - int phase; - int sampsToGo; -} -patest1data; -static int patest1Callback( void *inputBuffer, void *outputBuffer, - unsigned long bufferFrames, - PaTimestamp outTime, void *userData ) -{ - patest1data *data = (patest1data*)userData; - float *in = (float*)inputBuffer; - float *out = (float*)outputBuffer; - int framesToCalc = bufferFrames; - unsigned long i; - int finished = 0; - if(inputBuffer == NULL) return 0; - if( data->sampsToGo < bufferFrames ) - { - finished = 1; - } - for( i=0; iphase >= 100 ) - data->phase = 0; - } - data->sampsToGo -= bufferFrames; - /* zero remainder of final buffer if not already done */ - for( ; i int conversions diff --git a/test/patest_leftright.c b/test/patest_leftright.c index 42d3bde..33ccf12 100644 --- a/test/patest_leftright.c +++ b/test/patest_leftright.c @@ -57,15 +57,17 @@ #define M_PI (3.14159265) #endif #define TABLE_SIZE (200) +#define BALANCE_DELTA (0.001) + typedef struct { float sine[TABLE_SIZE]; int left_phase; int right_phase; - int toggle; - int countDown; -} -paTestData; + float targetBalance; // 0.0 = left, 1.0 = right + float currentBalance; +} paTestData; + /* This routine will be called by the PortAudio engine when audio is needed. ** It may called at interrupt level on some machines so don't do anything ** that could mess up the system like calling malloc() or free(). @@ -86,30 +88,25 @@ static int patestCallback( const void *inputBuffer, for( i=0; itoggle ) - { - *out++ = data->sine[data->left_phase]; /* left */ - *out++ = 0; /* right */ - } - else - { - *out++ = 0; /* left */ - *out++ = data->sine[data->right_phase]; /* right */ - } - + // Smoothly pan between left and right. + if( data->currentBalance < data->targetBalance ) + { + data->currentBalance += BALANCE_DELTA; + } + else if( data->currentBalance > data->targetBalance ) + { + data->currentBalance -= BALANCE_DELTA; + } + // Apply left/right balance. + *out++ = data->sine[data->left_phase] * (1.0f - data->currentBalance); /* left */ + *out++ = data->sine[data->right_phase] * data->currentBalance; /* right */ + data->left_phase += 1; if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE; data->right_phase += 3; /* higher pitch so we can distinguish left and right. */ if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE; } - if( data->countDown < 0 ) - { - data->countDown = SAMPLE_RATE; - data->toggle = !data->toggle; - } - data->countDown -= framesPerBuffer; - return finished; } @@ -121,9 +118,7 @@ int main(void) PaStreamParameters outputParameters; PaError err; paTestData data; - int i; - int timeout; - + int i; printf("Play different tone sine waves that alternate between left and right channel.\n"); printf("The low tone should be on the left channel.\n"); @@ -132,8 +127,9 @@ int main(void) { data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); } - data.left_phase = data.right_phase = data.toggle = 0; - data.countDown = SAMPLE_RATE; + data.left_phase = data.right_phase = 0; + data.currentBalance = 0.0; + data.targetBalance = 0.0; err = Pa_Initialize(); if( err != paNoError ) goto error; @@ -162,12 +158,16 @@ int main(void) if( err != paNoError ) goto error; printf("Play for several seconds.\n"); - timeout = NUM_SECONDS * 4; - while( timeout > 0 ) - { - Pa_Sleep( 300 ); /*(Irix very much likes sleeps <= 1000 ms.)*/ - timeout -= 1; - } + for( i=0; i<4; i++ ) + { + printf("Hear low sound on left side.\n"); + data.targetBalance = 0.01; + Pa_Sleep( 1000 ); + + printf("Hear high sound on right side.\n"); + data.targetBalance = 0.99; + Pa_Sleep( 1000 ); + } err = Pa_StopStream( stream ); if( err != paNoError ) goto error; diff --git a/test/patest_out_underflow.c b/test/patest_out_underflow.c index 3713a06..e69def3 100644 --- a/test/patest_out_underflow.c +++ b/test/patest_out_underflow.c @@ -47,7 +47,7 @@ #include #include "portaudio.h" -#define MAX_SINES (500) +#define MAX_SINES (1000) #define MAX_LOAD (1.2) #define SAMPLE_RATE (44100) #define FRAMES_PER_BUFFER (512) @@ -159,12 +159,25 @@ int main(void) /* Determine number of sines required to get to 50% */ do - { - data.sineCount++; - Pa_Sleep( 100 ); + { + Pa_Sleep( 100 ); load = Pa_GetStreamCpuLoad( stream ); printf("sineCount = %d, CPU load = %f\n", data.sineCount, load ); + + if( load < 0.3 ) + { + data.sineCount += 10; + } + else if( load < 0.4 ) + { + data.sineCount += 2; + } + else + { + data.sineCount += 1; + } + } while( load < 0.5 && data.sineCount < (MAX_SINES-1)); @@ -174,7 +187,7 @@ int main(void) stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD ); if( stressedSineCount > MAX_SINES ) stressedSineCount = MAX_SINES; - for( ; data.sineCount < stressedSineCount; data.sineCount++ ) + for( ; data.sineCount < stressedSineCount; data.sineCount+=4 ) { Pa_Sleep( 100 ); load = Pa_GetStreamCpuLoad( stream ); diff --git a/test/patest_read_write_wire.c b/test/patest_read_write_wire.c index 9941ae6..a0a042c 100644 --- a/test/patest_read_write_wire.c +++ b/test/patest_read_write_wire.c @@ -52,9 +52,15 @@ #define SAMPLE_RATE (44100) #define FRAMES_PER_BUFFER (1024) #define NUM_CHANNELS (2) +#define NUM_SECONDS (15) /* #define DITHER_FLAG (paDitherOff) */ #define DITHER_FLAG (0) /**/ +/* @todo Underflow and overflow is disabled until we fix priming of blocking write. */ +#define CHECK_OVERFLOW (0) +#define CHECK_UNDERFLOW (0) + + /* Select sample format. */ #if 0 #define PA_SAMPLE_TYPE paFloat32 @@ -152,20 +158,20 @@ int main(void) err = Pa_StartStream( stream ); if( err != paNoError ) goto error; - printf("Wire on. Will run one minute.\n"); fflush(stdout); + printf("Wire on. Will run %d seconds.\n", NUM_SECONDS); fflush(stdout); - for( i=0; i<(60*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i ) + for( i=0; i<(NUM_SECONDS*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i ) { err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER ); - if( err ) goto xrun; + if( err && CHECK_UNDERFLOW ) goto xrun; err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER ); - if( err ) goto xrun; + if( err && CHECK_OVERFLOW ) goto xrun; } err = Pa_StopStream( stream ); if( err != paNoError ) goto error; CLEAR( sampleBlock ); - +/* err = Pa_StartStream( stream ); if( err != paNoError ) goto error; printf("Wire on. Interrupt to stop.\n"); fflush(stdout); @@ -181,7 +187,7 @@ int main(void) if( err != paNoError ) goto error; Pa_CloseStream( stream ); - +*/ free( sampleBlock ); Pa_Terminate(); diff --git a/test/patest_record.c b/test/patest_record.c index 1da371d..d44f123 100644 --- a/test/patest_record.c +++ b/test/patest_record.c @@ -47,11 +47,13 @@ /* #define SAMPLE_RATE (17932) // Test failure to open with this value. */ #define SAMPLE_RATE (44100) -#define FRAMES_PER_BUFFER (1024) +#define FRAMES_PER_BUFFER (512) #define NUM_SECONDS (5) #define NUM_CHANNELS (2) /* #define DITHER_FLAG (paDitherOff) */ #define DITHER_FLAG (0) /**/ +/** Set to 1 if you want to capture the recording to a file. */ +#define WRITE_TO_FILE (0) /* Select sample format. */ #if 1 @@ -246,7 +248,7 @@ int main(void) err = Pa_StartStream( stream ); if( err != paNoError ) goto done; - printf("Now recording!!\n"); fflush(stdout); + printf("\n=== Now recording!! Please speak into the microphone. ===\n"); fflush(stdout); while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) { @@ -278,7 +280,7 @@ int main(void) printf("sample average = %lf\n", average ); /* Write recorded data to a file. */ -#if 0 +#if WRITE_TO_FILE { FILE *fid; fid = fopen("recorded.raw", "wb"); @@ -308,7 +310,7 @@ int main(void) outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; outputParameters.hostApiSpecificStreamInfo = NULL; - printf("Begin playback.\n"); fflush(stdout); + printf("\n=== Now playing back. ===\n"); fflush(stdout); err = Pa_OpenStream( &stream, NULL, /* no input */ diff --git a/test/patest_sine_channelmaps.c b/test/patest_sine_channelmaps.c index d6550b8..3d0d4c0 100644 --- a/test/patest_sine_channelmaps.c +++ b/test/patest_sine_channelmaps.c @@ -1,5 +1,5 @@ /* - * $Id: patest_sine.c 1097 2006-08-26 08:27:53Z rossb $ + * patest_sine_channelmaps.c * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com/ diff --git a/test/patest_timing.c b/test/patest_timing.c index bc340cb..f224bfe 100644 --- a/test/patest_timing.c +++ b/test/patest_timing.c @@ -1,12 +1,12 @@ /** @file patest_timing.c @ingroup test_src - @brief Play a sine wave for several seconds, and spits out a ton of timing info while it's at it. Based on patet_sine.c + @brief Play a sine wave for several seconds, and spits out a ton of timing info while it's at it. Based on patest_sine.c @author Bjorn Roche @author Ross Bencina @author Phil Burk */ /* - * $Id: patest_sine.c 578 2003-09-02 04:17:38Z rossbencina $ + * $Id: patest_timing.c 578 2003-09-02 04:17:38Z rossbencina $ * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com/ @@ -89,7 +89,7 @@ static int patestCallback( const void *inputBuffer, void *outputBuffer, timeInfo->currentTime, timeInfo->outputBufferDacTime ); - printf( "getStreamTime() returns: %g\n", Pa_GetStreamTime(data->stream)-data->start ); + printf( "getStreamTime() returns: %g\n", Pa_GetStreamTime(data->stream) - data->start ); for( i=0; i @author Phil Burk */ @@ -46,7 +47,7 @@ #include #include "portaudio.h" -#define MAX_SINES (500) +#define MAX_SINES (1000) #define MAX_LOAD (1.2) #define SAMPLE_RATE (44100) #define FRAMES_PER_BUFFER (512) @@ -145,18 +146,32 @@ int main(void) /* Determine number of sines required to get to 50% */ do - { - data.numSines++; - Pa_Sleep( 100 ); + { Pa_Sleep( 100 ); load = Pa_GetStreamCpuLoad( stream ); printf("numSines = %d, CPU load = %f\n", data.numSines, load ); + + if( load < 0.3 ) + { + data.numSines += 10; + } + else if( load < 0.4 ) + { + data.numSines += 2; + } + else + { + data.numSines += 1; + } + } while( load < 0.5 ); /* Calculate target stress value then ramp up to that level*/ numStress = (int) (2.0 * data.numSines * MAX_LOAD ); - for( ; data.numSines < numStress; data.numSines++ ) + if( numStress > MAX_SINES ) + numStress = MAX_SINES; + for( ; data.numSines < numStress; data.numSines+=2 ) { Pa_Sleep( 200 ); load = Pa_GetStreamCpuLoad( stream );