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.
This commit is contained in:
philburk 2011-02-27 00:06:07 +00:00
commit 7ffd3f5374
24 changed files with 478 additions and 2492 deletions

View file

@ -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:

View file

@ -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,60 +113,66 @@ 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;
for( int i=0; i<loopbackContext->test->inputParameters.channelCount; i++ )
/* This may get called with NULL inputBuffer during initial setup.
* We may also use the same callback with output only streams.
*/
if( in != NULL)
{
done |= PaQa_WriteRecording( &loopbackContext->recordings[i], in + i, framesPerBuffer, loopbackContext->test->inputParameters.channelCount );
for( int i=0; i<loopbackContext->test->inputParameters.channelCount; i++ )
{
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; i<loopbackContext->test->outputParameters.channelCount; i++ )
if( out != NULL )
{
PaQa_MixSine( &loopbackContext->generators[i], out + i, framesPerBuffer, loopbackContext->test->outputParameters.channelCount );
PaQa_EraseBuffer( out, framesPerBuffer, loopbackContext->test->outputParameters.channelCount );
for( int i=0; i<loopbackContext->test->outputParameters.channelCount; i++ )
{
PaQa_MixSine( &loopbackContext->generators[i], out + i, framesPerBuffer, loopbackContext->test->outputParameters.channelCount );
}
}
return done ? paComplete : paContinue;
}
/*******************************************************************/
/**
* Open an audio stream.
* 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_RunLoopback( LoopbackContext *loopbackContext )
int PaQa_RunLoopbackFullDuplex( LoopbackContext *loopbackContext )
{
PaStream *stream = NULL;
PaError err = 0;
TestParameters *test = loopbackContext->test;
PaError 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 );
// 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;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
// Wait for stream to finish.
while( Pa_IsStreamActive( stream ) )
{
Pa_Sleep(50);
//printf("loopback count = %d\n", loopbackContext->callbackCount );
//printf("recording position = %d\n", loopbackContext->recordings[0].numFrames );
}
err = Pa_StopStream( stream );
@ -163,6 +180,73 @@ int PaQa_RunLoopback( LoopbackContext *loopbackContext )
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
return 0;
error:
return err;
}
/*******************************************************************/
/**
* 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_RunLoopbackHalfDuplex( 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 */
RecordAndPlaySinesCallback,
loopbackContext );
if( err != paNoError ) goto error;
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 */
RecordAndPlaySinesCallback,
loopbackContext );
if( err != paNoError ) goto error;
err = Pa_StartStream( inStream );
if( err != paNoError ) goto error;
// 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( inStream ) )
{
Pa_Sleep(50);
}
err = Pa_StopStream( inStream );
if( err != paNoError ) goto error;
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; i<loopbackContext->test->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; i<loopbackContext->test->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; i<testParams->samplesPerFrame; 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; i<testParams->samplesPerFrame; 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<numRates; iRate++ )
for( int iFlags=0; iFlags<numFlagSettings; iFlags++ )
{
// SAMPLE RATE
testParams.sampleRate = sampleRates[iRate];
testParams.maxFrames = (int) (1.2 * testParams.sampleRate);
for( int iSize=0; iSize<numBufferSizes; iSize++ )
{
// BUFFER SIZE
testParams.framesPerBuffer = framesPerBuffers[iSize];
printf("| %5d | %6d | ", ((int)(testParams.sampleRate+0.5)), testParams.framesPerBuffer );
fflush(stdout);
int numBadChannels = PaQa_SingleLoopBackTest( userOptions, &testParams, expectedAmplitude );
if( numBadChannels == 0 )
{
printf( "OK" );
testParams.flags = flagSettings[iFlags];
printf( "************ FLAGS = 0x%08X ************************\n", testParams.flags );
// Loop though combinations of audio parameters.
for( int iRate=0; iRate<numRates; iRate++ )
{
// SAMPLE RATE
testParams.sampleRate = sampleRates[iRate];
testParams.maxFrames = (int) (1.2 * testParams.sampleRate);
for( int iSize=0; iSize<numBufferSizes; iSize++ )
{
// BUFFER SIZE
testParams.framesPerBuffer = framesPerBuffers[iSize];
printf("| %5d | %6d | ", ((int)(testParams.sampleRate+0.5)), testParams.framesPerBuffer );
fflush(stdout);
int numBadChannels = PaQa_SingleLoopBackTest( userOptions, &testParams, expectedAmplitude );
if( numBadChannels == 0 )
{
printf( "OK" );
}
//else if( numBadChannels < 0 )
//{
// printf( "Aborting because of error.\n" );
// return numBadChannels;
//}
totalBadChannels += numBadChannels;
printf( "\n" );
}
totalBadChannels += numBadChannels;
printf( "\n" );
}
printf( "\n" );
}
return totalBadChannels;
}
@ -446,6 +770,7 @@ int PaQa_CheckForLoopBack( PaDeviceIndex inputDevice, PaDeviceIndex outputDevice
PaQa_SetupLoopbackContext( &loopbackContext, &testParams );
testParams.flags = PAQA_FLAG_TWO_STREAMS;
err = PaQa_RunLoopback( &loopbackContext );
QA_ASSERT_TRUE("loopback detection callback did not run", (loopbackContext.callbackCount > 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);

View file

@ -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

View file

@ -1,138 +0,0 @@
/*
* $Id$
* Convert tagged values.
*
* Author: Phil Burk <philburk@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 <stdio.h>
#include <math.h>
#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<framesPerBuffer; i++ )
{
*out++ = 0x0000 + i; /* left */
*out++ = 0x1000 + i; /* right */
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PortAudioStream *stream;
PaError err;
paTestData data;
int i;
int totalSamps;
printf("PortAudio Test: output debug values\n" );
data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
printf("totalSamps = %d\n", totalSamps );
err = Pa_Initialize();
if( err != paNoError ) goto error;
printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
err = Pa_OpenStream(
&stream,
paNoDevice,
0, /* no input */
paFloat32, /* 32 bit floating point input */
NULL,
OUTPUT_DEVICE,
2, /* stereo output */
paInt16, /* 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;
printf("Is callback being called?\n");
for( i=0; i<((NUM_SECONDS+1)*1000); i+=SLEEP_DUR )
{
printf("data.framesToGo = %d\n", data.framesToGo ); fflush(stdout);
Pa_Sleep( SLEEP_DUR );
}
/* Stop sound until ENTER hit. */
printf("Call Pa_StopStream()\n");
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View file

@ -1,62 +0,0 @@
/*
* $Id$
* Test Dither calculations.
*
* 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 <stdio.h>
#include <math.h>
#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 );
}

View file

@ -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 <philburk@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 <stdio.h>
#include <math.h>
#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; i<framesPerBuffer; i++ )
{
*out++ = LookupSine(data, data->left_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; i<TABLE_SIZE; i++ )
{
data->sine[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;
}

View file

@ -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 <stdio.h>
#include <math.h>
#include <string.h>
#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; i<numDevices; i++ )
{
pdi = Pa_GetDeviceInfo( i );
if( strncmp( name, pdi->name, 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<data.numChannels; i++ )
{
data.liveChannel = i;
printf("Channel %d being sent to output. Hit ENTER for next channel.", i );
fflush(stdout);
getchar();
}
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = 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;
}

View file

@ -1,151 +0,0 @@
/*
* $Id$
* debug_multi_out.c
* Play a different sine wave on each channels,
* using the Portable Audio api.
*
* 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 <stdio.h>
#include <math.h>
#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; channelIndex<data->numChannels; 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;
}

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <memory.h>
#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; i<framesToCalc; i++ )
{
*wptr++ = 0; /* left */
*wptr++ = 0; /* right */
}
}
else
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = *rptr++; /* left */
*wptr++ = *rptr++; /* right */
}
}
data->frameIndex += 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; i<framesLeft; i++ )
{
*wptr++ = *rptr++; /* left */
*wptr++ = *rptr++; /* right */
}
for( ; i<framesPerBuffer; i++ )
{
*wptr++ = 0; /* left */
*wptr++ = 0; /* right */
}
data->frameIndex += framesLeft;
finished = 1;
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
*wptr++ = *rptr++; /* left */
*wptr++ = *rptr++; /* right */
}
data->frameIndex += 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; i<dataPtr->numSamples; i++ )
{
posVal = dataPtr->recordedSamples[i];
if( posVal < 0 ) posVal = -posVal;
if( posVal > max ) max = posVal;
}
printf("Largest recorded sample = %d\n", max );
}
/* Write recorded data to a file. */
#if 0
{
FILE *fid;
fid = fopen("recorded.raw", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( dataPtr->recordedSamples, dataPtr->samplesPerFrame * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
#endif
error:
return err;
}
/****************************************************************/
PaError 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<data.numSamples; i++ ) data.recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
for( i=0; i<2; i++ )
{
err = TestRecording( &data );
if( err != paNoError ) goto error;
err = TestPlayback( &data );
if( err != paNoError ) goto error;
}
free( data.recordedSamples );
Pa_Terminate();
return 0;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
if( err == paHostError )
{
fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
}
return -1;
}

View file

@ -1,358 +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 <stdio.h>
#include <stdlib.h>
#include <memory.h>
#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; i<framesToCalc; i++ )
{
*wptr++ = 0; /* left */
*wptr++ = 0; /* right */
}
}
else
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = *rptr++; /* left */
*wptr++ = *rptr++; /* right */
}
}
data->frameIndex += 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; i<framesLeft; i++ )
{
*wptr++ = *rptr++; /* left */
*wptr++ = *rptr++; /* right */
}
for( ; i<framesPerBuffer; i++ )
{
*wptr++ = 0; /* left */
*wptr++ = 0; /* right */
}
data->frameIndex += framesLeft;
finished = 1;
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
*wptr++ = *rptr++; /* left */
*wptr++ = *rptr++; /* right */
}
data->frameIndex += 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<data.numSamples; i++ ) data.recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
/* Record and playback multiple times. */
for( i=0; i<2; i++ )
{
err = TestRecording( &data );
if( err != paNoError ) goto error;
err = TestPlayback( &data );
if( err != paNoError ) goto error;
}
/* Clean up. */
err = Pa_CloseStream( data.inputStream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( data.outputStream );
if( err != paNoError ) goto error;
if( err != paNoError ) goto error;
free( data.recordedSamples );
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;
}

View file

@ -1,199 +0,0 @@
/*
* $Id$
* debug_sine.c
* Play a sine sweep using the Portable Audio api for several seconds.
* Hacked test for debugging PA.
*
* Author: Phil Burk <philburk@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 <stdio.h>
#include <math.h>
#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; i<framesToCalc; i++ )
{
*out++ = LookupSine(data, data->left_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<TABLE_SIZE; i++ )
{
data.sine[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);
data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
printf("totalSamps = %d\n", totalSamps );
err = Pa_Initialize();
if( err != paNoError ) goto error;
printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
err = Pa_OpenStream(
&stream,
paNoDevice,
0, /* no input */
paFloat32, /* 32 bit floating point input */
NULL,
OUTPUT_DEVICE,
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;
printf("Is callback being called?\n");
for( i=0; i<((NUM_SECONDS+1)*1000); i+=SLEEP_DUR )
{
printf("data.framesToGo = %d\n", data.framesToGo ); fflush(stdout);
Pa_Sleep( SLEEP_DUR );
}
/* Stop sound until ENTER hit. */
printf("Call Pa_StopStream()\n");
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View file

@ -1,164 +0,0 @@
/*
* $Id$
* Play a different sine wave on each channels,
* using the Portable Audio api.
* Allos amplitude to be set interactively.
*
* 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 <stdio.h>
#include <math.h>
#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; channelIndex<data->numChannels; 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", &amp );
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;
}

View file

@ -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 <stdio.h>
#include <math.h>
#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; i<framesToCalc; i++ )
{
data->left_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;
}

View file

@ -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 <stdio.h>
#include <stdlib.h>
#include <memory.h>
#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;
}

View file

@ -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 <rossb@audiomulch.com>
Modifications:
April 5th, 2001 - PLB - Check for NULL inputBuffer.
*/
#include <stdio.h>
#include <math.h>
#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; i<bufferFrames; i++ )
{
*out++ = *in++;
*out++ = *in++;
if( data->phase >= 100 )
data->phase = 0;
}
data->sampsToGo -= bufferFrames;
/* zero remainder of final buffer if not already done */
for( ; i<bufferFrames; i++ )
{
*out++ = 0; /* left */
*out++ = 0; /* right */
}
return finished;
}
int main(int argc, char* argv[]);
int main(int argc, char* argv[])
{
PaStream *stream;
PaError err;
patest1data data;
int i;
int inputDevice = Pa_GetDefaultInputDeviceID();
int outputDevice = Pa_GetDefaultOutputDeviceID();
/* initialise sinusoidal wavetable */
for( i=0; i<100; i++ )
data.sine[i] = sin( ((double)i/100.) * M_PI * 2. );
data.phase = 0;
data.sampsToGo = 44100 * 4; // 20 seconds
/* initialise portaudio subsytem */
Pa_Initialize();
err = Pa_OpenStream(
&stream,
inputDevice,
2, /* stereo input */
paFloat32, /* 32 bit floating point input */
NULL,
outputDevice,
2, /* stereo output */
paFloat32, /* 32 bit floating point output */
NULL,
44100.,
// 22050, /* half second buffers */
// 4, /* four buffers */
512, /* half second buffers */
0, /* four buffers */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patest1Callback,
&data );
if( err == paNoError )
{
err = Pa_StartStream( stream );
// printf( "Press any key to end.\n" );
// getc( stdin ); //wait for input before exiting
// Pa_AbortStream( stream );
printf( "Waiting for stream to complete...\n" );
while( Pa_StreamActive( stream ) )
Pa_Sleep(1000); /* sleep until playback has finished */
err = Pa_CloseStream( stream );
}
else
{
fprintf( stderr, "An error occured while opening the portaudio stream\n" );
if( err == paHostError )
fprintf( stderr, "Host error number: %d\n", Pa_GetHostError() );
else
fprintf( stderr, "Error number: %d\n", err );
}
Pa_Terminate();
printf( "bye\n" );
return 0;
}

View file

@ -2,7 +2,10 @@
@ingroup test_src
@brief Self Testing Quality Assurance app for PortAudio
Try to open each device and run through all the
possible configurations.
possible configurations. This test does not verify
that the configuration works well. It just verifies
that it does not crash. It requires a human to listen to
the outputs.
@author Phil Burk http://www.softsynth.com

View file

@ -75,6 +75,9 @@ static const char* sampleFormatNames_[SAMPLE_FORMAT_COUNT] =
static const char* abbreviatedSampleFormatNames_[SAMPLE_FORMAT_COUNT] =
{ "f32", "i32", "i24", "i16", " i8", "ui8" };
PaError My_Pa_GetSampleSize( PaSampleFormat format );
/*
available flags are paClipOff and paDitherOff
clipping is usually applied for float -> int conversions

View file

@ -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; i<framesPerBuffer; i++ )
{
if( data->toggle )
{
*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;

View file

@ -47,7 +47,7 @@
#include <math.h>
#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 );

View file

@ -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();

View file

@ -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 */

View file

@ -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/

View file

@ -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 <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $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<framesPerBuffer; i++ )
{

View file

@ -1,6 +1,7 @@
/** @file patest_toomanysines.c
@ingroup test_src
@brief Play more sine waves than we can handle in real time as a stress test.
@todo This may not be needed now that we have "patest_out_overflow.c".
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
@ -46,7 +47,7 @@
#include <math.h>
#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 );