initial commit

This commit is contained in:
2014-01-18 15:06:11 +01:00
parent 3fabb8dcf8
commit 768bec39b3
408 changed files with 171325 additions and 2 deletions

View File

@@ -0,0 +1,60 @@
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
the tests pass, just that they compile.
x- paqa_devs.c
x- paqa_errs.c (needs reviewing)
x- patest1.c
x- patest_buffer.c
x- patest_callbackstop.c
x- patest_clip.c (last test fails, dither doesn't currently force clip in V19)
x- patest_dither.c
x- patest_hang.c
x- patest_latency.c
x- patest_leftright.c
x- patest_longsine.c
x- patest_many.c
x- patest_maxsines.c
o- patest_mono.c
x- patest_multi_sine.c
x- patest_pink.c
x- patest_prime.c
x- patest_read_record.c
x- patest_record.c
x- patest_ringmix.c
x- patest_saw.c
x- patest_sine.c
x- patest_sine8.c
x- patest_sine_formats.c
x- patest_sine_time.c
x- patest_start_stop.c
x- patest_stop.c
x- patest_sync.c
x- patest_toomanysines.c
o- patest_two_rates.c
x- patest_underflow.c
x- patest_wire.c
x- patest_write_sine.c
x- pa_devs.c
x- pa_fuzz.c
x- pa_minlat.c
The debug_ files are still in V18 format and may need some V19 adaption.
Feel free to fix them, most simply require adjusting to the new API.
o- pa_tests/debug_convert.c
o- pa_tests/debug_dither_calc.c
o- pa_tests/debug_dual.c
o- pa_tests/debug_multi_in.c
o- pa_tests/debug_multi_out.c
o- pa_tests/debug_record.c
o- pa_tests/debug_record_reuse.c
o- pa_tests/debug_sine.c
o- pa_tests/debug_sine_amp.c
o- pa_tests/debug_sine_formats.c
o- pa_tests/debug_srate.c
o- pa_tests/debug_test1.c

View File

@@ -0,0 +1,138 @@
/*
* $Id: debug_convert.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,62 @@
/*
* $Id: debug_dither_calc.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,190 @@
/*
* $Id: debug_dual.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,186 @@
/*
* $Id: debug_multi_in.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,151 @@
/*
* $Id: debug_multi_out.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,346 @@
/*
* $Id: debug_record.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,358 @@
/*
* $Id: debug_record_reuse.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,199 @@
/*
* $Id: debug_sine.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,164 @@
/*
* $Id: debug_sine_amp.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,209 @@
/*
* $Id: debug_sine_formats.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,272 @@
/*
* $Id: debug_srate.c 1083 2006-08-23 07:30:49Z rossb $
* 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

@@ -0,0 +1,114 @@
/*
* $Id: debug_test1.c 178 2002-06-04 23:07:01Z $
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

@@ -0,0 +1,238 @@
/** @file pa_devs.c
@ingroup test_src
@brief List available devices, including device information.
@author Phil Burk http://www.softsynth.com
@note Define PA_NO_ASIO to compile this code on Windows without
ASIO support.
*/
/*
* $Id: pa_devs.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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"
#ifdef WIN32
#ifndef PA_NO_ASIO
#include "pa_asio.h"
#endif
#endif
/*******************************************************************/
static void PrintSupportedStandardSampleRates(
const PaStreamParameters *inputParameters,
const PaStreamParameters *outputParameters )
{
static double standardSampleRates[] = {
8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated list */
};
int i, printCount;
PaError err;
printCount = 0;
for( i=0; standardSampleRates[i] > 0; i++ )
{
err = Pa_IsFormatSupported( inputParameters, outputParameters, standardSampleRates[i] );
if( err == paFormatIsSupported )
{
if( printCount == 0 )
{
printf( "\t%8.2f", standardSampleRates[i] );
printCount = 1;
}
else if( printCount == 4 )
{
printf( ",\n\t%8.2f", standardSampleRates[i] );
printCount = 1;
}
else
{
printf( ", %8.2f", standardSampleRates[i] );
++printCount;
}
}
}
if( !printCount )
printf( "None\n" );
else
printf( "\n" );
}
/*******************************************************************/
int main(void);
int main(void)
{
int i, numDevices, defaultDisplayed;
const PaDeviceInfo *deviceInfo;
PaStreamParameters inputParameters, outputParameters;
PaError err;
Pa_Initialize();
printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n",
Pa_GetVersion(), Pa_GetVersionText() );
numDevices = Pa_GetDeviceCount();
if( numDevices < 0 )
{
printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
err = numDevices;
goto error;
}
printf( "Number of devices = %d\n", numDevices );
for( i=0; i<numDevices; i++ )
{
deviceInfo = Pa_GetDeviceInfo( i );
printf( "--------------------------------------- device #%d\n", i );
/* Mark global and API specific default devices */
defaultDisplayed = 0;
if( i == Pa_GetDefaultInputDevice() )
{
printf( "[ Default Input" );
defaultDisplayed = 1;
}
else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice )
{
const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
printf( "[ Default %s Input", hostInfo->name );
defaultDisplayed = 1;
}
if( i == Pa_GetDefaultOutputDevice() )
{
printf( (defaultDisplayed ? "," : "[") );
printf( " Default Output" );
defaultDisplayed = 1;
}
else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice )
{
const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
printf( (defaultDisplayed ? "," : "[") );
printf( " Default %s Output", hostInfo->name );
defaultDisplayed = 1;
}
if( defaultDisplayed )
printf( " ]\n" );
/* print device info fields */
printf( "Name = %s\n", deviceInfo->name );
printf( "Host API = %s\n", Pa_GetHostApiInfo( deviceInfo->hostApi )->name );
printf( "Max inputs = %d", deviceInfo->maxInputChannels );
printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels );
printf( "Default low input latency = %8.3f\n", deviceInfo->defaultLowInputLatency );
printf( "Default low output latency = %8.3f\n", deviceInfo->defaultLowOutputLatency );
printf( "Default high input latency = %8.3f\n", deviceInfo->defaultHighInputLatency );
printf( "Default high output latency = %8.3f\n", deviceInfo->defaultHighOutputLatency );
#ifdef WIN32
#ifndef PA_NO_ASIO
/* ASIO specific latency information */
if( Pa_GetHostApiInfo( deviceInfo->hostApi )->type == paASIO ){
long minLatency, maxLatency, preferredLatency, granularity;
err = PaAsio_GetAvailableLatencyValues( i,
&minLatency, &maxLatency, &preferredLatency, &granularity );
printf( "ASIO minimum buffer size = %ld\n", minLatency );
printf( "ASIO maximum buffer size = %ld\n", maxLatency );
printf( "ASIO preferred buffer size = %ld\n", preferredLatency );
if( granularity == -1 )
printf( "ASIO buffer granularity = power of 2\n" );
else
printf( "ASIO buffer granularity = %ld\n", granularity );
}
#endif /* !PA_NO_ASIO */
#endif /* WIN32 */
printf( "Default sample rate = %8.2f\n", deviceInfo->defaultSampleRate );
/* poll for standard sample rates */
inputParameters.device = i;
inputParameters.channelCount = deviceInfo->maxInputChannels;
inputParameters.sampleFormat = paInt16;
inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = i;
outputParameters.channelCount = deviceInfo->maxOutputChannels;
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
outputParameters.hostApiSpecificStreamInfo = NULL;
if( inputParameters.channelCount > 0 )
{
printf("Supported standard sample rates\n for half-duplex 16 bit %d channel input = \n",
inputParameters.channelCount );
PrintSupportedStandardSampleRates( &inputParameters, NULL );
}
if( outputParameters.channelCount > 0 )
{
printf("Supported standard sample rates\n for half-duplex 16 bit %d channel output = \n",
outputParameters.channelCount );
PrintSupportedStandardSampleRates( NULL, &outputParameters );
}
if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 )
{
printf("Supported standard sample rates\n for full-duplex 16 bit %d channel input, %d channel output = \n",
inputParameters.channelCount, outputParameters.channelCount );
PrintSupportedStandardSampleRates( &inputParameters, &outputParameters );
}
}
Pa_Terminate();
printf("----------------------------------------------\n");
return 0;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,176 @@
/** @file pa_fuzz.c
@ingroup test_src
@brief Distort input like a fuzz box.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: pa_fuzz.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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"
/*
** Note that many of the older ISA sound cards on PCs do NOT support
** full duplex audio (simultaneous record and playback).
** And some only support full duplex at lower sample rates.
*/
#define SAMPLE_RATE (44100)
#define PA_SAMPLE_TYPE paFloat32
#define FRAMES_PER_BUFFER (64)
typedef float SAMPLE;
float CubicAmplifier( float input );
static int fuzzCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );
/* Non-linear amplifier with soft distortion curve. */
float CubicAmplifier( float input )
{
float output, temp;
if( input < 0.0 )
{
temp = input + 1.0f;
output = (temp * temp * temp) - 1.0f;
}
else
{
temp = input - 1.0f;
output = (temp * temp * temp) + 1.0f;
}
return output;
}
#define FUZZ(x) CubicAmplifier(CubicAmplifier(CubicAmplifier(CubicAmplifier(x))))
static int gNumNoInputs = 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 fuzzCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
SAMPLE *out = (SAMPLE*)outputBuffer;
const SAMPLE *in = (const SAMPLE*)inputBuffer;
unsigned int i;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) userData;
if( inputBuffer == NULL )
{
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = 0; /* left - silent */
*out++ = 0; /* right - silent */
}
gNumNoInputs += 1;
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = FUZZ(*in++); /* left - distorted */
*out++ = *in++; /* right - clean */
}
}
return paContinue;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters inputParameters, outputParameters;
PaStream *stream;
PaError err;
err = Pa_Initialize();
if( err != paNoError ) goto error;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
inputParameters.channelCount = 2; /* stereo input */
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
0, /* paClipOff, */ /* we won't output out of range samples so don't bother clipping them */
fuzzCallback,
NULL );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Hit ENTER to stop program.\n");
getchar();
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
printf("Finished. gNumNoInputs = %d\n", gNumNoInputs );
Pa_Terminate();
return 0;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return -1;
}

View File

@@ -0,0 +1,194 @@
/** @file pa_minlat.c
@ingroup test_src
@brief Experiment with different numbers of buffers to determine the
minimum latency for a computer.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: pa_minlat.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 <math.h>
#include <string.h>
#include "portaudio.h"
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (M_PI * 2.0)
#define DEFAULT_BUFFER_SIZE (32)
typedef struct
{
double left_phase;
double right_phase;
}
paTestData;
/* Very simple synthesis routine to generate two sine waves. */
static int paminlatCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned int i;
double left_phaseInc = 0.02;
double right_phaseInc = 0.06;
double left_phase = data->left_phase;
double right_phase = data->right_phase;
for( i=0; i<framesPerBuffer; i++ )
{
left_phase += left_phaseInc;
if( left_phase > TWOPI ) left_phase -= TWOPI;
*out++ = (float) sin( left_phase );
right_phase += right_phaseInc;
if( right_phase > TWOPI ) right_phase -= TWOPI;
*out++ = (float) sin( right_phase );
}
data->left_phase = left_phase;
data->right_phase = right_phase;
return 0;
}
int main( int argc, char **argv );
int main( int argc, char **argv )
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int go;
int outLatency = 0;
int minLatency = DEFAULT_BUFFER_SIZE * 2;
int framesPerBuffer;
double sampleRate = 44100.0;
char str[256];
printf("pa_minlat - Determine minimum latency for your computer.\n");
printf(" usage: pa_minlat {userBufferSize}\n");
printf(" for example: pa_minlat 64\n");
printf("Adjust your stereo until you hear a smooth tone in each speaker.\n");
printf("Then try to find the smallest number of frames that still sounds smooth.\n");
printf("Note that the sound will stop momentarily when you change the number of buffers.\n");
/* Get bufferSize from command line. */
framesPerBuffer = ( argc > 1 ) ? atol( argv[1] ) : DEFAULT_BUFFER_SIZE;
printf("Frames per buffer = %d\n", framesPerBuffer );
data.left_phase = data.right_phase = 0.0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outLatency = sampleRate * 200.0 / 1000.0; /* 200 msec. */
/* Try different numBuffers in a loop. */
go = 1;
while( go )
{
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
outputParameters.channelCount = 2; /* Stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
outputParameters.suggestedLatency = (double)outLatency / sampleRate; /* In seconds. */
outputParameters.hostApiSpecificStreamInfo = NULL;
printf("Latency = %d frames = %6.1f msec.\n", outLatency, outputParameters.suggestedLatency * 1000.0 );
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
sampleRate,
framesPerBuffer,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
paminlatCallback,
&data );
if( err != paNoError ) goto error;
if( stream == NULL ) goto error;
/* Start audio. */
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
/* Ask user for a new nlatency. */
printf("\nMove windows around to see if the sound glitches.\n");
printf("Latency now %d, enter new number of frames, or 'q' to quit: ", outLatency );
fgets( str, 256, stdin );
{
/* Get rid of newline */
size_t l = strlen( str ) - 1;
if( str[ l ] == '\n')
str[ l ] = '\0';
}
if( str[0] == 'q' ) go = 0;
else
{
outLatency = atol( str );
if( outLatency < minLatency )
{
printf( "Latency below minimum of %d! Set to minimum!!!\n", minLatency );
outLatency = minLatency;
}
}
/* Stop sound until ENTER hit. */
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
}
printf("A good setting for latency would be somewhat higher than\n");
printf("the minimum latency that worked.\n");
printf("PortAudio: Test finished.\n");
Pa_Terminate();
return 0;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return 1;
}

View File

@@ -0,0 +1,355 @@
/** @file paqa_devs.c
@ingroup test_src
@brief Self Testing Quality Assurance app for PortAudio
Try to open each device and run through all the
possible configurations.
@author Phil Burk http://www.softsynth.com
Pieter adapted to V19 API. Test now relies heavily on
Pa_IsFormatSupported(). Uses same 'standard' sample rates
as in test pa_devs.c.
*/
/*
* $Id: paqa_devs.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_trace.h"
/****************************************** Definitions ***********/
#define MODE_INPUT (0)
#define MODE_OUTPUT (1)
typedef struct PaQaData
{
unsigned long framesLeft;
int numChannels;
int bytesPerSample;
int mode;
short sawPhase;
PaSampleFormat format;
}
PaQaData;
/****************************************** Prototypes ***********/
static void TestDevices( int mode );
static void TestFormats( int mode, PaDeviceIndex deviceID, double sampleRate,
int numChannels );
static int TestAdvance( int mode, PaDeviceIndex deviceID, double sampleRate,
int numChannels, PaSampleFormat format );
static int QaCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );
/****************************************** Globals ***********/
static int gNumPassed = 0;
static int gNumFailed = 0;
/****************************************** Macros ***********/
/* Print ERROR if it fails. Tally success or failure. */
/* Odd do-while wrapper seems to be needed for some compilers. */
#define EXPECT(_exp) \
do \
{ \
if ((_exp)) {\
/* printf("SUCCESS for %s\n", #_exp ); */ \
gNumPassed++; \
} \
else { \
printf("ERROR - 0x%x - %s for %s\n", result, \
((result == 0) ? "-" : Pa_GetErrorText(result)), \
#_exp ); \
gNumFailed++; \
goto error; \
} \
} while(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 QaCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
unsigned long i;
short phase;
PaQaData *data = (PaQaData *) userData;
(void) inputBuffer;
/* Play simle sawtooth wave. */
if( data->mode == MODE_OUTPUT )
{
phase = data->sawPhase;
switch( data->format )
{
case paFloat32:
{
float *out = (float *) outputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
phase += 0x123;
*out++ = (float) (phase * (1.0 / 32768.0));
if( data->numChannels == 2 )
{
*out++ = (float) (phase * (1.0 / 32768.0));
}
}
}
break;
case paInt32:
{
int *out = (int *) outputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
phase += 0x123;
*out++ = ((int) phase ) << 16;
if( data->numChannels == 2 )
{
*out++ = ((int) phase ) << 16;
}
}
}
break;
case paInt16:
{
short *out = (short *) outputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
phase += 0x123;
*out++ = phase;
if( data->numChannels == 2 )
{
*out++ = phase;
}
}
}
break;
default:
{
unsigned char *out = (unsigned char *) outputBuffer;
unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample;
for( i=0; i<numBytes; i++ )
{
*out++ = 0;
}
}
break;
}
data->sawPhase = phase;
}
/* Are we through yet? */
if( data->framesLeft > framesPerBuffer )
{
PaUtil_AddTraceMessage("QaCallback: running. framesLeft", data->framesLeft );
data->framesLeft -= framesPerBuffer;
return 0;
}
else
{
PaUtil_AddTraceMessage("QaCallback: DONE! framesLeft", data->framesLeft );
data->framesLeft = 0;
return 1;
}
}
/*******************************************************************/
int main(void);
int main(void)
{
PaError result;
EXPECT( ((result=Pa_Initialize()) == 0) );
printf("Test OUTPUT ---------------\n");
TestDevices( MODE_OUTPUT );
printf("Test INPUT ---------------\n");
TestDevices( MODE_INPUT );
error:
Pa_Terminate();
printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed );
return 0;
}
/*******************************************************************
* Try each output device, through its full range of capabilities. */
static void TestDevices( int mode )
{
int id, jc, i;
int maxChannels;
const PaDeviceInfo *pdi;
static double standardSampleRates[] = { 8000.0, 9600.0, 11025.0, 12000.0,
16000.0, 22050.0, 24000.0,
32000.0, 44100.0, 48000.0,
88200.0, 96000.0,
-1.0 }; /* Negative terminated list. */
int numDevices = Pa_GetDeviceCount();
for( id=0; id<numDevices; id++ ) /* Iterate through all devices. */
{
pdi = Pa_GetDeviceInfo( id );
/* Try 1 to maxChannels on each device. */
maxChannels = (( mode == MODE_INPUT ) ? pdi->maxInputChannels : pdi->maxOutputChannels);
for( jc=1; jc<=maxChannels; jc++ )
{
printf("Name = %s\n", pdi->name );
/* Try each standard sample rate. */
for( i=0; standardSampleRates[i] > 0; i++ )
{
TestFormats( mode, (PaDeviceIndex)id, standardSampleRates[i], jc );
}
}
}
}
/*******************************************************************/
static void TestFormats( int mode, PaDeviceIndex deviceID, double sampleRate,
int numChannels )
{
TestAdvance( mode, deviceID, sampleRate, numChannels, paFloat32 );
TestAdvance( mode, deviceID, sampleRate, numChannels, paInt16 );
TestAdvance( mode, deviceID, sampleRate, numChannels, paInt32 );
/* TestAdvance( mode, deviceID, sampleRate, numChannels, paInt24 ); */
}
/*******************************************************************/
static int TestAdvance( int mode, PaDeviceIndex deviceID, double sampleRate,
int numChannels, PaSampleFormat format )
{
PaStreamParameters inputParameters, outputParameters, *ipp, *opp;
PaStream *stream = NULL;
PaError result = paNoError;
PaQaData myData;
#define FRAMES_PER_BUFFER (64)
/* Setup data for synthesis thread. */
myData.framesLeft = (unsigned long) (sampleRate * 100); /* 100 seconds */
myData.numChannels = numChannels;
myData.mode = mode;
myData.format = format;
switch( format )
{
case paFloat32:
case paInt32:
case paInt24:
myData.bytesPerSample = 4;
break;
/* case paPackedInt24:
myData.bytesPerSample = 3;
break; */
default:
myData.bytesPerSample = 2;
break;
}
if( mode == MODE_INPUT )
{
inputParameters.device = deviceID;
inputParameters.channelCount = numChannels;
inputParameters.sampleFormat = format;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
ipp = &inputParameters;
}
else
ipp = NULL;
if( mode == MODE_OUTPUT ) /* Pa_GetDeviceInfo(paNoDevice) COREDUMPS!!! */
{
outputParameters.device = deviceID;
outputParameters.channelCount = numChannels;
outputParameters.sampleFormat = format;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
opp = &outputParameters;
}
else
opp = NULL;
if(paFormatIsSupported == Pa_IsFormatSupported( ipp, opp, sampleRate ))
{
printf("------ TestAdvance: %s, device = %d, rate = %g, numChannels = %d, format = %lu -------\n",
( mode == MODE_INPUT ) ? "INPUT" : "OUTPUT",
deviceID, sampleRate, numChannels, (unsigned long)format);
EXPECT( ((result = Pa_OpenStream( &stream,
ipp,
opp,
sampleRate,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
QaCallback,
&myData ) ) == 0) );
if( stream )
{
PaTime oldStamp, newStamp;
unsigned long oldFrames;
int minDelay = ( mode == MODE_INPUT ) ? 1000 : 400;
/* Was:
int minNumBuffers = Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate );
int msec = (int) ((minNumBuffers * 3 * 1000.0 * FRAMES_PER_BUFFER) / sampleRate);
*/
int msec = (int)( 3.0 *
(( mode == MODE_INPUT ) ? inputParameters.suggestedLatency : outputParameters.suggestedLatency ));
if( msec < minDelay ) msec = minDelay;
printf("msec = %d\n", msec); /**/
EXPECT( ((result=Pa_StartStream( stream )) == 0) );
/* Check to make sure PortAudio is advancing timeStamp. */
oldStamp = Pa_GetStreamTime(stream);
Pa_Sleep(msec);
newStamp = Pa_GetStreamTime(stream);
printf("oldStamp = %g,newStamp = %g\n", oldStamp, newStamp ); /**/
EXPECT( (oldStamp < newStamp) );
/* Check to make sure callback is decrementing framesLeft. */
oldFrames = myData.framesLeft;
Pa_Sleep(msec);
printf("oldFrames = %lu, myData.framesLeft = %lu\n", oldFrames, myData.framesLeft ); /**/
EXPECT( (oldFrames > myData.framesLeft) );
EXPECT( ((result=Pa_CloseStream( stream )) == 0) );
stream = NULL;
}
}
error:
if( stream != NULL ) Pa_CloseStream( stream );
return result;
}

View File

@@ -0,0 +1,387 @@
/** @file paqa_errs.c
@ingroup test_src
@brief Self Testing Quality Assurance app for PortAudio
Do lots of bad things to test error reporting.
@author Phil Burk http://www.softsynth.com
Pieter Suurmond adapted to V19 API.
*/
/*
* $Id: paqa_errs.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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"
/*--------- Definitions ---------*/
#define MODE_INPUT (0)
#define MODE_OUTPUT (1)
#define FRAMES_PER_BUFFER (64)
#define SAMPLE_RATE (44100.0)
typedef struct PaQaData
{
unsigned long framesLeft;
int numChannels;
int bytesPerSample;
int mode;
}
PaQaData;
static int gNumPassed = 0; /* Two globals */
static int gNumFailed = 0;
/*------------------- Macros ------------------------------*/
/* Print ERROR if it fails. Tally success or failure. Odd */
/* do-while wrapper seems to be needed for some compilers. */
#define EXPECT(_exp) \
do \
{ \
if ((_exp)) {\
gNumPassed++; \
} \
else { \
printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \
gNumFailed++; \
goto error; \
} \
} while(0)
#define HOPEFOR(_exp) \
do \
{ \
if ((_exp)) {\
gNumPassed++; \
} \
else { \
printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \
gNumFailed++; \
} \
} while(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 QaCallback( const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData )
{
unsigned long i;
unsigned char* out = (unsigned char *) outputBuffer;
PaQaData* data = (PaQaData *) userData;
(void)inputBuffer; /* Prevent "unused variable" warnings. */
/* Zero out buffer so we don't hear terrible noise. */
if( data->mode == MODE_OUTPUT )
{
unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample;
for( i=0; i<numBytes; i++ )
{
*out++ = 0;
}
}
/* Are we through yet? */
if( data->framesLeft > framesPerBuffer )
{
data->framesLeft -= framesPerBuffer;
return 0;
}
else
{
data->framesLeft = 0;
return 1;
}
}
static PaDeviceIndex FindInputOnlyDevice(void)
{
PaDeviceIndex result = Pa_GetDefaultInputDevice();
if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxOutputChannels == 0 )
return result;
for( result = 0; result < Pa_GetDeviceCount(); ++result )
{
if( Pa_GetDeviceInfo(result)->maxOutputChannels == 0 )
return result;
}
return paNoDevice;
}
static PaDeviceIndex FindOutputOnlyDevice(void)
{
PaDeviceIndex result = Pa_GetDefaultOutputDevice();
if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxInputChannels == 0 )
return result;
for( result = 0; result < Pa_GetDeviceCount(); ++result )
{
if( Pa_GetDeviceInfo(result)->maxInputChannels == 0 )
return result;
}
return paNoDevice;
}
/*-------------------------------------------------------------------------------------------------*/
static int TestBadOpens( void )
{
PaStream* stream = NULL;
PaError result;
PaQaData myData;
PaStreamParameters ipp, opp;
/* Setup data for synthesis thread. */
myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */
myData.numChannels = 1;
myData.mode = MODE_OUTPUT;
/*----------------------------- No devices specified: */
ipp.device = opp.device = paNoDevice;
ipp.channelCount = opp.channelCount = 0; /* Also no channels. */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
/* Take the low latency of the default device for all subsequent tests. */
ipp.suggestedLatency = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice())->defaultLowInputLatency;
opp.suggestedLatency = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice())->defaultLowOutputLatency;
HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidDevice));
/*----------------------------- No devices specified #2: */
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, NULL,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidDevice));
/*----------------------------- Out of range input device specified: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = Pa_GetDeviceCount(); /* And no output device, and no channels. */
opp.channelCount = 0; opp.device = paNoDevice;
HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidDevice));
/*----------------------------- Out of range output device specified: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice; /* And no input device, and no channels. */
opp.channelCount = 0; opp.device = Pa_GetDeviceCount();
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidDevice));
/*----------------------------- Zero input channels: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = Pa_GetDefaultInputDevice();
opp.channelCount = 0; opp.device = paNoDevice; /* And no output device, and no output channels. */
HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
/*----------------------------- Zero output channels: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice; /* And no input device, and no input channels. */
opp.channelCount = 0; opp.device = Pa_GetDefaultOutputDevice();
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
/*----------------------------- Nonzero input and output channels but no output device: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 2; ipp.device = Pa_GetDefaultInputDevice(); /* Both stereo. */
opp.channelCount = 2; opp.device = paNoDevice;
HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidDevice));
/*----------------------------- Nonzero input and output channels but no input device: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 2; ipp.device = paNoDevice;
opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice();
HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidDevice));
/*----------------------------- NULL stream pointer: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice; /* Output is more likely than input. */
opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice(); /* Only 2 output channels. */
HOPEFOR(((result = Pa_OpenStream(NULL, &ipp, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paBadStreamPtr));
/*----------------------------- Low sample rate: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice;
opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice();
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
1.0, FRAMES_PER_BUFFER, /* 1 cycle per second (1 Hz) is too low. */
paClipOff, QaCallback, &myData )) == paInvalidSampleRate));
/*----------------------------- High sample rate: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice;
opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice();
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
10000000.0, FRAMES_PER_BUFFER, /* 10^6 cycles per second (10 MHz) is too high. */
paClipOff, QaCallback, &myData )) == paInvalidSampleRate));
/*----------------------------- NULL callback: */
/* NULL callback is valid in V19 -- it means use blocking read/write stream
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice;
opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice();
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff,
NULL,
&myData )) == paNullCallback));
*/
/*----------------------------- Bad flag: */
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice;
opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice();
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
255, /* Is 8 maybe legal V19 API? */
QaCallback, &myData )) == paInvalidFlag));
/*----------------------------- using input device as output device: */
if( FindInputOnlyDevice() != paNoDevice )
{
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 0; ipp.device = paNoDevice; /* And no input device, and no channels. */
opp.channelCount = 2; opp.device = FindInputOnlyDevice();
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
}
/*----------------------------- using output device as input device: */
if( FindOutputOnlyDevice() != paNoDevice )
{
ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
ipp.sampleFormat = opp.sampleFormat = paFloat32;
ipp.channelCount = 2; ipp.device = FindOutputOnlyDevice();
opp.channelCount = 0; opp.device = paNoDevice; /* And no output device, and no channels. */
HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
}
if( stream != NULL ) Pa_CloseStream( stream );
return result;
}
/*-----------------------------------------------------------------------------------------*/
static int TestBadActions( void )
{
PaStream* stream = NULL;
PaError result;
PaQaData myData;
PaStreamParameters opp;
/* Setup data for synthesis thread. */
myData.framesLeft = (unsigned long)(SAMPLE_RATE * 100); /* 100 seconds */
myData.numChannels = 1;
myData.mode = MODE_OUTPUT;
opp.device = Pa_GetDefaultOutputDevice(); /* Default output. */
opp.channelCount = 2; /* Stereo output. */
opp.hostApiSpecificStreamInfo = NULL;
opp.sampleFormat = paFloat32;
opp.suggestedLatency = Pa_GetDeviceInfo(opp.device)->defaultLowOutputLatency;
HOPEFOR(((result = Pa_OpenStream(&stream, NULL, /* Take NULL as input parame- */
&opp, /* ters, meaning try only output. */
SAMPLE_RATE, FRAMES_PER_BUFFER,
paClipOff, QaCallback, &myData )) == paNoError));
HOPEFOR(((result = Pa_StartStream(NULL)) == paBadStreamPtr));
HOPEFOR(((result = Pa_StopStream(NULL)) == paBadStreamPtr));
HOPEFOR(((result = Pa_IsStreamStopped(NULL)) == paBadStreamPtr));
HOPEFOR(((result = Pa_IsStreamActive(NULL)) == paBadStreamPtr));
HOPEFOR(((result = Pa_CloseStream(NULL)) == paBadStreamPtr));
HOPEFOR(((result = Pa_SetStreamFinishedCallback(NULL, NULL)) == paBadStreamPtr));
HOPEFOR(((result = !Pa_GetStreamInfo(NULL))));
HOPEFOR(((result = Pa_GetStreamTime(NULL)) == 0.0));
HOPEFOR(((result = Pa_GetStreamCpuLoad(NULL)) == 0.0));
HOPEFOR(((result = Pa_ReadStream(NULL, NULL, 0)) == paBadStreamPtr));
HOPEFOR(((result = Pa_WriteStream(NULL, NULL, 0)) == paBadStreamPtr));
/** @todo test Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable */
if (stream != NULL) Pa_CloseStream(stream);
return result;
}
/*---------------------------------------------------------------------*/
int main(void);
int main(void)
{
PaError result;
EXPECT(((result = Pa_Initialize()) == paNoError));
TestBadOpens();
TestBadActions();
error:
Pa_Terminate();
printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed);
return 0;
}

View File

@@ -0,0 +1,200 @@
/** @file patest1.c
@ingroup test_src
@brief Ring modulate the audio input with a sine wave for 20 seconds.
@author Ross Bencina <rossb@audiomulch.com>
*/
/*
* $Id: patest1.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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"
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define SAMPLE_RATE (44100)
typedef struct
{
float sine[100];
int phase;
int sampsToGo;
}
patest1data;
static int patest1Callback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
patest1data *data = (patest1data*)userData;
float *in = (float*)inputBuffer;
float *out = (float*)outputBuffer;
int framesToCalc = framesPerBuffer;
unsigned long i = 0;
int finished;
if( data->sampsToGo < framesPerBuffer )
{
framesToCalc = data->sampsToGo;
finished = paComplete;
}
else
{
finished = paContinue;
}
for( ; i<framesToCalc; i++ )
{
*out++ = *in++ * data->sine[data->phase]; /* left */
*out++ = *in++ * data->sine[data->phase++]; /* right */
if( data->phase >= 100 )
data->phase = 0;
}
data->sampsToGo -= framesToCalc;
/* zero remainder of final buffer if not already done */
for( ; i<framesPerBuffer; 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;
PaStreamParameters inputParameters, outputParameters;
const PaHostErrorInfo* herr;
printf("patest1.c\n"); fflush(stdout);
printf("Ring modulate input for 20 seconds.\n"); fflush(stdout);
/* initialise sinusoidal wavetable */
for( i=0; i<100; i++ )
data.sine[i] = sin( ((double)i/100.) * M_PI * 2. );
data.phase = 0;
data.sampsToGo = SAMPLE_RATE * 20; /* 20 seconds. */
/* initialise portaudio subsytem */
err = Pa_Initialize();
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
inputParameters.channelCount = 2; /* stereo input */
inputParameters.sampleFormat = paFloat32; /* 32 bit floating point input */
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters,
(double)SAMPLE_RATE, /* Samplerate in Hertz. */
512, /* Small buffers */
paClipOff, /* We won't output out of range samples so don't bother clipping them. */
patest1Callback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf( "Press any key to end.\n" ); fflush(stdout);
getc( stdin ); /* wait for input before exiting */
err = Pa_AbortStream( stream );
if( err != paNoError ) goto done;
printf( "Waiting for stream to complete...\n" );
/* sleep until playback has finished */
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(1000);
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
done:
Pa_Terminate();
if( err != paNoError )
{
fprintf( stderr, "An error occured while using portaudio\n" );
if( err == paUnanticipatedHostError )
{
fprintf( stderr, " unanticipated host error.\n");
herr = Pa_GetLastHostErrorInfo();
if (herr)
{
fprintf( stderr, " Error number: %ld\n", herr->errorCode );
if (herr->errorText)
fprintf( stderr, " Error text: %s\n", herr->errorText );
}
else
fprintf( stderr, " Pa_GetLastHostErrorInfo() failed!\n" );
}
else
{
fprintf( stderr, " Error number: %d\n", err );
fprintf( stderr, " Error text: %s\n", Pa_GetErrorText( err ) );
}
err = 1; /* Always return 0 or 1, but no other return codes. */
}
printf( "bye\n" );
return err;
}

View File

@@ -0,0 +1,200 @@
/** @file patest_buffer.c
@ingroup test_src
@brief Test opening streams with different buffer sizes.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_buffer.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 <math.h>
#include "portaudio.h"
#define NUM_SECONDS (3)
#define SAMPLE_RATE (44100)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
#define BUFFER_TABLE 14
long buffer_table[] = {paFramesPerBufferUnspecified,16,32,64,128,200,256,500,512,600,723,1000,1024,2345};
typedef struct
{
short sine[TABLE_SIZE];
int left_phase;
int right_phase;
unsigned int sampsToGo;
}
paTestData;
PaError TestOnce( int buffersize, PaDeviceIndex );
/* 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 patest1Callback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
short *out = (short*)outputBuffer;
unsigned int i;
int finished = 0;
(void) inputBuffer; /* Prevent "unused variable" warnings. */
if( data->sampsToGo < framesPerBuffer )
{
/* final buffer... */
for( i=0; i<data->sampsToGo; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
/* zero remainder of final buffer */
for( ; i<framesPerBuffer; i++ )
{
*out++ = 0; /* left */
*out++ = 0; /* right */
}
finished = 1;
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
data->sampsToGo -= framesPerBuffer;
}
return finished;
}
/*******************************************************************/
int main(int argc, char **args);
int main(int argc, char **args)
{
int i;
int device = -1;
PaError err;
printf("Test opening streams with different buffer sizes\n");
if( argc > 1 ) {
device=atoi( args[1] );
printf("Using device number %d.\n\n", device );
} else {
printf("Using default device.\n\n" );
}
for (i = 0 ; i < BUFFER_TABLE; i++)
{
printf("Buffer size %ld\n", buffer_table[i]);
err = TestOnce(buffer_table[i], device);
if( err < 0 ) return 0;
}
return 0;
}
PaError TestOnce( int buffersize, PaDeviceIndex device )
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
int totalSamps;
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
}
data.left_phase = data.right_phase = 0;
data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
err = Pa_Initialize();
if( err != paNoError ) goto error;
if( device == -1 )
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
else
outputParameters.device = device ;
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paInt16; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
buffersize, /* frames per buffer */
(paClipOff | paDitherOff),
patest1Callback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Waiting for sound to finish.\n");
Pa_Sleep(1000*NUM_SECONDS);
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
return paNoError;
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 ) );
fprintf( stderr, "Host Error message: %s\n", Pa_GetLastHostErrorInfo()->errorText );
return err;
}

View File

@@ -0,0 +1,248 @@
/** @file patest_callbackstop.c
@ingroup test_src
@brief Test the paComplete callback result code.
@author Ross Bencina <rossb@audiomulch.com>
*/
/*
* $Id: patest_callbackstop.c 1294 2007-10-24 20:51:22Z bjornroche $
*
* 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 (5)
#define NUM_LOOPS (4)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (67)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int phase;
unsigned long generatedFramesCount;
volatile int callbackReturnedPaComplete;
volatile int callbackInvokedAfterReturningPaComplete;
char message[100];
}
TestData;
/*
This routine will be called by the PortAudio stream 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 TestCallback( const void *input, void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
TestData *data = (TestData*)userData;
float *out = (float*)output;
unsigned long i;
float x;
(void) input; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
if( data->callbackReturnedPaComplete )
data->callbackInvokedAfterReturningPaComplete = 1;
for( i=0; i<frameCount; i++ )
{
/* generate tone */
x = data->sine[ data->phase++ ];
if( data->phase >= TABLE_SIZE )
data->phase -= TABLE_SIZE;
*out++ = x; /* left */
*out++ = x; /* right */
}
data->generatedFramesCount += frameCount;
if( data->generatedFramesCount >= (NUM_SECONDS * SAMPLE_RATE) )
{
data->callbackReturnedPaComplete = 1;
return paComplete;
}
else
{
return paContinue;
}
}
/*
* This routine is called by portaudio when playback is done.
*/
static void StreamFinished( void* userData )
{
TestData *data = (TestData *) userData;
printf( "Stream Completed: %s\n", data->message );
}
/*----------------------------------------------------------------------------*/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
TestData data;
int i, j;
printf( "PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
SAMPLE_RATE, FRAMES_PER_BUFFER );
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice();
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* output will be in-range, so no need to clip */
TestCallback,
&data );
if( err != paNoError ) goto error;
sprintf( data.message, "Loop: XX" );
err = Pa_SetStreamFinishedCallback( stream, &StreamFinished );
if( err != paNoError ) goto error;
printf("Repeating test %d times.\n", NUM_LOOPS );
for( i=0; i < NUM_LOOPS; ++i )
{
data.phase = 0;
data.generatedFramesCount = 0;
data.callbackReturnedPaComplete = 0;
data.callbackInvokedAfterReturningPaComplete = 0;
sprintf( data.message, "Loop: %d", i );
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
/* wait for the callback to complete generating NUM_SECONDS of tone */
do
{
Pa_Sleep( 500 );
}
while( !data.callbackReturnedPaComplete );
printf( "Callback returned paComplete.\n" );
printf( "Waiting for buffers to finish playing...\n" );
/* wait for stream to become inactive,
or for a timeout of approximately NUM_SECONDS
*/
j = 0;
while( (err = Pa_IsStreamActive( stream )) == 1 && j < NUM_SECONDS * 2 )
{
printf(".\n" );
Pa_Sleep( 500 );
++j;
}
if( err < 0 )
{
goto error;
}
else if( err == 1 )
{
printf( "TEST FAILED: Timed out waiting for buffers to finish playing.\n" );
}
else
{
printf("Buffers finished.\n" );
}
if( data.callbackInvokedAfterReturningPaComplete )
{
printf( "TEST FAILED: Callback was invoked after returning paComplete.\n" );
}
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
printf( "sleeping for 1 second...\n" );
Pa_Sleep( 1000 );
}
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,186 @@
/** @file patest_clip.c
@ingroup test_src
@brief Play a sine wave for several seconds at an amplitude
that would require clipping.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_clip.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 (4)
#define SAMPLE_RATE (44100)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct paTestData
{
float sine[TABLE_SIZE];
float amplitude;
int left_phase;
int right_phase;
}
paTestData;
PaError PlaySine( paTestData *data, unsigned long flags, float amplitude );
/* 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 sineCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
float amplitude = data->amplitude;
unsigned int i;
(void) inputBuffer; /* Prevent "unused variable" warnings. */
(void) timeInfo;
(void) statusFlags;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = amplitude * data->sine[data->left_phase]; /* left */
*out++ = amplitude * data->sine[data->right_phase]; /* 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;
}
return 0;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output sine wave with and without clipping.\n");
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
printf("\nHalf amplitude. Should sound like sine wave.\n"); fflush(stdout);
err = PlaySine( &data, paClipOff | paDitherOff, 0.5f );
if( err < 0 ) goto error;
printf("\nFull amplitude. Should sound like sine wave.\n"); fflush(stdout);
err = PlaySine( &data, paClipOff | paDitherOff, 0.999f );
if( err < 0 ) goto error;
printf("\nOver range with clipping and dithering turned OFF. Should sound very nasty.\n");
fflush(stdout);
err = PlaySine( &data, paClipOff | paDitherOff, 1.1f );
if( err < 0 ) goto error;
printf("\nOver range with clipping and dithering turned ON. Should sound smoother than previous.\n");
fflush(stdout);
err = PlaySine( &data, paNoFlag, 1.1f );
if( err < 0 ) goto error;
printf("\nOver range with paClipOff but dithering ON.\n"
"That forces clipping ON so it should sound the same as previous.\n");
fflush(stdout);
err = PlaySine( &data, paClipOff, 1.1f );
if( err < 0 ) goto error;
return 0;
error:
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return 1;
}
/*****************************************************************************/
PaError PlaySine( paTestData *data, unsigned long flags, float amplitude )
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
data->left_phase = data->right_phase = 0;
data->amplitude = amplitude;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
1024,
flags,
sineCallback,
data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
Pa_Sleep( NUM_SECONDS * 1000 );
printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad( stream ) );
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
return paNoError;
error:
return err;
}

View File

@@ -0,0 +1,186 @@
/** @file patest_dither.c
@ingroup test_src
@brief Attempt to hear difference between dithered and non-dithered signal.
This only has an effect if the native format is 16 bit.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_dither.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 (5)
#define SAMPLE_RATE (44100)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct paTestData
{
float sine[TABLE_SIZE];
float amplitude;
int left_phase;
int right_phase;
}
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 sineCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
float amplitude = data->amplitude;
unsigned int i;
(void) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = amplitude * data->sine[data->left_phase]; /* left */
*out++ = amplitude * data->sine[data->right_phase]; /* 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;
}
return 0;
}
/*****************************************************************************/
/*
V18 version did not call Pa_Terminate() if Pa_Initialize() failed.
This V19 version ALWAYS calls Pa_Terminate(). PS.
*/
PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude );
PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude )
{
PaStream* stream;
PaStreamParameters outputParameters;
PaError err;
data->left_phase = data->right_phase = 0;
data->amplitude = amplitude;
err = Pa_Initialize();
if (err != paNoError)
goto done;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
/* When you change this, also */
/* adapt the callback routine! */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )
->defaultLowOutputLatency; /* Low latency. */
err = Pa_OpenStream( &stream,
NULL, /* No input. */
&outputParameters,
SAMPLE_RATE,
1024, /* frames per buffer */
flags,
sineCallback,
(void*)data );
if (err != paNoError)
goto done;
err = Pa_StartStream( stream );
if (err != paNoError)
goto done;
Pa_Sleep( NUM_SECONDS * 1000 );
printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad(stream));
err = Pa_CloseStream( stream );
done:
Pa_Sleep( 250 ); /* Just a small silence. */
Pa_Terminate();
return err;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaError err;
paTestData DATA;
int i;
float amplitude = 4.0 / (1<<15);
printf("PortAudio Test: output EXTREMELY QUIET sine wave with and without dithering.\n");
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
DATA.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
printf("\nNo treatment..\n"); fflush(stdout);
err = PlaySine( &DATA, paClipOff | paDitherOff, amplitude );
if( err < 0 ) goto done;
printf("\nClip..\n");
fflush(stdout);
err = PlaySine( &DATA, paDitherOff, amplitude );
if( err < 0 ) goto done;
printf("\nClip and Dither..\n");
fflush(stdout);
err = PlaySine( &DATA, paNoFlag, amplitude );
done:
if (err)
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1; /* Though PlaySine() already called Pa_Terminate(), */
} /* we may still call Pa_GetErrorText(). */
else
printf("\n(Don't forget to turn the VOLUME DOWN after listening so carefully.)\n");
return err; /* 0 or 1. */
}

View File

@@ -0,0 +1,205 @@
/*
* $Id: $
* Portable Audio I/O Library
* Windows DirectSound surround sound output test
*
* Copyright (c) 2007 Ross Bencina
*
* 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 <windows.h> /* required when using pa_win_wmme.h */
#include <mmsystem.h> /* required when using pa_win_wmme.h */
#include "portaudio.h"
#include "pa_win_ds.h"
#define NUM_SECONDS (12)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (100)
#define CHANNEL_COUNT (6)
typedef struct
{
float sine[TABLE_SIZE];
int phase;
int currentChannel;
int cycleCount;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i,j;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
for( j = 0; j < CHANNEL_COUNT; ++j ){
if( j == data->currentChannel && data->cycleCount < 4410 ){
*out++ = data->sine[data->phase];
data->phase += 1 + j; // play each channel at a different pitch so they can be distinguished
if( data->phase >= TABLE_SIZE ){
data->phase -= TABLE_SIZE;
}
}else{
*out++ = 0;
}
}
data->cycleCount++;
if( data->cycleCount > 44100 ){
data->cycleCount = 0;
++data->currentChannel;
if( data->currentChannel >= CHANNEL_COUNT )
data->currentChannel -= CHANNEL_COUNT;
}
}
return paContinue;
}
/*******************************************************************/
int main(int argc, char* argv[])
{
PaStreamParameters outputParameters;
PaWinDirectSoundStreamInfo directSoundStreamInfo;
PaStream *stream;
PaError err;
paTestData data;
int i;
int deviceIndex;
printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);
err = Pa_Initialize();
if( err != paNoError ) goto error;
deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paDirectSound ) )->defaultOutputDevice;
if( argc == 2 ){
sscanf( argv[1], "%d", &deviceIndex );
}
printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.phase = 0;
data.currentChannel = 0;
data.cycleCount = 0;
outputParameters.device = deviceIndex;
outputParameters.channelCount = CHANNEL_COUNT;
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* it's not strictly necessary to provide a channelMask for surround sound
output. But if you want to be sure which channel mask PortAudio will use
then you should supply one */
directSoundStreamInfo.size = sizeof(PaWinDirectSoundStreamInfo);
directSoundStreamInfo.hostApiType = paDirectSound;
directSoundStreamInfo.version = 1;
directSoundStreamInfo.flags = paWinDirectSoundUseChannelMask;
directSoundStreamInfo.channelMask = PAWIN_SPEAKER_5POINT1; /* request 5.1 output format */
outputParameters.hostApiSpecificStreamInfo = &directSoundStreamInfo;
if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){
printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
}else{
printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
}
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,160 @@
/** @file patest_hang.c
@ingroup test_src
@brief Play a sine then hang audio callback to test watchdog.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_hang.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (M_PI * 2.0)
typedef struct paTestData
{
int sleepFor;
double phase;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
int finished = 0;
double phaseInc = 0.02;
double phase = data->phase;
(void) inputBuffer; /* Prevent unused argument warning. */
for( i=0; i<framesPerBuffer; i++ )
{
phase += phaseInc;
if( phase > TWOPI ) phase -= TWOPI;
/* This is not a very efficient way to calc sines. */
*out++ = (float) sin( phase ); /* mono */
}
if( data->sleepFor > 0 )
{
Pa_Sleep( data->sleepFor );
}
data->phase = phase;
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStream* stream;
PaStreamParameters outputParameters;
PaError err;
int i;
paTestData data = {0};
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
SAMPLE_RATE, FRAMES_PER_BUFFER );
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
outputParameters.channelCount = 1; /* Mono output. */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point. */
outputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)
->defaultLowOutputLatency;
err = Pa_OpenStream(&stream,
NULL, /* No input. */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* No out of range samples. */
patestCallback,
&data);
if (err != paNoError) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
/* Gradually increase sleep time. */
/* Was: for( i=0; i<10000; i+= 1000 ) */
for(i=0; i <= 1000; i += 100)
{
printf("Sleep for %d milliseconds in audio callback.\n", i );
data.sleepFor = i;
Pa_Sleep( ((i<1000) ? 1000 : i) );
}
printf("Suffer for 10 seconds.\n");
Pa_Sleep( 10000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,232 @@
/** @file patest_in_overflow.c
@ingroup test_src
@brief Count input overflows (using paInputOverflow flag) under
overloaded and normal conditions.
This test uses the same method to overload the stream as does
patest_out_underflow.c -- it generates sine waves until the cpu load
exceeds a certain level. However this test is only concerned with
input and so doesn't ouput any sound.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_in_overflow.c 1097 2006-08-26 08:27:53Z rossb $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2004 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 MAX_SINES (500)
#define MAX_LOAD (1.2)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (512)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (M_PI * 2.0)
typedef struct paTestData
{
int sineCount;
double phases[MAX_SINES];
int countOverflows;
int inputOverflowCount;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float out; /* variable to hold dummy output */
unsigned long i;
int j;
int finished = paContinue;
(void) timeInfo; /* Prevent unused variable warning. */
(void) inputBuffer; /* Prevent unused variable warning. */
(void) outputBuffer; /* Prevent unused variable warning. */
if( data->countOverflows && (statusFlags & paInputOverflow) )
data->inputOverflowCount++;
for( i=0; i<framesPerBuffer; i++ )
{
float output = 0.0;
double phaseInc = 0.02;
double phase;
for( j=0; j<data->sineCount; j++ )
{
/* Advance phase of next oscillator. */
phase = data->phases[j];
phase += phaseInc;
if( phase > TWOPI ) phase -= TWOPI;
phaseInc *= 1.02;
if( phaseInc > 0.5 ) phaseInc *= 0.5;
/* This is not a very efficient way to calc sines. */
output += (float) sin( phase );
data->phases[j] = phase;
}
/* this is an input-only stream so we don't actually use the output */
out = (float) (output / data->sineCount);
(void) out; /* suppress unused variable warning*/
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters inputParameters;
PaStream *stream;
PaError err;
int safeSineCount, stressedSineCount;
int safeOverflowCount, stressedOverflowCount;
paTestData data = {0};
double load;
printf("PortAudio Test: input only, no sound output. Load callback by performing calculations, count input overflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );
err = Pa_Initialize();
if( err != paNoError ) goto error;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
inputParameters.channelCount = 1; /* mono output */
inputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* no output */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Establishing load conditions...\n" );
/* Determine number of sines required to get to 50% */
do
{
data.sineCount++;
Pa_Sleep( 100 );
load = Pa_GetStreamCpuLoad( stream );
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
}
while( load < 0.5 && data.sineCount < (MAX_SINES-1));
safeSineCount = data.sineCount;
/* Calculate target stress value then ramp up to that level*/
stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
if( stressedSineCount > MAX_SINES )
stressedSineCount = MAX_SINES;
for( ; data.sineCount < stressedSineCount; data.sineCount++ )
{
Pa_Sleep( 100 );
load = Pa_GetStreamCpuLoad( stream );
printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load );
}
printf("Counting overflows for 5 seconds.\n");
data.countOverflows = 1;
Pa_Sleep( 5000 );
stressedOverflowCount = data.inputOverflowCount;
data.countOverflows = 0;
data.sineCount = safeSineCount;
printf("Resuming safe load...\n");
Pa_Sleep( 1500 );
data.inputOverflowCount = 0;
Pa_Sleep( 1500 );
load = Pa_GetStreamCpuLoad( stream );
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
printf("Counting overflows for 5 seconds.\n");
data.countOverflows = 1;
Pa_Sleep( 5000 );
safeOverflowCount = data.inputOverflowCount;
printf("Stop stream.\n");
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
if( stressedOverflowCount == 0 )
printf("Test failed, no input overflows detected under stress.\n");
else if( safeOverflowCount != 0 )
printf("Test failed, %d unexpected overflows detected under safe load.\n", safeOverflowCount);
else
printf("Test passed, %d expected input overflows detected under stress, 0 unexpected overflows detected under safe load.\n", stressedOverflowCount );
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

@@ -0,0 +1,189 @@
/** @file
@ingroup test_src
@brief Hear the latency caused by big buffers.
Play a sine wave and change frequency based on letter input.
@author Phil Burk <philburk@softsynth.com>, and Darren Gibbs
*/
/*
* $Id: patest_latency.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_GetDefaultOutputDevice())
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#define MIN_FREQ (100.0f)
#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;
float LookupSine( paTestData *data, float phase );
/* Convert phase between and 1.0 to sine value
* using linear interpolation.
*/
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
int i;
(void) inputBuffer; /* Prevent unused variable warning. */
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;
}
return 0;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStream *stream;
PaStreamParameters outputParameters;
PaError err;
paTestData data;
int i;
int done = 0;
printf("PortAudio Test: enter letter then hit ENTER.\n" );
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = 0.90f * (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);
err = Pa_Initialize();
if( err != paNoError ) goto error;
printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
outputParameters.device = OUTPUT_DEVICE;
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
printf("Requested output latency = %.4f seconds.\n", outputParameters.suggestedLatency );
printf("%d frames per buffer.\n.", FRAMES_PER_BUFFER );
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
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("Play ASCII keyboard. Hit 'q' to stop. (Use RETURN key on Mac)\n");
fflush(stdout);
while ( !done )
{
float freq;
int index;
char c;
do
{
c = getchar();
}
while( c < ' '); /* Strip white space and control chars. */
if( c == 'q' ) done = 1;
index = c % 26;
freq = MIN_FREQ + (index * 40.0);
data.phase_increment = CalcPhaseIncrement(freq);
}
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

@@ -0,0 +1,181 @@
/** @file patest_leftright.c
@ingroup test_src
@brief Play different tone sine waves that
alternate between left and right channel.
The low tone should be on the left channel.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_leftright.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 (8)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (512)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
int toggle;
int countDown;
}
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( const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
int finished = 0;
/* Prevent unused variable warnings. */
(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 */
}
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;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStream *stream;
PaStreamParameters outputParameters;
PaError err;
paTestData data;
int i;
int timeout;
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");
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
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;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream( &stream,
NULL, /* No input. */
&outputParameters, /* As above. */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
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;
}
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,147 @@
/** @file patest_longsine.c
@ingroup test_src
@brief Play a sine wave until ENTER hit.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_longsine.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 SAMPLE_RATE (44100)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
}
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(const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData)
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned int i;
(void) inputBuffer; /* Prevent unused argument warning. */
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
return 0;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output sine wave.\n");
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.left_phase = data.right_phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream( &stream,
NULL, /* No input. */
&outputParameters, /* As above. */
SAMPLE_RATE,
256, /* Frames per buffer. */
paClipOff, /* No out of range samples expected. */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Hit ENTER to stop program.\n");
getchar();
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,206 @@
/** @file patest_many.c
@ingroup test_src
@brief Start and stop the PortAudio Driver multiple times.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_many.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 <math.h>
#include "portaudio.h"
#define NUM_SECONDS (1)
#define SAMPLE_RATE (44100)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
short sine[TABLE_SIZE];
int left_phase;
int right_phase;
unsigned int sampsToGo;
}
paTestData;
PaError TestOnce( void );
static int patest1Callback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );
/* 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 patest1Callback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
short *out = (short*)outputBuffer;
unsigned int i;
int finished = 0;
(void) inputBuffer; /* Prevent "unused variable" warnings. */
if( data->sampsToGo < framesPerBuffer )
{
/* final buffer... */
for( i=0; i<data->sampsToGo; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
/* zero remainder of final buffer */
for( ; i<framesPerBuffer; i++ )
{
*out++ = 0; /* left */
*out++ = 0; /* right */
}
finished = 1;
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
data->sampsToGo -= framesPerBuffer;
}
return finished;
}
/*******************************************************************/
#ifdef MACINTOSH
int main(void);
int main(void)
{
int i;
PaError err;
int numLoops = 10;
printf("Loop %d times.\n", numLoops );
for( i=0; i<numLoops; i++ )
{
printf("Loop %d out of %d.\n", i+1, numLoops );
err = TestOnce();
if( err < 0 ) return 0;
}
}
#else
int main(int argc, char **argv);
int main(int argc, char **argv)
{
PaError err;
int i, numLoops = 10;
if( argc > 1 )
{
numLoops = atoi(argv[1]);
}
for( i=0; i<numLoops; i++ )
{
printf("Loop %d out of %d.\n", i+1, numLoops );
err = TestOnce();
if( err < 0 ) return 1;
}
printf("Test complete.\n");
return 0;
}
#endif
PaError TestOnce( void )
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
int totalSamps;
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
}
data.left_phase = data.right_phase = 0;
data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paInt16;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
1024, /* frames per buffer */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patest1Callback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Waiting for sound to finish.\n");
Pa_Sleep(1000);
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
return paNoError;
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

@@ -0,0 +1,212 @@
/** @file patest_maxsines.c
@ingroup test_src
@brief How many sine waves can we calculate and play in less than 80% CPU Load.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_maxsines.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 MAX_SINES (500)
#define MAX_USAGE (0.8)
#define SAMPLE_RATE (44100)
#define FREQ_TO_PHASE_INC(freq) (freq/(float)SAMPLE_RATE)
#define MIN_PHASE_INC FREQ_TO_PHASE_INC(200.0f)
#define MAX_PHASE_INC (MIN_PHASE_INC * (1 << 5))
#define FRAMES_PER_BUFFER (512)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (M_PI * 2.0)
#define TABLE_SIZE (512)
typedef struct paTestData
{
int numSines;
float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
float phases[MAX_SINES];
}
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(const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
float outSample;
float scaler;
int numForScale;
unsigned long i;
int j;
int finished = 0;
(void) inputBuffer; /* Prevent unused argument warning. */
/* Determine amplitude scaling factor */
numForScale = data->numSines;
if( numForScale < 8 ) numForScale = 8; /* prevent pops at beginning */
scaler = 1.0f / numForScale;
for( i=0; i<framesPerBuffer; i++ )
{
float output = 0.0;
float phaseInc = MIN_PHASE_INC;
float phase;
for( j=0; j<data->numSines; j++ )
{
/* Advance phase of next oscillator. */
phase = data->phases[j];
phase += phaseInc;
if( phase >= 1.0 ) phase -= 1.0;
output += LookupSine(data, phase);
data->phases[j] = phase;
phaseInc *= 1.02f;
if( phaseInc > MAX_PHASE_INC ) phaseInc = MIN_PHASE_INC;
}
outSample = (float) (output * scaler);
*out++ = outSample; /* Left */
*out++ = outSample; /* Right */
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
int i;
PaStream* stream;
PaStreamParameters outputParameters;
PaError err;
paTestData data = {0};
double load;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */
err = Pa_Initialize();
if( err != paNoError )
goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
outputParameters.channelCount = 2; /* Stereo output. */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
outputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)
->defaultHighOutputLatency;
err = Pa_OpenStream(&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* No out of range samples should occur. */
patestCallback,
&data);
if( err != paNoError )
goto error;
err = Pa_StartStream( stream );
if( err != paNoError )
goto error;
/* Play an increasing number of sine waves until we hit MAX_USAGE */
do {
data.numSines++;
Pa_Sleep(200);
load = Pa_GetStreamCpuLoad(stream);
printf("numSines = %d, CPU load = %f\n", data.numSines, load );
fflush(stdout);
} while((load < MAX_USAGE) && (data.numSines < MAX_SINES));
Pa_Sleep(2000); /* Stay for 2 seconds around 80% CPU. */
err = Pa_StopStream( stream );
if( err != paNoError )
goto error;
err = Pa_CloseStream( stream );
if( err != paNoError )
goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,155 @@
/** @file patest_mono.c
@ingroup test_src
@brief Play a monophonic sine wave using the Portable Audio api for several seconds.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_mono.c 1097 2006-08-26 08:27:53Z rossb $
*
* Authors:
* Ross Bencina <rossb@audiomulch.com>
* 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 NUM_SECONDS (10)
#define SAMPLE_RATE (44100)
#define AMPLITUDE (0.8)
#define FRAMES_PER_BUFFER (64)
#define OUTPUT_DEVICE Pa_GetDefaultOutputDevice()
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int phase;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
int finished = 0;
/* avoid unused variable warnings */
(void) inputBuffer;
(void) timeInfo;
(void) statusFlags;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->phase]; /* left */
data->phase += 1;
if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE;
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output MONO sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) (AMPLITUDE * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
}
data.phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = OUTPUT_DEVICE;
outputParameters.channelCount = 1; /* MONO output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* 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("Play for %d seconds.\n", NUM_SECONDS ); fflush(stdout);
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,166 @@
/** @file pa_test_mono_asio_channel_select.c
@ingroup test_src
@brief Play a monophonic sine wave on a specific ASIO channel.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_mono_asio_channel_select.c 1097 2006-08-26 08:27:53Z rossb $
*
* Authors:
* Ross Bencina <rossb@audiomulch.com>
* 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"
#include "pa_asio.h"
#define NUM_SECONDS (10)
#define SAMPLE_RATE (44100)
#define AMPLITUDE (0.8)
#define FRAMES_PER_BUFFER (64)
#define OUTPUT_DEVICE Pa_GetDefaultOutputDevice()
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int phase;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
int finished = 0;
/* avoid unused variable warnings */
(void) inputBuffer;
(void) timeInfo;
(void) statusFlags;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->phase]; /* left */
data->phase += 1;
if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE;
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaAsioStreamInfo asioOutputInfo;
PaStream *stream;
PaError err;
paTestData data;
int outputChannelSelectors[1];
int i;
printf("PortAudio Test: output MONO sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) (AMPLITUDE * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
}
data.phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = OUTPUT_DEVICE;
outputParameters.channelCount = 1; /* MONO output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
asioOutputInfo.size = sizeof(PaAsioStreamInfo);
asioOutputInfo.hostApiType = paASIO;
asioOutputInfo.version = 1;
asioOutputInfo.flags = paAsioUseChannelSelectors;
outputChannelSelectors[0] = 1; /* select the second (right) ASIO device channel */
asioOutputInfo.channelSelectors = outputChannelSelectors;
outputParameters.hostApiSpecificStreamInfo = &asioOutputInfo;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS ); fflush(stdout);
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,201 @@
/** @file patest_multi_sine.c
@ingroup test_src
@brief Play a different sine wave on each channel.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_multi_sine.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 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
{
short interleaved; /* Nonzero for interleaved / zero for non-interleaved. */
int numChannels; /* Actually used. */
double phases[MAX_CHANNELS]; /* Each channel gets its' own frequency. */
}
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(const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData)
{
int frameIndex, channelIndex;
float** outputs = (float**)outputBuffer;
paTestData* data = (paTestData*)userData;
(void) inputBuffer; /* Prevent unused arg warning. */
if (data->interleaved)
{
float *out = (float*)outputBuffer; /* interleaved version */
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);
}
}
}
else
{
for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
{
for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
{
/* Output sine wave on every channel. */
outputs[channelIndex][frameIndex] = (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 test(short interleaved)
{
PaStream* stream;
PaStreamParameters outputParameters;
PaError err;
const PaDeviceInfo* pdi;
paTestData data;
short n;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device, max channels. */
pdi = Pa_GetDeviceInfo(outputParameters.device);
outputParameters.channelCount = pdi->maxOutputChannels;
if (outputParameters.channelCount > MAX_CHANNELS)
outputParameters.channelCount = MAX_CHANNELS;
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = pdi->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
data.interleaved = interleaved;
data.numChannels = outputParameters.channelCount;
for (n = 0; n < data.numChannels; n++)
data.phases[n] = 0.0; /* Phases wrap and maybe don't need initialisation. */
printf("%d ", data.numChannels);
if (interleaved)
printf("interleaved ");
else
{
printf(" non-interleaved ");
outputParameters.sampleFormat |= paNonInterleaved;
}
printf("channels.\n");
err = Pa_OpenStream(&stream,
NULL, /* No input. */
&outputParameters,
SAMPLE_RATE, /* Sample rate. */
FRAMES_PER_BUFFER, /* Frames per buffer. */
paClipOff, /* Samples never out of range, no clipping. */
patestCallback,
&data);
if (err == paNoError)
{
err = Pa_StartStream(stream);
if (err == paNoError)
{
printf("Hit ENTER to stop this test.\n");
getchar();
err = Pa_StopStream(stream);
}
Pa_CloseStream( stream );
}
return err;
}
/*******************************************************************/
int main(void)
{
PaError err;
printf("PortAudio Test: output sine wave on each channel.\n" );
err = Pa_Initialize();
if (err != paNoError)
goto done;
err = test(1); /* 1 means interleaved. */
if (err != paNoError)
goto done;
err = test(0); /* 0 means not interleaved. */
if (err != paNoError)
goto done;
printf("Test finished.\n");
done:
if (err)
{
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));
}
Pa_Terminate();
return 0;
}

View File

@@ -0,0 +1,225 @@
/** @file patest_out_underflow.c
@ingroup test_src
@brief Count output underflows (using paOutputUnderflow flag)
under overloaded and normal conditions.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_out_underflow.c 1097 2006-08-26 08:27:53Z rossb $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com
* Copyright (c) 1999-2004 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 MAX_SINES (500)
#define MAX_LOAD (1.2)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (512)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (M_PI * 2.0)
typedef struct paTestData
{
int sineCount;
double phases[MAX_SINES];
int countUnderflows;
int outputUnderflowCount;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
int j;
int finished = paContinue;
(void) timeInfo; /* Prevent unused variable warning. */
(void) inputBuffer; /* Prevent unused variable warning. */
if( data->countUnderflows && (statusFlags & paOutputUnderflow) )
data->outputUnderflowCount++;
for( i=0; i<framesPerBuffer; i++ )
{
float output = 0.0;
double phaseInc = 0.02;
double phase;
for( j=0; j<data->sineCount; j++ )
{
/* Advance phase of next oscillator. */
phase = data->phases[j];
phase += phaseInc;
if( phase > TWOPI ) phase -= TWOPI;
phaseInc *= 1.02;
if( phaseInc > 0.5 ) phaseInc *= 0.5;
/* This is not a very efficient way to calc sines. */
output += (float) sin( phase );
data->phases[j] = phase;
}
*out++ = (float) (output / data->sineCount);
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
int safeSineCount, stressedSineCount;
int safeUnderflowCount, stressedUnderflowCount;
paTestData data = {0};
double load;
printf("PortAudio Test: output sine waves, count underflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 1; /* mono output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* 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("Establishing load conditions...\n" );
/* Determine number of sines required to get to 50% */
do
{
data.sineCount++;
Pa_Sleep( 100 );
load = Pa_GetStreamCpuLoad( stream );
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
}
while( load < 0.5 && data.sineCount < (MAX_SINES-1));
safeSineCount = data.sineCount;
/* Calculate target stress value then ramp up to that level*/
stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
if( stressedSineCount > MAX_SINES )
stressedSineCount = MAX_SINES;
for( ; data.sineCount < stressedSineCount; data.sineCount++ )
{
Pa_Sleep( 100 );
load = Pa_GetStreamCpuLoad( stream );
printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load );
}
printf("Counting underflows for 5 seconds.\n");
data.countUnderflows = 1;
Pa_Sleep( 5000 );
stressedUnderflowCount = data.outputUnderflowCount;
data.countUnderflows = 0;
data.sineCount = safeSineCount;
printf("Resuming safe load...\n");
Pa_Sleep( 1500 );
data.outputUnderflowCount = 0;
Pa_Sleep( 1500 );
load = Pa_GetStreamCpuLoad( stream );
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
printf("Counting underflows for 5 seconds.\n");
data.countUnderflows = 1;
Pa_Sleep( 5000 );
safeUnderflowCount = data.outputUnderflowCount;
printf("Stop stream.\n");
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
if( stressedUnderflowCount == 0 )
printf("Test failed, no output underflows detected under stress.\n");
else if( safeUnderflowCount != 0 )
printf("Test failed, %d unexpected underflows detected under safe load.\n", safeUnderflowCount);
else
printf("Test passed, %d expected output underflows detected under stress, 0 unexpected underflows detected under safe load.\n", stressedUnderflowCount );
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

@@ -0,0 +1,276 @@
/** @file patest_pink.c
@ingroup test_src
@brief Generate Pink Noise using Gardner method.
Optimization suggested by James McCartney uses a tree
to select which random value to replace.
<pre>
x x x x x x x x x x x x x x x x
x x x x x x x x
x x x x
x x
x
</pre>
Tree is generated by counting trailing zeros in an increasing index.
When the index is zero, no random number is selected.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_pink.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 PINK_MAX_RANDOM_ROWS (30)
#define PINK_RANDOM_BITS (24)
#define PINK_RANDOM_SHIFT ((sizeof(long)*8)-PINK_RANDOM_BITS)
typedef struct
{
long pink_Rows[PINK_MAX_RANDOM_ROWS];
long pink_RunningSum; /* Used to optimize summing of generators. */
int pink_Index; /* Incremented each sample. */
int pink_IndexMask; /* Index wrapped by ANDing with this mask. */
float pink_Scalar; /* Used to scale within range of -1.0 to +1.0 */
}
PinkNoise;
/* Prototypes */
static unsigned long GenerateRandomNumber( void );
void InitializePinkNoise( PinkNoise *pink, int numRows );
float GeneratePinkNoise( PinkNoise *pink );
/************************************************************/
/* Calculate pseudo-random 32 bit number based on linear congruential method. */
static unsigned long GenerateRandomNumber( void )
{
/* Change this seed for different random sequences. */
static unsigned long randSeed = 22222;
randSeed = (randSeed * 196314165) + 907633515;
return randSeed;
}
/************************************************************/
/* Setup PinkNoise structure for N rows of generators. */
void InitializePinkNoise( PinkNoise *pink, int numRows )
{
int i;
long pmax;
pink->pink_Index = 0;
pink->pink_IndexMask = (1<<numRows) - 1;
/* Calculate maximum possible signed random value. Extra 1 for white noise always added. */
pmax = (numRows + 1) * (1<<(PINK_RANDOM_BITS-1));
pink->pink_Scalar = 1.0f / pmax;
/* Initialize rows. */
for( i=0; i<numRows; i++ ) pink->pink_Rows[i] = 0;
pink->pink_RunningSum = 0;
}
#define PINK_MEASURE
#ifdef PINK_MEASURE
float pinkMax = -999.0;
float pinkMin = 999.0;
#endif
/* Generate Pink noise values between -1.0 and +1.0 */
float GeneratePinkNoise( PinkNoise *pink )
{
long newRandom;
long sum;
float output;
/* Increment and mask index. */
pink->pink_Index = (pink->pink_Index + 1) & pink->pink_IndexMask;
/* If index is zero, don't update any random values. */
if( pink->pink_Index != 0 )
{
/* Determine how many trailing zeros in PinkIndex. */
/* This algorithm will hang if n==0 so test first. */
int numZeros = 0;
int n = pink->pink_Index;
while( (n & 1) == 0 )
{
n = n >> 1;
numZeros++;
}
/* Replace the indexed ROWS random value.
* Subtract and add back to RunningSum instead of adding all the random
* values together. Only one changes each time.
*/
pink->pink_RunningSum -= pink->pink_Rows[numZeros];
newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
pink->pink_RunningSum += newRandom;
pink->pink_Rows[numZeros] = newRandom;
}
/* Add extra white noise value. */
newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
sum = pink->pink_RunningSum + newRandom;
/* Scale to range of -1.0 to 0.9999. */
output = pink->pink_Scalar * sum;
#ifdef PINK_MEASURE
/* Check Min/Max */
if( output > pinkMax ) pinkMax = output;
else if( output < pinkMin ) pinkMin = output;
#endif
return output;
}
/*******************************************************************/
#define PINK_TEST
#ifdef PINK_TEST
/* Context for callback routine. */
typedef struct
{
PinkNoise leftPink;
PinkNoise rightPink;
unsigned int sampsToGo;
}
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(const void* inputBuffer,
void* outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void* userData)
{
int finished;
int i;
int numFrames;
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
(void) inputBuffer; /* Prevent "unused variable" warnings. */
/* Are we almost at end. */
if( data->sampsToGo < framesPerBuffer )
{
numFrames = data->sampsToGo;
finished = 1;
}
else
{
numFrames = framesPerBuffer;
finished = 0;
}
for( i=0; i<numFrames; i++ )
{
*out++ = GeneratePinkNoise( &data->leftPink );
*out++ = GeneratePinkNoise( &data->rightPink );
}
data->sampsToGo -= numFrames;
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStream* stream;
PaError err;
paTestData data;
PaStreamParameters outputParameters;
int totalSamps;
static const double SR = 44100.0;
static const int FPB = 2048; /* Frames per buffer: 46 ms buffers. */
/* Initialize two pink noise signals with different numbers of rows. */
InitializePinkNoise( &data.leftPink, 12 );
InitializePinkNoise( &data.rightPink, 16 );
/* Look at a few values. */
{
int i;
float pink;
for( i=0; i<20; i++ )
{
pink = GeneratePinkNoise( &data.leftPink );
printf("Pink = %f\n", pink );
}
}
data.sampsToGo = totalSamps = (int)(60.0 * SR); /* Play a whole minute. */
err = Pa_Initialize();
if( err != paNoError ) goto error;
/* Open a stereo PortAudio stream so we can hear the result. */
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Take the default output device. */
outputParameters.channelCount = 2; /* Stereo output, most likely supported. */
outputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
outputParameters.suggestedLatency =
Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
err = Pa_OpenStream(&stream,
NULL, /* No input. */
&outputParameters,
SR, /* Sample rate. */
FPB, /* Frames per buffer. */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data);
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Stereo pink noise for one minute...\n");
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
if( err < 0 ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
#ifdef PINK_MEASURE
printf("Pink min = %f, max = %f\n", pinkMin, pinkMax );
#endif
Pa_Terminate();
return 0;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return 0;
}
#endif /* PINK_TEST */

View File

@@ -0,0 +1,230 @@
/** @file patest_prime.c
@ingroup test_src
@brief Test stream priming mode.
@author Ross Bencina http://www.audiomulch.com/~rossb
*/
/*
* $Id: patest_prime.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_util.h"
#define NUM_BEEPS (3)
#define SAMPLE_RATE (44100)
#define SAMPLE_PERIOD (1.0/44100.0)
#define FRAMES_PER_BUFFER (256)
#define BEEP_DURATION (400)
#define IDLE_DURATION (SAMPLE_RATE*2) /* 2 seconds */
#define SLEEP_MSEC (50)
#define STATE_BKG_IDLE (0)
#define STATE_BKG_BEEPING (1)
typedef struct
{
float leftPhase;
float rightPhase;
int state;
int beepCountdown;
int idleCountdown;
}
paTestData;
static void InitializeTestData( paTestData *testData )
{
testData->leftPhase = 0;
testData->rightPhase = 0;
testData->state = STATE_BKG_BEEPING;
testData->beepCountdown = BEEP_DURATION;
testData->idleCountdown = IDLE_DURATION;
}
/* 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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData )
{
/* Cast data passed through stream to our structure. */
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned int i;
int result = paContinue;
/* supress unused parameter warnings */
(void) inputBuffer;
(void) timeInfo;
(void) statusFlags;
for( i=0; i<framesPerBuffer; i++ )
{
switch( data->state )
{
case STATE_BKG_IDLE:
*out++ = 0.0; /* left */
*out++ = 0.0; /* right */
--data->idleCountdown;
if( data->idleCountdown <= 0 ) result = paComplete;
break;
case STATE_BKG_BEEPING:
if( data->beepCountdown <= 0 )
{
data->state = STATE_BKG_IDLE;
*out++ = 0.0; /* left */
*out++ = 0.0; /* right */
}
else
{
/* Play sawtooth wave. */
*out++ = data->leftPhase; /* left */
*out++ = data->rightPhase; /* right */
/* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
data->leftPhase += 0.01f;
/* When signal reaches top, drop back down. */
if( data->leftPhase >= 1.0f ) data->leftPhase -= 2.0f;
/* higher pitch so we can distinguish left and right. */
data->rightPhase += 0.03f;
if( data->rightPhase >= 1.0f ) data->rightPhase -= 2.0f;
}
--data->beepCountdown;
break;
}
}
return result;
}
/*******************************************************************/
static PaError DoTest( int flags )
{
PaStream *stream;
PaError err;
paTestData data;
PaStreamParameters outputParameters;
InitializeTestData( &data );
outputParameters.device = Pa_GetDefaultOutputDevice();
outputParameters.channelCount = 2;
outputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.sampleFormat = paFloat32;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
/* Open an audio I/O stream. */
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER, /* frames per buffer */
paClipOff | flags, /* 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("hear \"BEEP\"\n" );
fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(SLEEP_MSEC);
if( err < 0 ) goto error;
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
return err;
error:
return err;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaError err = paNoError;
int i;
/* Initialize library before making any other calls. */
err = Pa_Initialize();
if( err != paNoError ) goto error;
printf("PortAudio Test: Testing stream playback with no priming.\n");
printf("PortAudio Test: you should see BEEP before you hear it.\n");
printf("BEEP %d times.\n", NUM_BEEPS );
for( i=0; i< NUM_BEEPS; ++i )
{
err = DoTest( 0 );
if( err != paNoError )
goto error;
}
printf("PortAudio Test: Testing stream playback with priming.\n");
printf("PortAudio Test: you should see BEEP around the same time you hear it.\n");
for( i=0; i< NUM_BEEPS; ++i )
{
err = DoTest( paPrimeOutputBuffersUsingStreamCallback );
if( err != paNoError )
goto error;
}
printf("Test finished.\n");
Pa_Terminate();
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

@@ -0,0 +1,236 @@
/** @file patest_read_record.c
@ingroup test_src
@brief Record input into an array; Save array to a file; Playback recorded
data. Implemented using the blocking API (Pa_ReadStream(), Pa_WriteStream() )
@author Phil Burk http://www.softsynth.com
@author Ross Bencina rossb@audiomulch.com
*/
/*
* $Id: patest_read_record.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 "portaudio.h"
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#define NUM_SECONDS (5)
#define NUM_CHANNELS (2)
/* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/
/* Select sample format. */
#if 1
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#define PRINTF_S_FORMAT "%.8f"
#elif 1
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#elif 0
#define PA_SAMPLE_TYPE paInt8
typedef char SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#else
#define PA_SAMPLE_TYPE paUInt8
typedef unsigned char SAMPLE;
#define SAMPLE_SILENCE (128)
#define PRINTF_S_FORMAT "%d"
#endif
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters inputParameters, outputParameters;
PaStream *stream;
PaError err;
SAMPLE *recordedSamples;
int i;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, average, val;
printf("patest_read_record.c\n"); fflush(stdout);
totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
recordedSamples = (SAMPLE *) malloc( numBytes );
if( recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
exit(1);
}
for( i=0; i<numSamples; i++ ) recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
inputParameters.channelCount = NUM_CHANNELS;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Now recording!!\n"); fflush(stdout);
err = Pa_ReadStream( stream, recordedSamples, totalFrames );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
/* Measure maximum peak amplitude. */
max = 0;
average = 0;
for( i=0; i<numSamples; i++ )
{
val = recordedSamples[i];
if( val < 0 ) val = -val; /* ABS */
if( val > max )
{
max = val;
}
average += val;
}
average = average / numSamples;
printf("Sample max amplitude = "PRINTF_S_FORMAT"\n", max );
printf("Sample average = "PRINTF_S_FORMAT"\n", average );
/* Was as below. Better choose at compile time because this
keeps generating compiler-warnings:
if( PA_SAMPLE_TYPE == paFloat32 )
{
printf("sample max amplitude = %f\n", max );
printf("sample average = %f\n", average );
}
else
{
printf("sample max amplitude = %d\n", max );
printf("sample average = %d\n", average );
}
*/
/* Write recorded data to a file. */
#if 0
{
FILE *fid;
fid = fopen("recorded.raw", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
#endif
/* Playback recorded data. -------------------------------------------- */
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = NUM_CHANNELS;
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
printf("Begin playback.\n"); fflush(stdout);
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) goto error;
if( stream )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Waiting for playback to finish.\n"); fflush(stdout);
err = Pa_WriteStream( stream, recordedSamples, totalFrames );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
printf("Done.\n"); fflush(stdout);
}
free( recordedSamples );
Pa_Terminate();
return 0;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return -1;
}

View File

@@ -0,0 +1,215 @@
/** @file patest_read_write_wire.c
@ingroup test_src
@brief Tests full duplex blocking I/O by passing input straight to output.
@author Bjorn Roche. XO Audio LLC for Z-Systems Engineering.
@author based on code by: Phil Burk http://www.softsynth.com
@author based on code by: Ross Bencina rossb@audiomulch.com
*/
/*
* $Id: patest_read_record.c 757 2004-02-13 07:48:10Z rossbencina $
*
* 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 <strings.h>
#include "portaudio.h"
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#define NUM_CHANNELS (2)
/* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/
/* Select sample format. */
#if 0
#define PA_SAMPLE_TYPE paFloat32
#define SAMPLE_SIZE (4)
#define SAMPLE_SILENCE (0.0f)
#define CLEAR(a) bzero( (a), FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%.8f"
#elif 0
#define PA_SAMPLE_TYPE paInt16
#define SAMPLE_SIZE (2)
#define SAMPLE_SILENCE (0)
#define CLEAR(a) bzero( (a), FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%d"
#elif 1
#define PA_SAMPLE_TYPE paInt24
#define SAMPLE_SIZE (3)
#define SAMPLE_SILENCE (0)
#define CLEAR(a) bzero( (a), FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%d"
#elif 0
#define PA_SAMPLE_TYPE paInt8
#define SAMPLE_SIZE (1)
#define SAMPLE_SILENCE (0)
#define CLEAR(a) bzero( (a), FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE )
#define PRINTF_S_FORMAT "%d"
#else
#define PA_SAMPLE_TYPE paUInt8
#define SAMPLE_SIZE (1)
#define SAMPLE_SILENCE (128)
#define CLEAR( a ) { \
int i; \
for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ ) \
((unsigned char *)a)[i] = (SAMPLE_SILENCE); \
}
#define PRINTF_S_FORMAT "%d"
#endif
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters inputParameters, outputParameters;
PaStream *stream = NULL;
PaError err;
char *sampleBlock;
int i;
int numBytes;
printf("patest_read_write_wire.c\n"); fflush(stdout);
numBytes = FRAMES_PER_BUFFER * NUM_CHANNELS * SAMPLE_SIZE ;
sampleBlock = (char *) malloc( numBytes );
if( sampleBlock == NULL )
{
printf("Could not allocate record array.\n");
exit(1);
}
CLEAR( sampleBlock );
err = Pa_Initialize();
if( err != paNoError ) goto error;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
printf( "Input device # %d.\n", inputParameters.device );
printf( "Input LL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency );
printf( "Input HL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency );
inputParameters.channelCount = NUM_CHANNELS;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
printf( "Output device # %d.\n", outputParameters.device );
printf( "Output LL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency );
printf( "Output HL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency );
outputParameters.channelCount = NUM_CHANNELS;
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* -- setup -- */
err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Wire on. Will run one minute.\n"); fflush(stdout);
for( i=0; i<(60*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i )
{
err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
if( err ) goto xrun;
err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
if( err ) 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);
while( 1 )
{
err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
if( err ) goto xrun;
err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
if( err ) goto xrun;
}
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
Pa_CloseStream( stream );
free( sampleBlock );
Pa_Terminate();
return 0;
xrun:
if( stream ) {
Pa_AbortStream( stream );
Pa_CloseStream( stream );
}
free( sampleBlock );
Pa_Terminate();
if( err & paInputOverflow )
fprintf( stderr, "Input Overflow.\n" );
if( err & paOutputUnderflow )
fprintf( stderr, "Output Underflow.\n" );
return -2;
error:
if( stream ) {
Pa_AbortStream( stream );
Pa_CloseStream( stream );
}
free( sampleBlock );
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return -1;
}

View File

@@ -0,0 +1,344 @@
/** @file patest_record.c
@ingroup test_src
@brief Record input into an array; Save array to a file; Playback recorded data.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_record.c 1281 2007-09-16 11:06:51Z aknudsen $
*
* 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 "portaudio.h"
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#define NUM_SECONDS (5)
#define NUM_CHANNELS (2)
/* #define DITHER_FLAG (paDitherOff) */
#define DITHER_FLAG (0) /**/
/* Select sample format. */
#if 1
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#define PRINTF_S_FORMAT "%.8f"
#elif 1
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#elif 0
#define PA_SAMPLE_TYPE paInt8
typedef char SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#else
#define PA_SAMPLE_TYPE paUInt8
typedef unsigned char SAMPLE;
#define SAMPLE_SILENCE (128)
#define PRINTF_S_FORMAT "%d"
#endif
typedef struct
{
int frameIndex; /* Index into sample array. */
int maxFrameIndex;
SAMPLE *recordedSamples;
}
paTestData;
/* This routine will be called by the PortAudio engine when audio is needed.
** It may be called at interrupt level on some machines so don't do anything
** that could mess up the system like calling malloc() or free().
*/
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
(void) outputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
if( framesLeft < framesPerBuffer )
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if( inputBuffer == NULL )
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = SAMPLE_SILENCE; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE; /* right */
}
}
else
{
for( i=0; i<framesToCalc; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
SAMPLE *wptr = (SAMPLE*)outputBuffer;
unsigned int i;
int finished;
unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
(void) inputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
(void) userData;
if( framesLeft < framesPerBuffer )
{
/* final buffer... */
for( i=0; i<framesLeft; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
}
for( ; i<framesPerBuffer; i++ )
{
*wptr++ = 0; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = 0; /* right */
}
data->frameIndex += framesLeft;
finished = paComplete;
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
*wptr++ = *rptr++; /* left */
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++; /* right */
}
data->frameIndex += framesPerBuffer;
finished = paContinue;
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
printf("patest_record.c\n"); fflush(stdout);
data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
data.frameIndex = 0;
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */
if( data.recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
goto done;
}
for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
err = Pa_Initialize();
if( err != paNoError ) goto done;
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
inputParameters.channelCount = 2; /* stereo input */
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, /* &outputParameters, */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
recordCallback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("Now recording!!\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(1000);
printf("index = %d\n", data.frameIndex ); fflush(stdout);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
/* Measure maximum peak amplitude. */
max = 0;
average = 0.0;
for( i=0; i<numSamples; i++ )
{
val = data.recordedSamples[i];
if( val < 0 ) val = -val; /* ABS */
if( val > max )
{
max = val;
}
average += val;
}
average = average / (double)numSamples;
printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
printf("sample average = %lf\n", average );
/* Write recorded data to a file. */
#if 0
{
FILE *fid;
fid = fopen("recorded.raw", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
#endif
/* Playback recorded data. -------------------------------------------- */
data.frameIndex = 0;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
printf("Begin playback.\n"); fflush(stdout);
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
playCallback,
&data );
if( err != paNoError ) goto done;
if( stream )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("Waiting for playback to finish.\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
printf("Done.\n"); fflush(stdout);
}
done:
Pa_Terminate();
if( data.recordedSamples ) /* Sure it is NULL or valid. */
free( data.recordedSamples );
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
return err;
}

View File

@@ -0,0 +1,86 @@
/** @file patest_ringmix.c
@ingroup test_src
@brief Ring modulate inputs to left output, mix inputs to right output.
*/
/*
* $Id: patest_ringmix.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 "portaudio.h"
/* This will be called asynchronously by the PortAudio engine. */
static int myCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
const float *in = (const float *) inputBuffer;
float *out = (float *) outputBuffer;
float leftInput, rightInput;
unsigned int i;
/* Read input buffer, process data, and fill output buffer. */
for( i=0; i<framesPerBuffer; i++ )
{
leftInput = *in++; /* Get interleaved samples from input buffer. */
rightInput = *in++;
*out++ = leftInput * rightInput; /* ring modulation */
*out++ = 0.5f * (leftInput + rightInput); /* mix */
}
return 0;
}
/* Open a PortAudioStream to input and output audio data. */
int main(void)
{
PaStream *stream;
Pa_Initialize();
Pa_OpenDefaultStream(
&stream,
2, 2, /* stereo input and output */
paFloat32, 44100.0,
64, /* 64 frames per buffer */
myCallback, NULL );
Pa_StartStream( stream );
Pa_Sleep( 10000 ); /* Sleep for 10 seconds while processing. */
Pa_StopStream( stream );
Pa_CloseStream( stream );
Pa_Terminate();
return 0;
}

View File

@@ -0,0 +1,133 @@
/** @file patest_saw.c
@ingroup test_src
@brief Play a simple (aliasing) sawtooth wave.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_saw.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 (4)
#define SAMPLE_RATE (44100)
typedef struct
{
float left_phase;
float right_phase;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
/* Cast data passed through stream to our structure. */
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned int i;
(void) inputBuffer; /* Prevent unused variable warning. */
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->left_phase; /* left */
*out++ = data->right_phase; /* right */
/* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
data->left_phase += 0.01f;
/* When signal reaches top, drop back down. */
if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
/* higher pitch so we can distinguish left and right. */
data->right_phase += 0.03f;
if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
}
return 0;
}
/*******************************************************************/
static paTestData data;
int main(void);
int main(void)
{
PaStream *stream;
PaError err;
printf("PortAudio Test: output sawtooth wave.\n");
/* Initialize our data for use by callback. */
data.left_phase = data.right_phase = 0.0;
/* Initialize library before making any other calls. */
err = Pa_Initialize();
if( err != paNoError ) goto error;
/* Open an audio I/O stream. */
err = Pa_OpenDefaultStream( &stream,
0, /* no input channels */
2, /* stereo output */
paFloat32, /* 32 bit floating point output */
SAMPLE_RATE,
256, /* frames per buffer */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
/* Sleep for several seconds. */
Pa_Sleep(NUM_SECONDS*1000);
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,172 @@
/** @file patest_sine.c
@ingroup test_src
@brief Play a sine wave for several seconds.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_sine.c 1294 2007-10-24 20:51:22Z bjornroche $
*
* 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 (5)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
char message[20];
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
return paContinue;
}
/*
* This routine is called by portaudio when playback is done.
*/
static void StreamFinished( void* userData )
{
paTestData *data = (paTestData *) userData;
printf( "Stream Completed: %s\n", data->message );
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.left_phase = data.right_phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
sprintf( data.message, "No Message" );
err = Pa_SetStreamFinishedCallback( stream, &StreamFinished );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,221 @@
/** @file patest_sine8.c
@ingroup test_src
@brief Test 8 bit data: play a sine wave for several seconds.
@author Ross Bencina <rossb@audiomulch.com>
*/
/*
* $Id: patest_sine8.c 1162 2006-12-18 20:40:35Z bjornroche $
*
* 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 (8)
#define SAMPLE_RATE (44100)
#define TABLE_SIZE (200)
#define TEST_UNSIGNED (0)
#if TEST_UNSIGNED
#define TEST_FORMAT paUInt8
#else
#define TEST_FORMAT paInt8
#endif
#ifndef M_PI
#define M_PI (3.14159265)
#endif
typedef struct
{
#if TEST_UNSIGNED
unsigned char sine[TABLE_SIZE];
#else
char sine[TABLE_SIZE];
#endif
int left_phase;
int 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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
char *out = (char*)outputBuffer;
int i;
int framesToCalc;
int finished = 0;
(void) inputBuffer; /* Prevent unused variable warnings. */
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++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
/* zero remainder of final buffer */
for( ; i<(int)framesPerBuffer; i++ )
{
#if TEST_UNSIGNED
*out++ = (unsigned char) 0x80; /* left */
*out++ = (unsigned char) 0x80; /* right */
#else
*out++ = 0; /* left */
*out++ = 0; /* right */
#endif
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream* stream;
PaError err;
paTestData data;
PaTime streamOpened;
int i, totalSamps;
#if TEST_UNSIGNED
printf("PortAudio Test: output UNsigned 8 bit sine wave.\n");
#else
printf("PortAudio Test: output signed 8 bit sine wave.\n");
#endif
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (char) (127.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
#if TEST_UNSIGNED
data.sine[i] += (unsigned char) 0x80;
#endif
}
data.left_phase = data.right_phase = 0;
data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
err = Pa_Initialize();
if( err != paNoError )
goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
outputParameters.channelCount = 2; /* Stereo output. */
outputParameters.sampleFormat = TEST_FORMAT;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream( &stream,
NULL, /* No input. */
&outputParameters,
SAMPLE_RATE,
256, /* Frames per buffer. */
paClipOff, /* We won't output out of range samples so don't bother clipping them. */
patestCallback,
&data );
if( err != paNoError )
goto error;
streamOpened = Pa_GetStreamTime( stream ); /* Time in seconds when stream was opened (approx). */
err = Pa_StartStream( stream );
if( err != paNoError )
goto error;
/* Watch until sound is halfway finished. */
/* (Was ( Pa_StreamTime( stream ) < (totalSamps/2) ) in V18. */
while( (Pa_GetStreamTime( stream ) - streamOpened) < (PaTime)NUM_SECONDS / 2.0 )
Pa_Sleep(10);
/* Stop sound. */
printf("Stopping Stream.\n");
err = Pa_StopStream( stream );
if( err != paNoError )
goto error;
printf("Pause for 2 seconds.\n");
Pa_Sleep( 2000 );
printf("Starting again.\n");
err = Pa_StartStream( stream );
if( err != paNoError )
goto error;
printf("Waiting for sound to finish.\n");
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
Pa_Sleep(100);
if( err < 0 )
goto error;
err = Pa_CloseStream( stream );
if( err != paNoError )
goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,184 @@
/** @file patest_sine.c
@ingroup test_src
@brief Plays sine waves using sme simple channel maps.
Designed for use with COreAudio, but should made to work with other APIs
@author Bjorn Roche <bjorn@xowave.com>
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_sine.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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"
#ifdef __APPLE__
#include "pa_mac_core.h"
#endif
#define NUM_SECONDS (5)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
return paContinue;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
#ifdef __APPLE__
PaMacCoreStreamInfo macInfo;
const SInt32 channelMap[4] = { -1, -1, 0, 1 };
#endif
int i;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
printf("Output will be mapped to channels 2 and 3 instead of 0 and 1.\n");
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.left_phase = data.right_phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
/** setup host specific info */
#ifdef __APPLE__
PaMacCore_SetupStreamInfo( &macInfo, paMacCorePlayNice );
PaMacCore_SetupChannelMap( &macInfo, channelMap, 4 );
for( i=0; i<4; ++i )
printf( "channel %d name: %s\n", i, PaMacCore_GetChannelName( Pa_GetDefaultOutputDevice(), i, false ) );
#else
printf( "Channel mapping not supported on this platform. Reverting to normal sine test.\n" );
#endif
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
#ifdef __APPLE__
outputParameters.hostApiSpecificStreamInfo = &macInfo;
#else
outputParameters.hostApiSpecificStreamInfo = NULL;
#endif
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,203 @@
/** @file patest_sine_formats.c
@ingroup test_src
@brief Play a sine wave for several seconds. Test various data formats.
@author Phil Burk
*/
/*
* $Id: patest_sine_formats.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 (512)
#define LEFT_FREQ (SAMPLE_RATE/256.0) /* So we hit 1.0 */
#define RIGHT_FREQ (500.0)
#define AMPLITUDE (1.0)
/* Select ONE format for testing. */
#define TEST_UINT8 (0)
#define TEST_INT8 (0)
#define TEST_INT16 (1)
#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( const void *inputBuffer,
void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
SAMPLE_t *out = (SAMPLE_t *)outputBuffer;
int i;
int framesToCalc;
int finished = 0;
(void) inputBuffer; /* Prevent unused variable warnings. */
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;
*out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. )));
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. )));
}
/* 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)
{
PaStream *stream;
PaStreamParameters outputParameters;
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;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
outputParameters.channelCount = 2; /* Stereo output */
outputParameters.sampleFormat = TEST_FORMAT; /* Selected above. */
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream( &stream,
NULL, /* No input. */
&outputParameters, /* As above. */
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS );
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
if( err < 0 ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,215 @@
/** @file patest_sine_time.c
@ingroup test_src
@brief Play a sine wave for several seconds, pausing in the middle.
Uses the Pa_GetStreamTime() call.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_sine_time.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_util.h"
#define NUM_SECONDS (8)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (M_PI * 2.0)
#define TABLE_SIZE (200)
typedef struct
{
double left_phase;
double right_phase;
volatile PaTime outTime;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned int i;
double left_phaseInc = 0.02;
double right_phaseInc = 0.06;
double left_phase = data->left_phase;
double right_phase = data->right_phase;
(void) statusFlags; /* Prevent unused variable warnings. */
(void) inputBuffer;
data->outTime = timeInfo->outputBufferDacTime;
for( i=0; i<framesPerBuffer; i++ )
{
left_phase += left_phaseInc;
if( left_phase > TWOPI ) left_phase -= TWOPI;
*out++ = (float) sin( left_phase );
right_phase += right_phaseInc;
if( right_phase > TWOPI ) right_phase -= TWOPI;
*out++ = (float) sin( right_phase );
}
data->left_phase = left_phase;
data->right_phase = right_phase;
return paContinue;
}
/*******************************************************************/
static void ReportStreamTime( PaStream *stream, paTestData *data );
static void ReportStreamTime( PaStream *stream, paTestData *data )
{
PaTime streamTime, latency, outTime;
streamTime = Pa_GetStreamTime( stream );
outTime = data->outTime;
if( outTime < 0.0 )
{
printf("Stream time = %8.1f\n", streamTime );
}
else
{
latency = outTime - streamTime;
printf("Stream time = %8.4f, outTime = %8.4f, latency = %8.4f\n",
streamTime, outTime, latency );
}
fflush(stdout);
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
PaTime startTime;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
data.left_phase = data.right_phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
/* Watch until sound is halfway finished. */
printf("Play for %d seconds.\n", NUM_SECONDS/2 ); fflush(stdout);
data.outTime = -1.0; /* mark time for callback as undefined */
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
startTime = Pa_GetStreamTime( stream );
do
{
ReportStreamTime( stream, &data );
Pa_Sleep(100);
} while( (Pa_GetStreamTime( stream ) - startTime) < (NUM_SECONDS/2) );
/* Stop sound for 2 seconds. */
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
printf("Pause for 2 seconds.\n"); fflush(stdout);
Pa_Sleep( 2000 );
data.outTime = -1.0; /* mark time for callback as undefined */
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
startTime = Pa_GetStreamTime( stream );
printf("Play until sound is finished.\n"); fflush(stdout);
do
{
ReportStreamTime( stream, &data );
Pa_Sleep(100);
} while( (Pa_GetStreamTime( stream ) - startTime) < (NUM_SECONDS/2) );
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,168 @@
/** @file patest_start_stop.c
@ingroup test_src
@brief Play a sine wave for several seconds. Start and stop the stream multiple times.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_start_stop.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_GetDefaultOutputDevice() /* default output device */
#define NUM_SECONDS (3)
#define NUM_LOOPS (4)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (400)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
return paContinue;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.left_phase = data.right_phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = OUTPUT_DEVICE;
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
for( i=0; i<NUM_LOOPS; i++ )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
printf("Stopped.\n" );
Pa_Sleep( 1000 );
}
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,320 @@
/** @file patest_stop.c
@ingroup test_src
@brief Test different ways of stopping audio.
Test the three ways of stopping audio:
- calling Pa_StopStream(),
- calling Pa_AbortStream(),
- and returning a 1 from the callback function.
A long latency is set up so that you can hear the difference.
Then a simple 8 note sequence is repeated twice.
The program will print what you should hear.
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_stop.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_GetDefaultOutputDevice())
#define SLEEP_DUR (200)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (256)
#define LATENCY_SECONDS (3.f)
#define FRAMES_PER_NOTE (SAMPLE_RATE/2)
#define MAX_REPEATS (2)
#define FUNDAMENTAL (400.0f / SAMPLE_RATE)
#define NOTE_0 (FUNDAMENTAL * 1.0f / 1.0f)
#define NOTE_1 (FUNDAMENTAL * 5.0f / 4.0f)
#define NOTE_2 (FUNDAMENTAL * 4.0f / 3.0f)
#define NOTE_3 (FUNDAMENTAL * 3.0f / 2.0f)
#define NOTE_4 (FUNDAMENTAL * 2.0f / 1.0f)
#define MODE_FINISH (0)
#define MODE_STOP (1)
#define MODE_ABORT (2)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (400)
typedef struct
{
float waveform[TABLE_SIZE + 1]; /* Add one for guard point for interpolation. */
float phase_increment;
float phase;
float *tune;
int notesPerTune;
int frameCounter;
int noteCounter;
int repeatCounter;
PaTime outTime;
int stopMode;
int done;
}
paTestData;
/************* Prototypes *****************************/
int TestStopMode( paTestData *data );
float LookupWaveform( paTestData *data, float phase );
/******************************************************
* Convert phase between 0.0 and 1.0 to waveform value
* using linear interpolation.
*/
float LookupWaveform( paTestData *data, float phase )
{
float fIndex = phase*TABLE_SIZE;
int index = (int) fIndex;
float fract = fIndex - index;
float lo = data->waveform[index];
float hi = data->waveform[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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
float value;
unsigned int i = 0;
int finished = paContinue;
(void) inputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
/* data->outTime = outTime; */
if( !data->done )
{
for( i=0; i<framesPerBuffer; i++ )
{
/* Are we done with this note? */
if( data->frameCounter >= FRAMES_PER_NOTE )
{
data->noteCounter += 1;
data->frameCounter = 0;
/* Are we done with this tune? */
if( data->noteCounter >= data->notesPerTune )
{
data->noteCounter = 0;
data->repeatCounter += 1;
/* Are we totally done? */
if( data->repeatCounter >= MAX_REPEATS )
{
data->done = 1;
if( data->stopMode == MODE_FINISH )
{
finished = paComplete;
break;
}
}
}
data->phase_increment = data->tune[data->noteCounter];
}
value = LookupWaveform(data, data->phase);
*out++ = value; /* left */
*out++ = value; /* right */
data->phase += data->phase_increment;
if( data->phase >= 1.0f ) data->phase -= 1.0f;
data->frameCounter += 1;
}
}
/* zero remainder of final buffer */
for( ; i<framesPerBuffer; i++ )
{
*out++ = 0; /* left */
*out++ = 0; /* right */
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
paTestData data;
int i;
float simpleTune[] = { NOTE_0, NOTE_1, NOTE_2, NOTE_3, NOTE_4, NOTE_3, NOTE_2, NOTE_1 };
printf("PortAudio Test: play song and test stopping. ask for %f seconds latency\n", LATENCY_SECONDS );
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.waveform[i] = (float) (
(0.2 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )) +
(0.2 * sin( ((double)(3*i)/(double)TABLE_SIZE) * M_PI * 2. )) +
(0.1 * sin( ((double)(5*i)/(double)TABLE_SIZE) * M_PI * 2. ))
);
}
data.waveform[TABLE_SIZE] = data.waveform[0]; /* Set guard point. */
data.tune = &simpleTune[0];
data.notesPerTune = sizeof(simpleTune) / sizeof(float);
printf("Test MODE_FINISH - callback returns 1.\n");
printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
data.stopMode = MODE_FINISH;
if( TestStopMode( &data ) != paNoError )
{
printf("Test of MODE_FINISH failed!\n");
goto error;
}
printf("Test MODE_STOP - stop when song is done.\n");
printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
data.stopMode = MODE_STOP;
if( TestStopMode( &data ) != paNoError )
{
printf("Test of MODE_STOP failed!\n");
goto error;
}
printf("Test MODE_ABORT - abort immediately.\n");
printf("Should hear last repetition cut short by %f seconds.\n", LATENCY_SECONDS);
data.stopMode = MODE_ABORT;
if( TestStopMode( &data ) != paNoError )
{
printf("Test of MODE_ABORT failed!\n");
goto error;
}
return 0;
error:
return 1;
}
int TestStopMode( paTestData *data )
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
data->done = 0;
data->phase = 0.0;
data->frameCounter = 0;
data->noteCounter = 0;
data->repeatCounter = 0;
data->phase_increment = data->tune[data->noteCounter];
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = OUTPUT_DEVICE;
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = LATENCY_SECONDS;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER, /* frames per buffer */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
if( data->stopMode == MODE_FINISH )
{
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
/*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
data->noteCounter, data->repeatCounter );
fflush(stdout); */
Pa_Sleep( SLEEP_DUR );
}
if( err < 0 ) goto error;
}
else
{
while( data->repeatCounter < MAX_REPEATS )
{
/*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
data->noteCounter, data->repeatCounter );
fflush(stdout); */
Pa_Sleep( SLEEP_DUR );
}
}
if( data->stopMode == MODE_ABORT )
{
printf("Call Pa_AbortStream()\n");
err = Pa_AbortStream( stream );
}
else
{
printf("Call Pa_StopStream()\n");
err = Pa_StopStream( stream );
}
if( err != paNoError ) goto error;
printf("Call Pa_CloseStream()\n"); fflush(stdout);
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,439 @@
/** @file patest_stop_playout.c
@ingroup test_src
@brief Test whether all queued samples are played when Pa_StopStream()
is used with a callback or read/write stream, or when the callback
returns paComplete.
@author Ross Bencina <rossb@audiomulch.com>
*/
/*
* $Id: patest_stop_playout.c 1097 2006-08-26 08:27:53Z rossb $
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.portaudio.com/
* Copyright (c) 1999-2004 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 SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#define TONE_SECONDS (1) /* long tone */
#define TONE_FADE_SECONDS (.04) /* fades at start and end of long tone */
#define GAP_SECONDS (.25) /* gap between long tone and blip */
#define BLIP_SECONDS (.035) /* short blip */
#define NUM_REPEATS (3)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (2048)
typedef struct
{
float sine[TABLE_SIZE+1];
int repeatCount;
double phase;
double lowIncrement, highIncrement;
int gap1Length, toneLength, toneFadesLength, gap2Length, blipLength;
int gap1Countdown, toneCountdown, gap2Countdown, blipCountdown;
}
TestData;
static void RetriggerTestSignalGenerator( TestData *data )
{
data->phase = 0.;
data->gap1Countdown = data->gap1Length;
data->toneCountdown = data->toneLength;
data->gap2Countdown = data->gap2Length;
data->blipCountdown = data->blipLength;
}
static void ResetTestSignalGenerator( TestData *data )
{
data->repeatCount = 0;
RetriggerTestSignalGenerator( data );
}
static void InitTestSignalGenerator( TestData *data )
{
int signalLengthModBufferLength, 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]; /* guard point for linear interpolation */
data->lowIncrement = (330. / SAMPLE_RATE) * TABLE_SIZE;
data->highIncrement = (1760. / SAMPLE_RATE) * TABLE_SIZE;
data->gap1Length = GAP_SECONDS * SAMPLE_RATE;
data->toneLength = TONE_SECONDS * SAMPLE_RATE;
data->toneFadesLength = TONE_FADE_SECONDS * SAMPLE_RATE;
data->gap2Length = GAP_SECONDS * SAMPLE_RATE;
data->blipLength = BLIP_SECONDS * SAMPLE_RATE;
/* adjust signal length to be a multiple of the buffer length */
signalLengthModBufferLength = (data->gap1Length + data->toneLength + data->gap2Length + data->blipLength) % FRAMES_PER_BUFFER;
if( signalLengthModBufferLength > 0 )
data->toneLength += signalLengthModBufferLength;
ResetTestSignalGenerator( data );
}
#define MIN( a, b ) (((a)<(b))?(a):(b))
static void GenerateTestSignal( TestData *data, float *stereo, int frameCount )
{
int framesGenerated = 0;
float output;
long index;
float fraction;
int count, i;
while( framesGenerated < frameCount && data->repeatCount < NUM_REPEATS )
{
if( framesGenerated < frameCount && data->gap1Countdown > 0 ){
count = MIN( frameCount - framesGenerated, data->gap1Countdown );
for( i=0; i < count; ++i )
{
*stereo++ = 0.f;
*stereo++ = 0.f;
}
data->gap1Countdown -= count;
framesGenerated += count;
}
if( framesGenerated < frameCount && data->toneCountdown > 0 ){
count = MIN( frameCount - framesGenerated, data->toneCountdown );
for( i=0; i < count; ++i )
{
/* tone with data->lowIncrement phase increment */
index = (long)data->phase;
fraction = data->phase - index;
output = data->sine[ index ] + (data->sine[ index + 1 ] - data->sine[ index ]) * fraction;
data->phase += data->lowIncrement;
while( data->phase >= TABLE_SIZE )
data->phase -= TABLE_SIZE;
/* apply fade to ends */
if( data->toneCountdown < data->toneFadesLength )
{
/* cosine-bell fade out at end */
output *= (-cos(((float)data->toneCountdown / (float)data->toneFadesLength) * M_PI) + 1.) * .5;
}
else if( data->toneCountdown > data->toneLength - data->toneFadesLength )
{
/* cosine-bell fade in at start */
output *= (cos(((float)(data->toneCountdown - (data->toneLength - data->toneFadesLength)) / (float)data->toneFadesLength) * M_PI) + 1.) * .5;
}
output *= .5; /* play tone half as loud as blip */
*stereo++ = output;
*stereo++ = output;
data->toneCountdown--;
}
framesGenerated += count;
}
if( framesGenerated < frameCount && data->gap2Countdown > 0 ){
count = MIN( frameCount - framesGenerated, data->gap2Countdown );
for( i=0; i < count; ++i )
{
*stereo++ = 0.f;
*stereo++ = 0.f;
}
data->gap2Countdown -= count;
framesGenerated += count;
}
if( framesGenerated < frameCount && data->blipCountdown > 0 ){
count = MIN( frameCount - framesGenerated, data->blipCountdown );
for( i=0; i < count; ++i )
{
/* tone with data->highIncrement phase increment */
index = (long)data->phase;
fraction = data->phase - index;
output = data->sine[ index ] + (data->sine[ index + 1 ] - data->sine[ index ]) * fraction;
data->phase += data->highIncrement;
while( data->phase >= TABLE_SIZE )
data->phase -= TABLE_SIZE;
/* cosine-bell envelope over whole blip */
output *= (-cos( ((float)data->blipCountdown / (float)data->blipLength) * 2. * M_PI) + 1.) * .5;
*stereo++ = output;
*stereo++ = output;
data->blipCountdown--;
}
framesGenerated += count;
}
if( data->blipCountdown == 0 )
{
RetriggerTestSignalGenerator( data );
data->repeatCount++;
}
}
if( framesGenerated < frameCount )
{
count = frameCount - framesGenerated;
for( i=0; i < count; ++i )
{
*stereo++ = 0.f;
*stereo++ = 0.f;
}
}
}
static int IsTestSignalFinished( TestData *data )
{
if( data->repeatCount >= NUM_REPEATS )
return 1;
else
return 0;
}
static int TestCallback1( const void *inputBuffer, void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
(void) inputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
GenerateTestSignal( (TestData*)userData, (float*)outputBuffer, frameCount );
if( IsTestSignalFinished( (TestData*)userData ) )
return paComplete;
else
return paContinue;
}
volatile int testCallback2Finished = 0;
static int TestCallback2( const void *inputBuffer, void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
(void) inputBuffer; /* Prevent unused variable warnings. */
(void) timeInfo;
(void) statusFlags;
GenerateTestSignal( (TestData*)userData, (float*)outputBuffer, frameCount );
if( IsTestSignalFinished( (TestData*)userData ) )
testCallback2Finished = 1;
return paContinue;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
TestData data;
float writeBuffer[ FRAMES_PER_BUFFER * 2 ];
printf("PortAudio Test: check that stopping stream plays out all queued samples. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
InitTestSignalGenerator( &data );
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* test paComplete ---------------------------------------------------------- */
ResetTestSignalGenerator( &data );
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
TestCallback1,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("\nPlaying 'tone-blip' %d times using callback, stops by returning paComplete from callback.\n", NUM_REPEATS );
printf("If final blip is not intact, callback+paComplete implementation may be faulty.\n\n" );
while( (err = Pa_IsStreamActive( stream )) == 1 )
Pa_Sleep( 5 );
if( err != 0 ) goto error;
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Sleep( 500 );
/* test Pa_StopStream() with callback --------------------------------------- */
ResetTestSignalGenerator( &data );
testCallback2Finished = 0;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
TestCallback2,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("\nPlaying 'tone-blip' %d times using callback, stops by calling Pa_StopStream.\n", NUM_REPEATS );
printf("If final blip is not intact, callback+Pa_StopStream implementation may be faulty.\n\n" );
/* note that polling a volatile flag is not a good way to synchronise with
the callback, but it's the best we can do portably. */
while( !testCallback2Finished )
Pa_Sleep( 2 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Sleep( 500 );
/* test Pa_StopStream() with Pa_WriteStream --------------------------------- */
ResetTestSignalGenerator( &data );
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("\nPlaying 'tone-blip' %d times using Pa_WriteStream, stops by calling Pa_StopStream.\n", NUM_REPEATS );
printf("If final blip is not intact, Pa_WriteStream+Pa_StopStream implementation may be faulty.\n\n" );
do{
GenerateTestSignal( &data, writeBuffer, FRAMES_PER_BUFFER );
err = Pa_WriteStream( stream, writeBuffer, FRAMES_PER_BUFFER );
if( err != paNoError ) goto error;
}while( !IsTestSignalFinished( &data ) );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
/* -------------------------------------------------------------------------- */
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,267 @@
/** @file patest_sync.c
@ingroup test_src
@brief Test time stamping and synchronization of audio and video.
A high latency is used so we can hear the difference in time.
Random durations are used so we know we are hearing the right beep
and not the one before or after.
Sequence of events:
-# Foreground requests a beep.
-# Background randomly schedules a beep.
-# Foreground waits for the beep to be heard based on PaUtil_GetTime().
-# Foreground outputs video (printf) in sync with audio.
-# Repeat.
@author Phil Burk http://www.softsynth.com
*/
/*
* $Id: patest_sync.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_util.h"
#define NUM_BEEPS (6)
#define SAMPLE_RATE (44100)
#define SAMPLE_PERIOD (1.0/44100.0)
#define FRAMES_PER_BUFFER (256)
#define BEEP_DURATION (400)
#define LATENCY_MSEC (2000)
#define SLEEP_MSEC (10)
#define TIMEOUT_MSEC (15000)
#define STATE_BKG_IDLE (0)
#define STATE_BKG_PENDING (1)
#define STATE_BKG_BEEPING (2)
typedef struct
{
float left_phase;
float right_phase;
int state;
volatile int requestBeep; /* Set by foreground, cleared by background. */
PaTime beepTime;
int beepCount;
double latency; /* For debugging. */
}
paTestData;
static unsigned long GenerateRandomNumber( void );
/************************************************************/
/* Calculate pseudo-random 32 bit number based on linear congruential method. */
static unsigned long GenerateRandomNumber( void )
{
static unsigned long randSeed = 99887766; /* Change this for different random sequences. */
randSeed = (randSeed * 196314165) + 907633515;
return randSeed;
}
/* 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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags, void *userData )
{
/* Cast data passed through stream to our structure. */
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned int i;
(void) inputBuffer;
data->latency = timeInfo->outputBufferDacTime - timeInfo->currentTime;
for( i=0; i<framesPerBuffer; i++ )
{
switch( data->state )
{
case STATE_BKG_IDLE:
/* Schedule beep at some random time in the future. */
if( data->requestBeep )
{
int random = GenerateRandomNumber() >> 14;
data->beepTime = timeInfo->outputBufferDacTime + (( (double)(random + SAMPLE_RATE)) * SAMPLE_PERIOD );
data->state = STATE_BKG_PENDING;
}
*out++ = 0.0; /* left */
*out++ = 0.0; /* right */
break;
case STATE_BKG_PENDING:
if( (timeInfo->outputBufferDacTime + (i*SAMPLE_PERIOD)) >= data->beepTime )
{
data->state = STATE_BKG_BEEPING;
data->beepCount = BEEP_DURATION;
data->left_phase = data->right_phase = 0.0;
}
*out++ = 0.0; /* left */
*out++ = 0.0; /* right */
break;
case STATE_BKG_BEEPING:
if( data->beepCount <= 0 )
{
data->state = STATE_BKG_IDLE;
data->requestBeep = 0;
*out++ = 0.0; /* left */
*out++ = 0.0; /* right */
}
else
{
/* Play sawtooth wave. */
*out++ = data->left_phase; /* left */
*out++ = data->right_phase; /* right */
/* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
data->left_phase += 0.01f;
/* When signal reaches top, drop back down. */
if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
/* higher pitch so we can distinguish left and right. */
data->right_phase += 0.03f;
if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
}
data->beepCount -= 1;
break;
default:
data->state = STATE_BKG_IDLE;
break;
}
}
return 0;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStream *stream;
PaError err;
paTestData DATA;
int i, timeout;
PaTime previousTime;
PaStreamParameters outputParameters;
printf("PortAudio Test: you should see BEEP at the same time you hear it.\n");
printf("Wait for a few seconds random delay between BEEPs.\n");
printf("BEEP %d times.\n", NUM_BEEPS );
/* Initialize our DATA for use by callback. */
DATA.left_phase = DATA.right_phase = 0.0;
DATA.state = STATE_BKG_IDLE;
DATA.requestBeep = 0;
/* Initialize library before making any other calls. */
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice();
outputParameters.channelCount = 2;
outputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.sampleFormat = paFloat32;
outputParameters.suggestedLatency = (double)LATENCY_MSEC / 1000;
/* Open an audio I/O stream. */
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER, /* frames per buffer */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&DATA );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("started\n");
fflush(stdout);
previousTime = Pa_GetStreamTime( stream );
for( i=0; i<NUM_BEEPS; i++ )
{
/* Request a beep from background. */
DATA.requestBeep = 1;
/* Wait for background to acknowledge request. */
timeout = TIMEOUT_MSEC;
while( (DATA.requestBeep == 1) && (timeout-- > 0 ) ) Pa_Sleep(SLEEP_MSEC);
if( timeout <= 0 )
{
fprintf( stderr, "Timed out waiting for background to acknowledge request.\n" );
goto error;
}
printf("calc beep for %9.3f, latency = %6.3f\n", DATA.beepTime, DATA.latency );
fflush(stdout);
/* Wait for scheduled beep time. */
timeout = TIMEOUT_MSEC + (10000/SLEEP_MSEC);
while( (Pa_GetStreamTime( stream ) < DATA.beepTime) && (timeout-- > 0 ) )
{
Pa_Sleep(SLEEP_MSEC);
}
if( timeout <= 0 )
{
fprintf( stderr, "Timed out waiting for time. Now = %9.3f, Beep for %9.3f.\n",
PaUtil_GetTime(), DATA.beepTime );
goto error;
}
/* Beep should be sounding now so print synchronized BEEP. */
printf("hear \"BEEP\" at %9.3f, delta = %9.3f\n",
Pa_GetStreamTime( stream ), (DATA.beepTime - previousTime) );
fflush(stdout);
previousTime = DATA.beepTime;
}
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,173 @@
/** @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
@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 $
*
* 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 (5)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
PaStream *stream;
PaTime start;
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
printf( "Timing info given to callback: Adc: %g, Current: %g, Dac: %g\n",
timeInfo->inputBufferAdcTime,
timeInfo->currentTime,
timeInfo->outputBufferDacTime );
printf( "getStreamTime() returns: %g\n", Pa_GetStreamTime(data->stream)-data->start );
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
return paContinue;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.left_phase = data.right_phase = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
data.stream = stream;
data.start = Pa_GetStreamTime(stream);
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
data.start = Pa_GetStreamTime(stream);
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
printf("The tone should have been heard for about 5 seconds and all the timing info above should report that about 5 seconds elapsed (except Adc, which is undefined since there was no input device opened).\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

@@ -0,0 +1,181 @@
/** @file patest_toomanysines.c
@ingroup test_src
@brief Play more sine waves than we can handle in real time as a stress test.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_toomanysines.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 MAX_SINES (500)
#define MAX_LOAD (1.2)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (512)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TWOPI (M_PI * 2.0)
typedef struct paTestData
{
int numSines;
double phases[MAX_SINES];
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
int j;
int finished = 0;
(void) inputBuffer; /* Prevent unused variable warning. */
for( i=0; i<framesPerBuffer; i++ )
{
float output = 0.0;
double phaseInc = 0.02;
double phase;
for( j=0; j<data->numSines; j++ )
{
/* Advance phase of next oscillator. */
phase = data->phases[j];
phase += phaseInc;
if( phase > TWOPI ) phase -= TWOPI;
phaseInc *= 1.02;
if( phaseInc > 0.5 ) phaseInc *= 0.5;
/* This is not a very efficient way to calc sines. */
output += (float) sin( phase );
data->phases[j] = phase;
}
*out++ = (float) (output / data->numSines);
}
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
int numStress;
paTestData data = {0};
double load;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD );
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 1; /* mono output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* 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;
/* Determine number of sines required to get to 50% */
do
{
data.numSines++;
Pa_Sleep( 100 );
load = Pa_GetStreamCpuLoad( stream );
printf("numSines = %d, CPU load = %f\n", data.numSines, load );
}
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++ )
{
Pa_Sleep( 200 );
load = Pa_GetStreamCpuLoad( stream );
printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load );
}
printf("Suffer for 5 seconds.\n");
Pa_Sleep( 5000 );
printf("Stop stream.\n");
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,178 @@
/** @file patest_two_rates.c
@ingroup test_src
@brief Play two streams at different rates to make sure they don't interfere.
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_two_rates.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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_1 (44100)
#define SAMPLE_RATE_2 (44100)
#define FRAMES_PER_BUFFER (256)
#define FREQ_INCR (0.1)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
typedef struct
{
double phase;
double numFrames;
} 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++ )
{
/* Generate sine wave. */
float value = (float) 0.3 * sin(data->phase);
/* Stereo - two channels. */
*out++ = value;
*out++ = value;
data->phase += FREQ_INCR;
if( data->phase >= (2.0 * M_PI) ) data->phase -= (2.0 * M_PI);
}
return 0;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaError err;
PortAudioStream *stream1;
PortAudioStream *stream2;
paTestData data1 = {0};
paTestData data2 = {0};
printf("PortAudio Test: two rates.\n" );
err = Pa_Initialize();
if( err != paNoError ) goto error;
/* Start first stream. **********************/
err = Pa_OpenStream(
&stream1,
paNoDevice, /* default input device */
0, /* no input */
paFloat32, /* 32 bit floating point input */
NULL,
OUTPUT_DEVICE,
2, /* Stereo */
paFloat32, /* 32 bit floating point output */
NULL,
SAMPLE_RATE_1,
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,
&data1 );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream1 );
if( err != paNoError ) goto error;
Pa_Sleep( 3 * 1000 );
/* Start second stream. **********************/
err = Pa_OpenStream(
&stream2,
paNoDevice, /* default input device */
0, /* no input */
paFloat32, /* 32 bit floating point input */
NULL,
OUTPUT_DEVICE,
2, /* Stereo */
paFloat32, /* 32 bit floating point output */
NULL,
SAMPLE_RATE_2,
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,
&data2 );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream2 );
if( err != paNoError ) goto error;
Pa_Sleep( 3 * 1000 );
err = Pa_StopStream( stream2 );
if( err != paNoError ) goto error;
Pa_Sleep( 3 * 1000 );
err = Pa_StopStream( stream1 );
if( err != paNoError ) goto error;
Pa_CloseStream( stream2 );
Pa_CloseStream( stream1 );
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

@@ -0,0 +1,158 @@
/** @file patest_underflow.c
@ingroup test_src
@brief Simulate an output buffer underflow condition.
Tests whether the stream can be stopped when underflowing buffers.
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_underflow.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 (20)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (2048)
#define MSEC_PER_BUFFER ( (FRAMES_PER_BUFFER * 1000) / SAMPLE_RATE )
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
int sleepTime;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i;
int finished = 0;
(void) inputBuffer; /* Prevent unused variable warnings. */
for( i=0; i<framesPerBuffer; i++ )
{
*out++ = data->sine[data->left_phase]; /* left */
*out++ = data->sine[data->right_phase]; /* 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;
}
/* Cause underflow to occur. */
if( data->sleepTime > 0 ) Pa_Sleep( data->sleepTime );
data->sleepTime += 1;
return finished;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
paTestData data;
int i;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.left_phase = data.right_phase = data.sleepTime = 0;
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
while( data.sleepTime < (2 * MSEC_PER_BUFFER) )
{
printf("SleepTime = %d\n", data.sleepTime );
Pa_Sleep( data.sleepTime );
}
printf("Try to stop stream.\n");
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,292 @@
/** @file patest_wire.c
@ingroup test_src
@brief Pass input directly to output.
Note that some HW devices, for example many ISA audio cards
on PCs, do NOT support full duplex! For a PC, you normally need
a PCI based audio card such as the SBLive.
@author Phil Burk http://www.softsynth.com
While adapting to V19-API, I excluded configs with framesPerCallback=0
because of an assert in file pa_common/pa_process.c. Pieter, Oct 9, 2003.
*/
/*
* $Id: patest_wire.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 SAMPLE_RATE (44100)
typedef struct WireConfig_s
{
int isInputInterleaved;
int isOutputInterleaved;
int numInputChannels;
int numOutputChannels;
int framesPerCallback;
} WireConfig_t;
#define USE_FLOAT_INPUT (1)
#define USE_FLOAT_OUTPUT (1)
/* Latencies set to defaults. */
#if USE_FLOAT_INPUT
#define INPUT_FORMAT paFloat32
typedef float INPUT_SAMPLE;
#else
#define INPUT_FORMAT paInt16
typedef short INPUT_SAMPLE;
#endif
#if USE_FLOAT_OUTPUT
#define OUTPUT_FORMAT paFloat32
typedef float OUTPUT_SAMPLE;
#else
#define OUTPUT_FORMAT paInt16
typedef short OUTPUT_SAMPLE;
#endif
double gInOutScaler = 1.0;
#define CONVERT_IN_TO_OUT(in) ((OUTPUT_SAMPLE) ((in) * gInOutScaler))
#define INPUT_DEVICE (Pa_GetDefaultInputDevice())
#define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice())
static PaError TestConfiguration( WireConfig_t *config );
static int wireCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData );
/* 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 wireCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
INPUT_SAMPLE *in;
OUTPUT_SAMPLE *out;
int inStride;
int outStride;
int inDone = 0;
int outDone = 0;
WireConfig_t *config = (WireConfig_t *) userData;
unsigned int i;
int inChannel, outChannel;
/* This may get called with NULL inputBuffer during initial setup. */
if( inputBuffer == NULL) return 0;
inChannel=0, outChannel=0;
while( !(inDone && outDone) )
{
if( config->isInputInterleaved )
{
in = ((INPUT_SAMPLE*)inputBuffer) + inChannel;
inStride = config->numInputChannels;
}
else
{
in = ((INPUT_SAMPLE**)inputBuffer)[inChannel];
inStride = 1;
}
if( config->isOutputInterleaved )
{
out = ((OUTPUT_SAMPLE*)outputBuffer) + outChannel;
outStride = config->numOutputChannels;
}
else
{
out = ((OUTPUT_SAMPLE**)outputBuffer)[outChannel];
outStride = 1;
}
for( i=0; i<framesPerBuffer; i++ )
{
*out = CONVERT_IN_TO_OUT( *in );
out += outStride;
in += inStride;
}
if(inChannel < (config->numInputChannels - 1)) inChannel++;
else inDone = 1;
if(outChannel < (config->numOutputChannels - 1)) outChannel++;
else outDone = 1;
}
return 0;
}
/*******************************************************************/
int main(void);
int main(void)
{
PaError err;
WireConfig_t CONFIG;
WireConfig_t *config = &CONFIG;
int configIndex = 0;;
err = Pa_Initialize();
if( err != paNoError ) goto error;
printf("Please connect audio signal to input and listen for it on output!\n");
printf("input format = %lu\n", INPUT_FORMAT );
printf("output format = %lu\n", OUTPUT_FORMAT );
printf("input device ID = %d\n", INPUT_DEVICE );
printf("output device ID = %d\n", OUTPUT_DEVICE );
if( INPUT_FORMAT == OUTPUT_FORMAT )
{
gInOutScaler = 1.0;
}
else if( (INPUT_FORMAT == paInt16) && (OUTPUT_FORMAT == paFloat32) )
{
gInOutScaler = 1.0/32768.0;
}
else if( (INPUT_FORMAT == paFloat32) && (OUTPUT_FORMAT == paInt16) )
{
gInOutScaler = 32768.0;
}
for( config->isInputInterleaved = 0; config->isInputInterleaved < 2; config->isInputInterleaved++ )
{
for( config->isOutputInterleaved = 0; config->isOutputInterleaved < 2; config->isOutputInterleaved++ )
{
for( config->numInputChannels = 1; config->numInputChannels < 3; config->numInputChannels++ )
{
for( config->numOutputChannels = 1; config->numOutputChannels < 3; config->numOutputChannels++ )
{
/* If framesPerCallback = 0, assertion fails in file pa_common/pa_process.c, line 1413: EX. */
for( config->framesPerCallback = 64; config->framesPerCallback < 129; config->framesPerCallback += 64 )
{
printf("-----------------------------------------------\n" );
printf("Configuration #%d\n", configIndex++ );
err = TestConfiguration( config );
/* Give user a chance to bail out. */
if( err == 1 )
{
err = paNoError;
goto done;
}
else if( err != paNoError ) goto error;
}
}
}
}
}
done:
Pa_Terminate();
printf("Full duplex sound test complete.\n"); fflush(stdout);
printf("Hit ENTER to quit.\n"); fflush(stdout);
getchar();
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 ) );
printf("Hit ENTER to quit.\n"); fflush(stdout);
getchar();
return -1;
}
static PaError TestConfiguration( WireConfig_t *config )
{
int c;
PaError err;
PaStream *stream;
PaStreamParameters inputParameters, outputParameters;
printf("input %sinterleaved!\n", (config->isInputInterleaved ? " " : "NOT ") );
printf("output %sinterleaved!\n", (config->isOutputInterleaved ? " " : "NOT ") );
printf("input channels = %d\n", config->numInputChannels );
printf("output channels = %d\n", config->numOutputChannels );
printf("framesPerCallback = %d\n", config->framesPerCallback );
inputParameters.device = INPUT_DEVICE; /* default input device */
inputParameters.channelCount = config->numInputChannels;
inputParameters.sampleFormat = INPUT_FORMAT | (config->isInputInterleaved ? 0 : paNonInterleaved);
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = OUTPUT_DEVICE; /* default output device */
outputParameters.channelCount = config->numOutputChannels;
outputParameters.sampleFormat = OUTPUT_FORMAT | (config->isOutputInterleaved ? 0 : paNonInterleaved);
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
&inputParameters,
&outputParameters,
SAMPLE_RATE,
config->framesPerCallback, /* frames per buffer */
paClipOff, /* we won't output out of range samples so don't bother clipping them */
wireCallback,
config );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Hit ENTER for next configuration, or 'q' to quit.\n"); fflush(stdout);
c = getchar();
printf("Closing stream.\n");
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
if( c == 'q' ) return 1;
error:
return err;
}

View File

@@ -0,0 +1,206 @@
/*
* $Id: $
* Portable Audio I/O Library
* Windows MME surround sound output test
*
* Copyright (c) 2007 Ross Bencina
*
* 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 <windows.h> /* required when using pa_win_wmme.h */
#include <mmsystem.h> /* required when using pa_win_wmme.h */
#include "portaudio.h"
#include "pa_win_wmme.h"
#define NUM_SECONDS (12)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (64)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (100)
#define CHANNEL_COUNT (6)
typedef struct
{
float sine[TABLE_SIZE];
int phase;
int currentChannel;
int cycleCount;
}
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( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
float *out = (float*)outputBuffer;
unsigned long i,j;
(void) timeInfo; /* Prevent unused variable warnings. */
(void) statusFlags;
(void) inputBuffer;
for( i=0; i<framesPerBuffer; i++ )
{
for( j = 0; j < CHANNEL_COUNT; ++j ){
if( j == data->currentChannel && data->cycleCount < 4410 ){
*out++ = data->sine[data->phase];
data->phase += 1 + j; // play each channel at a different pitch so they can be distinguished
if( data->phase >= TABLE_SIZE ){
data->phase -= TABLE_SIZE;
}
}else{
*out++ = 0;
}
}
data->cycleCount++;
if( data->cycleCount > 44100 ){
data->cycleCount = 0;
++data->currentChannel;
if( data->currentChannel >= CHANNEL_COUNT )
data->currentChannel -= CHANNEL_COUNT;
}
}
return paContinue;
}
/*******************************************************************/
int main(int argc, char* argv[])
{
PaStreamParameters outputParameters;
PaWinMmeStreamInfo wmmeStreamInfo;
PaStream *stream;
PaError err;
paTestData data;
int i;
int deviceIndex;
printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);
err = Pa_Initialize();
if( err != paNoError ) goto error;
deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paMME ) )->defaultOutputDevice;
if( argc == 2 ){
sscanf( argv[1], "%d", &deviceIndex );
}
printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
data.phase = 0;
data.currentChannel = 0;
data.cycleCount = 0;
outputParameters.device = deviceIndex;
outputParameters.channelCount = CHANNEL_COUNT;
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* it's not strictly necessary to provide a channelMask for surround sound
output. But if you want to be sure which channel mask PortAudio will use
then you should supply one */
wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo);
wmmeStreamInfo.hostApiType = paMME;
wmmeStreamInfo.version = 1;
wmmeStreamInfo.flags = paWinMmeUseChannelMask;
wmmeStreamInfo.channelMask = PAWIN_SPEAKER_5POINT1; /* request 5.1 output format */
outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo;
if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){
printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
}else{
printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
}
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
patestCallback,
&data );
if( err != paNoError ) goto error;
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
Pa_Sleep( NUM_SECONDS * 1000 );
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("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

@@ -0,0 +1,155 @@
/** @file patest_write_sine.c
@ingroup test_src
@brief Play a sine wave for several seconds using the blocking API (Pa_WriteStream())
@author Ross Bencina <rossb@audiomulch.com>
@author Phil Burk <philburk@softsynth.com>
*/
/*
* $Id: patest_write_sine.c 1097 2006-08-26 08:27:53Z rossb $
*
* 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 (5)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
float sine[TABLE_SIZE]; /* sine wavetable */
int left_phase = 0;
int right_phase = 0;
int left_inc = 1;
int right_inc = 3; /* higher pitch so we can distinguish left and right. */
int i, j, k;
int bufferCount;
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) goto error;
printf( "Play 3 times, higher each time.\n" );
for( k=0; k < 3; ++k )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Play for %d seconds.\n", NUM_SECONDS );
bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER);
for( i=0; i < bufferCount; i++ )
{
for( j=0; j < FRAMES_PER_BUFFER; j++ )
{
buffer[j][0] = sine[left_phase]; /* left */
buffer[j][1] = sine[right_phase]; /* right */
left_phase += left_inc;
if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
right_phase += right_inc;
if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
}
err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
if( err != paNoError ) goto error;
}
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
++left_inc;
++right_inc;
Pa_Sleep( 1000 );
}
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}

View File

@@ -0,0 +1,165 @@
/** @file patest_write_stop.c
@brief Play a few seconds of silence followed by a few cycles of a sine wave. Tests to make sure that pa_StopStream() completes playback in blocking I/O
@author Bjorn Roche of XO Audio (www.xoaudio.com)
@author Ross Bencina
@author Phil Burk
*/
/*
* $Id: patest_write_stop.c 1083 2006-08-23 07:30:49Z rossb $
*
* 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 (5)
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
int main(void);
int main(void)
{
PaStreamParameters outputParameters;
PaStream *stream;
PaError err;
float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
float sine[TABLE_SIZE]; /* sine wavetable */
int left_phase = 0;
int right_phase = 0;
int left_inc = 1;
int right_inc = 3; /* higher pitch so we can distinguish left and right. */
int i, j;
int bufferCount;
const int framesBy2 = FRAMES_PER_BUFFER >> 1;
const float framesBy2f = (float) framesBy2 ;
printf( "PortAudio Test: output silence, followed by one buffer of a ramped sine wave. SR = %d, BufSize = %d\n",
SAMPLE_RATE, FRAMES_PER_BUFFER);
/* initialise sinusoidal wavetable */
for( i=0; i<TABLE_SIZE; i++ )
{
sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
}
err = Pa_Initialize();
if( err != paNoError ) goto error;
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
outputParameters.channelCount = 2; /* stereo output */
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency * 5;
outputParameters.hostApiSpecificStreamInfo = NULL;
/* open the stream */
err = Pa_OpenStream(
&stream,
NULL, /* no input */
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff, /* we won't output out of range samples so don't bother clipping them */
NULL, /* no callback, use blocking API */
NULL ); /* no callback, so no callback userData */
if( err != paNoError ) goto error;
/* start the stream */
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
printf("Playing %d seconds of silence followed by one buffer of a ramped sinusoid.\n", NUM_SECONDS );
bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER);
/* clear buffer */
for( j=0; j < FRAMES_PER_BUFFER; j++ )
{
buffer[j][0] = 0; /* left */
buffer[j][1] = 0; /* right */
}
/* play the silent buffer a bunch o' times */
for( i=0; i < bufferCount; i++ )
{
err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
if( err != paNoError ) goto error;
}
/* play a non-silent buffer once */
for( j=0; j < FRAMES_PER_BUFFER; j++ )
{
float ramp = 1;
if( j < framesBy2 )
ramp = j / framesBy2f;
else
ramp = (FRAMES_PER_BUFFER - j) / framesBy2f ;
buffer[j][0] = sine[left_phase] * ramp; /* left */
buffer[j][1] = sine[right_phase] * ramp; /* right */
left_phase += left_inc;
if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
right_phase += right_inc;
if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
}
err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
if( err != paNoError ) goto error;
/* stop stream, close, and terminate */
err = Pa_StopStream( stream );
if( err != paNoError ) goto error;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
printf("Test finished.\n");
return err;
error:
Pa_Terminate();
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
return err;
}