From ae6b5d89ea93b95c2990895077cf5e8f0bba9ad9 Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Mon, 2 Feb 2004 11:28:02 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r1301, which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=1302 --- pd/portaudio_v18/pa_tests/debug_convert.c | 131 +++++++++ pd/portaudio_v18/pa_tests/debug_dither_calc.c | 55 ++++ pd/portaudio_v18/pa_tests/debug_dual.c | 183 ++++++++++++ pd/portaudio_v18/pa_tests/debug_multi_in.c | 187 +++++++++++++ pd/portaudio_v18/pa_tests/debug_multi_out.c | 139 ++++++++++ pd/portaudio_v18/pa_tests/debug_record.c | 338 +++++++++++++++++++++++ pd/portaudio_v18/pa_tests/debug_record_reuse.c | 351 ++++++++++++++++++++++++ pd/portaudio_v18/pa_tests/debug_sine.c | 201 ++++++++++++++ pd/portaudio_v18/pa_tests/debug_sine_amp.c | 157 +++++++++++ pd/portaudio_v18/pa_tests/debug_sine_formats.c | 202 ++++++++++++++ pd/portaudio_v18/pa_tests/debug_sine_getchar.c | 140 ++++++++++ pd/portaudio_v18/pa_tests/debug_srate.c | 265 ++++++++++++++++++ pd/portaudio_v18/pa_tests/debug_test1.c | 114 ++++++++ pd/portaudio_v18/pa_tests/pa_devs.c | 99 +++++++ pd/portaudio_v18/pa_tests/pa_fuzz.c | 156 +++++++++++ pd/portaudio_v18/pa_tests/pa_minlat.c | 172 ++++++++++++ pd/portaudio_v18/pa_tests/paqa_devs.c | 322 ++++++++++++++++++++++ pd/portaudio_v18/pa_tests/paqa_errs.c | 330 ++++++++++++++++++++++ pd/portaudio_v18/pa_tests/patest1.c | 114 ++++++++ pd/portaudio_v18/pa_tests/patest_buffer.c | 180 ++++++++++++ pd/portaudio_v18/pa_tests/patest_clip.c | 156 +++++++++++ pd/portaudio_v18/pa_tests/patest_dither.c | 152 ++++++++++ pd/portaudio_v18/pa_tests/patest_hang.c | 153 +++++++++++ pd/portaudio_v18/pa_tests/patest_latency.c | 176 ++++++++++++ pd/portaudio_v18/pa_tests/patest_leftright.c | 168 ++++++++++++ pd/portaudio_v18/pa_tests/patest_longsine.c | 137 +++++++++ pd/portaudio_v18/pa_tests/patest_many.c | 195 +++++++++++++ pd/portaudio_v18/pa_tests/patest_maxsines.c | 201 ++++++++++++++ pd/portaudio_v18/pa_tests/patest_mono.c | 136 +++++++++ pd/portaudio_v18/pa_tests/patest_multi_sine.c | 144 ++++++++++ pd/portaudio_v18/pa_tests/patest_pink.c | 245 +++++++++++++++++ pd/portaudio_v18/pa_tests/patest_record.c | 325 ++++++++++++++++++++++ pd/portaudio_v18/pa_tests/patest_ringmix.c | 41 +++ pd/portaudio_v18/pa_tests/patest_saw.c | 118 ++++++++ pd/portaudio_v18/pa_tests/patest_sine.c | 141 ++++++++++ pd/portaudio_v18/pa_tests/patest_sine8.c | 184 +++++++++++++ pd/portaudio_v18/pa_tests/patest_sine_formats.c | 203 ++++++++++++++ pd/portaudio_v18/pa_tests/patest_sine_time.c | 205 ++++++++++++++ pd/portaudio_v18/pa_tests/patest_stop.c | 285 +++++++++++++++++++ pd/portaudio_v18/pa_tests/patest_sync.c | 227 +++++++++++++++ pd/portaudio_v18/pa_tests/patest_toomanysines.c | 175 ++++++++++++ pd/portaudio_v18/pa_tests/patest_two_rates.c | 168 ++++++++++++ pd/portaudio_v18/pa_tests/patest_underflow.c | 151 ++++++++++ pd/portaudio_v18/pa_tests/patest_wire.c | 176 ++++++++++++ 44 files changed, 8098 insertions(+) create mode 100644 pd/portaudio_v18/pa_tests/debug_convert.c create mode 100644 pd/portaudio_v18/pa_tests/debug_dither_calc.c create mode 100644 pd/portaudio_v18/pa_tests/debug_dual.c create mode 100644 pd/portaudio_v18/pa_tests/debug_multi_in.c create mode 100644 pd/portaudio_v18/pa_tests/debug_multi_out.c create mode 100644 pd/portaudio_v18/pa_tests/debug_record.c create mode 100644 pd/portaudio_v18/pa_tests/debug_record_reuse.c create mode 100644 pd/portaudio_v18/pa_tests/debug_sine.c create mode 100644 pd/portaudio_v18/pa_tests/debug_sine_amp.c create mode 100644 pd/portaudio_v18/pa_tests/debug_sine_formats.c create mode 100644 pd/portaudio_v18/pa_tests/debug_sine_getchar.c create mode 100644 pd/portaudio_v18/pa_tests/debug_srate.c create mode 100644 pd/portaudio_v18/pa_tests/debug_test1.c create mode 100644 pd/portaudio_v18/pa_tests/pa_devs.c create mode 100644 pd/portaudio_v18/pa_tests/pa_fuzz.c create mode 100644 pd/portaudio_v18/pa_tests/pa_minlat.c create mode 100644 pd/portaudio_v18/pa_tests/paqa_devs.c create mode 100644 pd/portaudio_v18/pa_tests/paqa_errs.c create mode 100644 pd/portaudio_v18/pa_tests/patest1.c create mode 100644 pd/portaudio_v18/pa_tests/patest_buffer.c create mode 100644 pd/portaudio_v18/pa_tests/patest_clip.c create mode 100644 pd/portaudio_v18/pa_tests/patest_dither.c create mode 100644 pd/portaudio_v18/pa_tests/patest_hang.c create mode 100644 pd/portaudio_v18/pa_tests/patest_latency.c create mode 100644 pd/portaudio_v18/pa_tests/patest_leftright.c create mode 100644 pd/portaudio_v18/pa_tests/patest_longsine.c create mode 100644 pd/portaudio_v18/pa_tests/patest_many.c create mode 100644 pd/portaudio_v18/pa_tests/patest_maxsines.c create mode 100644 pd/portaudio_v18/pa_tests/patest_mono.c create mode 100644 pd/portaudio_v18/pa_tests/patest_multi_sine.c create mode 100644 pd/portaudio_v18/pa_tests/patest_pink.c create mode 100644 pd/portaudio_v18/pa_tests/patest_record.c create mode 100644 pd/portaudio_v18/pa_tests/patest_ringmix.c create mode 100644 pd/portaudio_v18/pa_tests/patest_saw.c create mode 100644 pd/portaudio_v18/pa_tests/patest_sine.c create mode 100644 pd/portaudio_v18/pa_tests/patest_sine8.c create mode 100644 pd/portaudio_v18/pa_tests/patest_sine_formats.c create mode 100644 pd/portaudio_v18/pa_tests/patest_sine_time.c create mode 100644 pd/portaudio_v18/pa_tests/patest_stop.c create mode 100644 pd/portaudio_v18/pa_tests/patest_sync.c create mode 100644 pd/portaudio_v18/pa_tests/patest_toomanysines.c create mode 100644 pd/portaudio_v18/pa_tests/patest_two_rates.c create mode 100644 pd/portaudio_v18/pa_tests/patest_underflow.c create mode 100644 pd/portaudio_v18/pa_tests/patest_wire.c (limited to 'pd/portaudio_v18/pa_tests') diff --git a/pd/portaudio_v18/pa_tests/debug_convert.c b/pd/portaudio_v18/pa_tests/debug_convert.c new file mode 100644 index 00000000..11d25d9a --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_convert.c @@ -0,0 +1,131 @@ +/* + * $Id: debug_convert.c,v 1.1 2002/03/21 00:44:35 philburk Exp $ + * Convert tagged values. + * + * Author: Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +//#define OUTPUT_DEVICE (11) +#define NUM_SECONDS (8) +#define SLEEP_DUR (800) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) + +#define NUM_BUFFERS (0) + +typedef struct +{ + unsigned int framesToGo; +} +paTestData; +/* This routine will be called by the PortAudio engine when audio is needed. +** It may called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + short *out = (short*)outputBuffer; + int i; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + if( data->framesToGo < framesPerBuffer ) finished = 1; + + for( i=0; i +#include +#include "portaudio.h" +#include "pa_host.h" + +/*******************************************************************/ +int main(void); +int main(void) +{ + long max,min; + int i; + + for( i=0; i<10000; i++ ) + { + long dither = PaConvert_TriangularDither(); + // printf("dither = 0x%08X\n", dither ); + if( dither < min ) min = dither; + else if( dither > max ) max = dither; + } + printf("min = 0x%08X = %d, max = 0x%08X = %d\n", min, min, max, max ); +} diff --git a/pd/portaudio_v18/pa_tests/debug_dual.c b/pd/portaudio_v18/pa_tests/debug_dual.c new file mode 100644 index 00000000..bdb3c413 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_dual.c @@ -0,0 +1,183 @@ +/* + * $Id: debug_dual.c,v 1.1.1.1 2002/01/22 00:52:27 phil Exp $ + * debug_dual.c + * Try to open TWO streams on separate cards. + * Play a sine sweep using the Portable Audio api for several seconds. + * Hacked test for debugging PA. + * + * Author: Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +#define DEV_ID_1 (13) +#define DEV_ID_2 (15) +#define NUM_SECONDS (8) +#define SLEEP_DUR (800) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) +#if 0 +#define MIN_LATENCY_MSEC (200) +#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) +#else +#define NUM_BUFFERS (0) +#endif +#define MIN_FREQ (100.0f) +#define MAX_FREQ (4000.0f) +#define FREQ_SCALAR (1.00002f) +#define CalcPhaseIncrement(freq) (freq/SAMPLE_RATE) +#ifndef M_PI +#define M_PI (3.14159265) +#endif +#define TABLE_SIZE (400) +typedef struct +{ + float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation + float phase_increment; + float left_phase; + float right_phase; +} +paTestData; +/* Convert phase between and 1.0 to sine value + * using linear interpolation. + */ +float LookupSine( paTestData *data, float phase ); +float LookupSine( paTestData *data, float phase ) +{ + float fIndex = phase*TABLE_SIZE; + int index = (int) fIndex; + float fract = fIndex - index; + float lo = data->sine[index]; + float hi = data->sine[index+1]; + float val = lo + fract*(hi-lo); + return val; +} +/* This routine will be called by the PortAudio engine when audio is needed. +** It may called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + unsigned long i; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + + for( i=0; ileft_phase); /* left */ + *out++ = LookupSine(data, data->right_phase); /* right */ + data->left_phase += data->phase_increment; + if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; + data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ + if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; + /* sweep frequency then start over. */ + data->phase_increment *= FREQ_SCALAR; + if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ); + } + return 0; +} + +PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID, + paTestData *data ); +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream1, *stream2; + PaError err; + paTestData DATA1, DATA2; + printf("PortAudio Test: DUAL sine sweep. ask for %d buffers\n", NUM_BUFFERS ); + err = Pa_Initialize(); + if( err != paNoError ) goto error; + err = TestStart( &stream1, DEV_ID_1, &DATA1 ); + if( err != paNoError ) goto error; + err = TestStart( &stream2, DEV_ID_2, &DATA2 ); + if( err != paNoError ) goto error; + printf("Hit ENTER\n"); + getchar(); + err = Pa_StopStream( stream1 ); + if( err != paNoError ) goto error; + err = Pa_StopStream( stream2 ); + if( err != paNoError ) goto error; + Pa_Terminate(); + printf("Test finished.\n"); + return err; +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return err; +} +PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID, paTestData *data ) +{ + PortAudioStream *stream; + PaError err; + int i; + /* initialise sinusoidal wavetable */ + for( i=0; isine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ); + } + data->sine[TABLE_SIZE] = data->sine[0]; // set guard point + data->left_phase = data->right_phase = 0.0; + data->phase_increment = CalcPhaseIncrement(MIN_FREQ); + printf("PortAudio Test: output device = %d\n", devID ); + err = Pa_OpenStream( + &stream, + paNoDevice, + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + devID, + 2, /* stereo output */ + paFloat32, /* 32 bit floating point output */ + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, + NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ + paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + data ); + if( err != paNoError ) goto error; + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + *streamPtr = stream; + return 0; +error: + return err; +} diff --git a/pd/portaudio_v18/pa_tests/debug_multi_in.c b/pd/portaudio_v18/pa_tests/debug_multi_in.c new file mode 100644 index 00000000..9e376ce1 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_multi_in.c @@ -0,0 +1,187 @@ +/* + * $Id: debug_multi_in.c,v 1.1.1.1.4.3 2003/04/16 19:07:56 philburk Exp $ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include +#include "portaudio.h" +//#define INPUT_DEVICE_NAME ("EWS88 MT Interleaved Rec") +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +//#define OUTPUT_DEVICE (18) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) +#define MIN_LATENCY_MSEC (400) +#define MAX_INPUT_CHANNELS (9999) +#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; + (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 stereo output. */ + *out++ = in[data->liveChannel]; + *out++ = in[data->liveChannel]; + in += data->numChannels; + } + return 0; +} +/*******************************************************************/ +int PaFindDeviceByName( const char *name ) +{ + int i; + int numDevices; + const PaDeviceInfo *pdi; + int len = strlen( name ); + PaDeviceID result = paNoDevice; + numDevices = Pa_CountDevices(); + for( i=0; iname, len ) == 0 ) + { + result = i; + break; + } + } + return result; +} +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + PaDeviceID inputDevice; + const PaDeviceInfo *pdi; + printf("PortAudio Test: input signal from each channel. %d buffers\n", NUM_BUFFERS ); + data.liveChannel = 0; + err = Pa_Initialize(); + if( err != paNoError ) goto error; +#ifdef INPUT_DEVICE_NAME + printf("Try to use device: %s\n", INPUT_DEVICE_NAME ); + inputDevice = PaFindDeviceByName(INPUT_DEVICE_NAME); + if( inputDevice == paNoDevice ) + { + printf("Could not find %s. Using default instead.\n", INPUT_DEVICE_NAME ); + inputDevice = Pa_GetDefaultInputDeviceID(); + } +#else + printf("Using default input device.\n"); + inputDevice = Pa_GetDefaultInputDeviceID(); +#endif + pdi = Pa_GetDeviceInfo( inputDevice ); + if( pdi == NULL ) + { + printf("Could not get device info!\n"); + goto error; + } + printf("Input Device name is %s\n", pdi->name ); + printf("Input Device has %d channels.\n", pdi->maxInputChannels); + if( pdi->maxInputChannels <= MAX_INPUT_CHANNELS ) + { + data.numChannels = pdi->maxInputChannels; + } + else + { + data.numChannels = MAX_INPUT_CHANNELS; + printf("Only use %d channels.\n", MAX_INPUT_CHANNELS ); + } + err = Pa_OpenStream( + &stream, + inputDevice, + data.numChannels, + paFloat32, /* 32 bit floating point input */ + NULL, + OUTPUT_DEVICE, + 2, + paFloat32, /* 32 bit floating point output */ + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + NUM_BUFFERS, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + &data ); + if( err != paNoError ) goto error; + data.liveChannel = 0; + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + for( i=0; i +#include +#include "portaudio.h" + +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) +#define FREQ_INCR (300.0 / SAMPLE_RATE) +#define MAX_CHANNELS (64) + +#ifndef M_PI +#define M_PI (3.14159265) +#endif + +typedef struct +{ + int numChannels; +} +paTestData; + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + int frameIndex, channelIndex; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) + { + for( channelIndex=0; channelIndexnumChannels; channelIndex++ ) + { + /* Output sine wave on every channel. */ + *out++ = (float) ((channelIndex + 1) * 0.1); + } + } + + return 0; +} +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + const PaDeviceInfo *pdi; + paTestData data = {0}; + printf("PortAudio Test: output channel number on each channel.\n" ); + + err = Pa_Initialize(); + if( err != paNoError ) goto error; + + pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); + data.numChannels = pdi->maxOutputChannels; + if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; + printf("Number of Channels = %d\n", data.numChannels ); + + err = Pa_OpenStream( + &stream, + paNoDevice, /* default input device */ + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + OUTPUT_DEVICE, + data.numChannels, + paFloat32, /* 32 bit floating point output */ + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + 0, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + &data ); + if( err != paNoError ) goto error; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + printf("Hit ENTER to stop sound.\n"); + fflush(stdout); + getchar(); + + err = Pa_StopStream( stream ); + if( err != paNoError ) goto error; + + Pa_CloseStream( stream ); + Pa_Terminate(); + printf("Test finished.\n"); + return err; +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return err; +} diff --git a/pd/portaudio_v18/pa_tests/debug_record.c b/pd/portaudio_v18/pa_tests/debug_record.c new file mode 100644 index 00000000..f9359254 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_record.c @@ -0,0 +1,338 @@ +/* + * $Id: debug_record.c,v 1.3.4.3 2003/03/06 06:09:20 philburk Exp $ + * patest_record.c + * Record input into an array. + * Save array to a file. + * Playback recorded data. + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" + +#define SAMPLE_RATE (44100) +#define NUM_SECONDS (6) +#define NUM_CHANNELS (2) +#define FRAMES_PER_BUFFER (64) +/* #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) + +#elif 0 +#define PA_SAMPLE_TYPE paInt32 +typedef long SAMPLE; +#define SAMPLE_SILENCE (0) + +#elif 0 +#define PA_SAMPLE_TYPE paInt16 +typedef short SAMPLE; +#define SAMPLE_SILENCE (0) + +#elif 0 +#define PA_SAMPLE_TYPE paInt8 +typedef char SAMPLE; +#define SAMPLE_SILENCE (0) + +#else +#define PA_SAMPLE_TYPE paUInt8 +typedef unsigned char SAMPLE; +#define SAMPLE_SILENCE (128) + +#endif + +typedef struct +{ + int frameIndex; /* Index into sample array. */ + int maxFrameIndex; + SAMPLE *recordedSamples; +} +paTestData; +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int recordCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + SAMPLE *rptr = (SAMPLE*)inputBuffer; + SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS]; + long framesToCalc; + long i; + int finished; + unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; + + (void) outputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + + if( framesLeft < framesPerBuffer ) + { + framesToCalc = framesLeft; + finished = 1; + } + else + { + framesToCalc = framesPerBuffer; + finished = 0; + } + if( inputBuffer == NULL ) + { + for( i=0; iframeIndex += framesToCalc; + return finished; +} + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int playCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS]; + SAMPLE *wptr = (SAMPLE*)outputBuffer; + unsigned int i; + int finished; + unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; + (void) inputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + + if( framesLeft < framesPerBuffer ) + { + /* final buffer... */ + for( i=0; iframeIndex += framesLeft; + finished = 1; + } + else + { + for( i=0; iframeIndex += framesPerBuffer; + finished = 0; + } + return finished; +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + int totalFrames; + int numSamples; + int numBytes; + SAMPLE max, average, val; + + printf("debug_record.c, sampleRate = %d, numChannels = %d\n", + SAMPLE_RATE, NUM_CHANNELS ); + 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 ); + if( data.recordedSamples == NULL ) + { + printf("Could not allocate record array.\n"); + exit(1); + } + for( i=0; i max ) + { + max = val; + } + average += val; + } + + average = average / numSamples; + + if( PA_SAMPLE_TYPE == paFloat32 ) + { + printf("sample max amplitude = %f\n", (double) max ); + printf("sample average = %f\n", (double) average ); + } + else + { + printf("sample max amplitude = %d\n", (int) max ); + printf("sample average = %d\n", (int) 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; + printf("Begin playback.\n"); fflush(stdout); + err = Pa_OpenStream( + &stream, + paNoDevice, + 0, /* NO input */ + PA_SAMPLE_TYPE, + NULL, + Pa_GetDefaultOutputDeviceID(), + NUM_CHANNELS, /* 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, + &data ); + if( err != paNoError ) goto error; + + if( stream ) + { + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + printf("Start playback!!\n"); fflush(stdout); + + while( Pa_StreamActive( stream ) ) + { + Pa_Sleep(1000); + printf("index = %d\n", data.frameIndex ); fflush(stdout); + } + + printf("Stop playback!!\n"); fflush(stdout); + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + printf("Done.\n"); fflush(stdout); + } + 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 ) ); + return -1; +} diff --git a/pd/portaudio_v18/pa_tests/debug_record_reuse.c b/pd/portaudio_v18/pa_tests/debug_record_reuse.c new file mode 100644 index 00000000..e0670009 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_record_reuse.c @@ -0,0 +1,351 @@ +/* + * $Id: debug_record_reuse.c,v 1.1 2002/05/02 20:16:29 philburk Exp $ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include +#include "portaudio.h" +#define SAMPLE_RATE (22050) +#define NUM_SECONDS (4) +#define SLEEP_DUR_MSEC (200) +#define FRAMES_PER_BUFFER (256) +#define NUM_REC_BUFS (0) + +#if 1 +#define PA_SAMPLE_TYPE paFloat32 +typedef float SAMPLE; +#else +#define PA_SAMPLE_TYPE paInt16 +typedef short SAMPLE; +#endif + +typedef struct +{ + long frameIndex; /* Index into sample array. */ + long maxFrameIndex; + long samplesPerFrame; + long numSamples; + PortAudioStream *outputStream; + PortAudioStream *inputStream; + SAMPLE *recordedSamples; +} +paTestData; + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int recordCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + SAMPLE *rptr = (SAMPLE*)inputBuffer; + SAMPLE *wptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame]; + long framesToCalc; + unsigned long i; + int finished; + unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; + + (void) outputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + + if( framesLeft < framesPerBuffer ) + { + framesToCalc = framesLeft; + finished = 1; + } + else + { + framesToCalc = framesPerBuffer; + finished = 0; + } + if( inputBuffer == NULL ) + { + for( i=0; iframeIndex += framesToCalc; + return finished; +} + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int playCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + SAMPLE *rptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame]; + SAMPLE *wptr = (SAMPLE*)outputBuffer; + unsigned long i; + int finished; + unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; + if( outputBuffer == NULL ) return 0; + (void) inputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + + if( framesLeft < framesPerBuffer ) + { + /* final buffer... */ + for( i=0; iframeIndex += framesLeft; + finished = 1; + } + else + { + for( i=0; iframeIndex += framesPerBuffer; + finished = 0; + } + return finished; +} + +/****************************************************************/ +PaError TestRecording( paTestData *dataPtr ) +{ + PaError err; + int i; + int lastIndex = 0; + +/* Open input stream if not already open. */ + if( dataPtr->inputStream == NULL ) + { + /* Record some audio. */ + err = Pa_OpenStream( + &dataPtr->inputStream, + Pa_GetDefaultInputDeviceID(), + dataPtr->samplesPerFrame, /* stereo input */ + PA_SAMPLE_TYPE, + NULL, + paNoDevice, + 0, + PA_SAMPLE_TYPE, + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + recordCallback, + dataPtr ); + if( err != paNoError ) goto error; + } + + dataPtr->frameIndex = 0; + + err = Pa_StartStream( dataPtr->inputStream ); + if( err != paNoError ) goto error; + + printf("Now recording!\n"); fflush(stdout); + for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) + { + int frameIndex, delta; + Pa_Sleep(SLEEP_DUR_MSEC); + + frameIndex = dataPtr->frameIndex; + if( Pa_StreamActive( dataPtr->inputStream ) <= 0) + { + printf("Stream inactive!\n"); + break; + } + if( dataPtr->maxFrameIndex <= frameIndex ) + { + printf("Buffer recording complete.\n"); + break; + } + + delta = frameIndex - lastIndex; + lastIndex = frameIndex; + printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout); + } + + err = Pa_StopStream( dataPtr->inputStream ); + if( err != paNoError ) goto error; + + printf("Done.\n"); fflush(stdout); + +error: + return err; +} + +/****************************************************************/ +PaError TestPlayback( paTestData *dataPtr ) +{ + PaError err; + int i; + int lastIndex = 0; + + /* Playback recorded data. */ + dataPtr->frameIndex = 0; + printf("Begin playback.\n"); fflush(stdout); + +/* Open output stream if not already open. */ + if( dataPtr->outputStream == NULL ) + { + err = Pa_OpenStream( + &dataPtr->outputStream, + paNoDevice, + 0, /* NO input */ + PA_SAMPLE_TYPE, + NULL, + Pa_GetDefaultOutputDeviceID(), + dataPtr->samplesPerFrame, /* stereo output */ + PA_SAMPLE_TYPE, + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + 0, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + playCallback, + dataPtr ); + if( err != paNoError ) goto error; + } + + err = Pa_StartStream( dataPtr->outputStream ); + if( err != paNoError ) goto error; + + printf("Waiting for playback to finish.\n"); fflush(stdout); + for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) + { + int frameIndex, delta; + Pa_Sleep(SLEEP_DUR_MSEC); + frameIndex = dataPtr->frameIndex; + delta = frameIndex - lastIndex; + lastIndex = frameIndex; + printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout); + } + + err = Pa_StopStream( dataPtr->outputStream ); + if( err != paNoError ) goto error; + +error: + return err; +} +/*******************************************************************/ +int main(void); +int main(void) +{ + PaError err; + paTestData data = { 0 }; + long totalFrames; + long numBytes; + long i; + printf("patest_record.c\n"); fflush(stdout); + +/* Set up test data structure and sample array. */ + data.frameIndex = 0; + data.samplesPerFrame = 2; + data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE; + + printf("totalFrames = %d\n", totalFrames ); fflush(stdout); + data.numSamples = totalFrames * data.samplesPerFrame; + + numBytes = data.numSamples * sizeof(SAMPLE); + data.recordedSamples = (SAMPLE *) malloc( numBytes ); + if( data.recordedSamples == NULL ) + { + printf("Could not allocate record array.\n"); + exit(1); + } + for( i=0; i + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +//#define OUTPUT_DEVICE (11) +#define NUM_SECONDS (8) +#define SLEEP_DUR (800) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) + +#define MSEC_PER_BUFFER (1000 * FRAMES_PER_BUFFER / SAMPLE_RATE) + +#if 0 +#define MIN_LATENCY_MSEC (200) +#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) +#else +#define NUM_BUFFERS (0) +#endif + +#define MIN_FREQ (100.0f) +#define MAX_FREQ (4000.0f) +#define FREQ_SCALAR (1.00002f) +#define CalcPhaseIncrement(freq) (freq/SAMPLE_RATE) +#ifndef M_PI +#define M_PI (3.14159265) +#endif +#define TABLE_SIZE (400) +typedef struct +{ + float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation + float phase_increment; + float left_phase; + float right_phase; + unsigned int framesToGo; +} +paTestData; +/* Convert phase between and 1.0 to sine value + * using linear interpolation. + */ +float LookupSine( paTestData *data, float phase ); +float LookupSine( paTestData *data, float phase ) +{ + float fIndex = phase*TABLE_SIZE; + int index = (int) fIndex; + float fract = fIndex - index; + float lo = data->sine[index]; + float hi = data->sine[index+1]; + float val = lo + fract*(hi-lo); + return val; +} +/* This routine will be called by the PortAudio engine when audio is needed. +** It may called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + int framesToCalc; + int i; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + if( data->framesToGo < framesPerBuffer ) + { + framesToCalc = data->framesToGo; + data->framesToGo = 0; + finished = 1; + } + else + { + framesToCalc = framesPerBuffer; + data->framesToGo -= framesPerBuffer; + } + + for( i=0; ileft_phase); /* left */ + *out++ = LookupSine(data, data->right_phase); /* right */ + data->left_phase += data->phase_increment; + if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; + data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ + if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; + /* sweep frequency then start over. */ + data->phase_increment *= FREQ_SCALAR; + if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ); + } + /* zero remainder of final buffer */ + for( ; i<(int)framesPerBuffer; i++ ) + { + *out++ = 0; /* left */ + *out++ = 0; /* right */ + } + // Pa_Sleep( 3 * MSEC_PER_BUFFER / 4 ); + // Pa_Sleep( MSEC_PER_BUFFER / 3 ); + + 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 ); + printf("MSEC_PER_BUFFER = %d\n", MSEC_PER_BUFFER ); + + /* initialise sinusoidal wavetable */ + for( i=0; i +#include +#include "portaudio.h" + +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) +#define FREQ_INCR (300.0 / SAMPLE_RATE) +#define MAX_CHANNELS (64) + +#ifndef M_PI +#define M_PI (3.14159265) +#endif + +typedef struct +{ + int numChannels; + double phases[MAX_CHANNELS]; + float amplitude; +} +paTestData; + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + int frameIndex, channelIndex; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) + { + for( channelIndex=0; channelIndexnumChannels; channelIndex++ ) + { + /* Output sine wave on every channel. */ + *out++ = (float) ( data->amplitude * sin(data->phases[channelIndex]) ); + + /* Play each channel at a higher frequency. */ + data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); + if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); + } + } + + return 0; +} +/*******************************************************************/ +int main(void); +int main(void) +{ + char pad[256]; + PortAudioStream *stream; + PaError err; + const PaDeviceInfo *pdi; + paTestData data = {0}; + printf("PortAudio Test: output sine wave on each channel.\n" ); + + err = Pa_Initialize(); + if( err != paNoError ) goto error; + + pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); + data.numChannels = pdi->maxOutputChannels; + if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; + printf("Number of Channels = %d\n", data.numChannels ); + data.amplitude = 1.0; + + err = Pa_OpenStream( + &stream, + paNoDevice, /* default input device */ + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + OUTPUT_DEVICE, + data.numChannels, + paFloat32, /* 32 bit floating point output */ + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + 0, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + &data ); + if( err != paNoError ) goto error; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + do + { + printf("Current amplitude = %f\n", data.amplitude ); + printf("Enter new amplitude or 'q' to quit.\n"); + fflush(stdout); + gets( pad ); + if( pad[0] != 'q' ) + { + // I tried to use atof but it seems to be broken on Mac OS X 10.1 + float amp; + sscanf( pad, "%f", & ); + data.amplitude = amp; + } + } while( pad[0] != 'q' ); + + err = Pa_StopStream( stream ); + if( err != paNoError ) goto error; + + Pa_CloseStream( stream ); + Pa_Terminate(); + printf("Test finished.\n"); + return err; +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return err; +} diff --git a/pd/portaudio_v18/pa_tests/debug_sine_formats.c b/pd/portaudio_v18/pa_tests/debug_sine_formats.c new file mode 100644 index 00000000..c331dde3 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_sine_formats.c @@ -0,0 +1,202 @@ +/* + * $Id: debug_sine_formats.c,v 1.1 2002/03/21 00:44:35 philburk Exp $ + * 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.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" + +#define NUM_SECONDS (10) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) + +#define LEFT_FREQ (SAMPLE_RATE/512.0) /* So we hit 1.0 */ +#define RIGHT_FREQ (500.0) + +#define AMPLITUDE (1.0) + +/* Select ONE format for testing. */ +#define TEST_UINT8 (1) +#define TEST_INT8 (0) +#define TEST_INT16 (0) +#define TEST_FLOAT32 (0) + +#if TEST_UINT8 +#define TEST_FORMAT paUInt8 +typedef unsigned char SAMPLE_t; +#define SAMPLE_ZERO (0x80) +#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) +#define FORMAT_NAME "Unsigned 8 Bit" + +#elif TEST_INT8 +#define TEST_FORMAT paInt8 +typedef char SAMPLE_t; +#define SAMPLE_ZERO (0) +#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x))) +#define FORMAT_NAME "Signed 8 Bit" + +#elif TEST_INT16 +#define TEST_FORMAT paInt16 +typedef short SAMPLE_t; +#define SAMPLE_ZERO (0) +#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x))) +#define FORMAT_NAME "Signed 16 Bit" + +#elif TEST_FLOAT32 +#define TEST_FORMAT paFloat32 +typedef float SAMPLE_t; +#define SAMPLE_ZERO (0.0) +#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x)) +#define FORMAT_NAME "Float 32 Bit" +#endif + +#ifndef M_PI +#define M_PI (3.14159265) +#endif + + +typedef struct +{ + double left_phase; + double right_phase; + unsigned int framesToGo; +} +paTestData; +/* This routine will be called by the PortAudio engine when audio is needed. +** It may called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + SAMPLE_t *out = (SAMPLE_t *)outputBuffer; + SAMPLE_t sample; + int i; + int framesToCalc; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + if( data->framesToGo < framesPerBuffer ) + { + framesToCalc = data->framesToGo; + data->framesToGo = 0; + finished = 1; + } + else + { + framesToCalc = framesPerBuffer; + data->framesToGo -= framesPerBuffer; + } + + for( i=0; ileft_phase += (LEFT_FREQ / SAMPLE_RATE); + if( data->left_phase > 1.0) data->left_phase -= 1.0; + sample = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. ))); /**/ + *out++ = sample; +/* *out++ = sample; /**/ +/* *out++ = 0; /**/ + + data->right_phase += (RIGHT_FREQ / SAMPLE_RATE); + if( data->right_phase > 1.0) data->right_phase -= 1.0; + *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. ))); /**/ +/* *out++ = 0; /* */ + } + /* zero remainder of final buffer */ + for( ; i<(int)framesPerBuffer; i++ ) + { + *out++ = SAMPLE_ZERO; /* left */ + *out++ = SAMPLE_ZERO; /* right */ + } + return finished; +} +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int totalSamps; + + printf("PortAudio Test: output " FORMAT_NAME "\n"); + + + data.left_phase = data.right_phase = 0.0; + data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */ + err = Pa_Initialize(); + if( err != paNoError ) goto error; + + err = Pa_OpenStream( + &stream, + paNoDevice,/* default input device */ + 0, /* no input */ + TEST_FORMAT, + NULL, + Pa_GetDefaultOutputDeviceID(), /* default output device */ + 2, /* stereo output */ + TEST_FORMAT, + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, + 0, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + &data ); + if( err != paNoError ) goto error; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS ); + while( Pa_StreamActive( stream ) ) Pa_Sleep(10); + + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + Pa_Terminate(); + + printf("PortAudio Test Finished: " FORMAT_NAME "\n"); + + return err; +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return err; +} diff --git a/pd/portaudio_v18/pa_tests/debug_sine_getchar.c b/pd/portaudio_v18/pa_tests/debug_sine_getchar.c new file mode 100644 index 00000000..54c0cba5 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_sine_getchar.c @@ -0,0 +1,140 @@ +/* + * $Id: debug_sine_getchar.c,v 1.1.2.2 2003/04/10 23:09:40 philburk Exp $ + * + * Play a sine wave using the Portable Audio api until ENTER hit. + * + * Authors: + * Ross Bencina + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" + +#define SAMPLE_RATE (48000) +#define AMPLITUDE (0.3) +#define FRAMES_PER_BUFFER (64) +#define OUTPUT_DEVICE Pa_GetDefaultOutputDeviceID() +//#define OUTPUT_DEVICE (2) + +#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( 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; isine[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 finished; +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d, devID = %d\n", + SAMPLE_RATE, FRAMES_PER_BUFFER, OUTPUT_DEVICE); + /* initialise sinusoidal wavetable */ + for( i=0; i +#include +#include +#include "portaudio.h" + +#define EWS88MT_12_REC (1) +#define EWS88MT_12_PLAY (10) +#define SBLIVE_REC (2) +#define SBLIVE_PLAY (11) + +#if 0 +#define INPUT_DEVICE_ID Pa_GetDefaultInputDeviceID() +#define OUTPUT_DEVICE_ID Pa_GetDefaultOutputDeviceID() +#else +#define INPUT_DEVICE_ID (EWS88MT_12_REC) +#define OUTPUT_DEVICE_ID (SBLIVE_PLAY) +#endif + +#define INPUT_SAMPLE_RATE (22050.0) +#define OUTPUT_SAMPLE_RATE (22050.0) +#define NUM_SECONDS (4) +#define SLEEP_DUR_MSEC (1000) +#define FRAMES_PER_BUFFER (64) +#define NUM_REC_BUFS (0) +#define SAMPLES_PER_FRAME (2) + +#define PA_SAMPLE_TYPE paInt16 +typedef short SAMPLE; + +typedef struct +{ + long frameIndex; /* Index into sample array. */ +} +paTestData; + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int recordCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData *) userData; + (void) outputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + + if( inputBuffer != NULL ) + { + data->frameIndex += framesPerBuffer; + } + return 0; +} + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int playCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData *) userData; + (void) inputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + + if( outputBuffer != NULL ) + { + data->frameIndex += framesPerBuffer; + } + return 0; +} + +/****************************************************************/ +PaError MeasureStreamRate( PortAudioStream *stream, paTestData *dataPtr, double *ratePtr ) +{ + PaError err; + int i; + int totalFrames = 0; + int totalMSec = 0; + + dataPtr->frameIndex = 0; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ ) + { + int delta, endIndex; + + int startIndex = dataPtr->frameIndex; + Pa_Sleep(SLEEP_DUR_MSEC); + endIndex = dataPtr->frameIndex; + + delta = endIndex - startIndex; + totalFrames += delta; + totalMSec += SLEEP_DUR_MSEC; + + printf("index = %d, delta = %d\n", endIndex, delta ); fflush(stdout); + } + + err = Pa_StopStream( stream ); + if( err != paNoError ) goto error; + + *ratePtr = (totalFrames * 1000.0) / totalMSec; + +error: + return err; +} + +void ReportRate( double measuredRate, double expectedRate ) +{ + double error; + + error = (measuredRate - expectedRate) / expectedRate; + error = (error < 0 ) ? -error : error; + + printf("Measured rate = %6.1f, expected rate = %6.1f\n", + measuredRate, expectedRate ); + if( error > 0.1 ) + { + printf("ERROR: unexpected rate! --------------------- ERROR!\n"); + } + else + { + printf("SUCCESS: rate within tolerance!\n"); + } +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PaError err; + paTestData data = { 0 }; + long i; + double rate; + const PaDeviceInfo *pdi; + + PortAudioStream *outputStream; + PortAudioStream *inputStream; + + err = Pa_Initialize(); + if( err != paNoError ) goto error; + + + pdi = Pa_GetDeviceInfo( INPUT_DEVICE_ID ); + printf("Input device = %s\n", pdi->name ); + pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE_ID ); + printf("Output device = %s\n", pdi->name ); + +/* Open input stream. */ + err = Pa_OpenStream( + &inputStream, + INPUT_DEVICE_ID, + SAMPLES_PER_FRAME, /* stereo input */ + PA_SAMPLE_TYPE, + NULL, + paNoDevice, + 0, + PA_SAMPLE_TYPE, + NULL, + INPUT_SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + NUM_REC_BUFS, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + recordCallback, + &data ); + if( err != paNoError ) goto error; + + err = Pa_OpenStream( + &outputStream, + paNoDevice, + 0, /* NO input */ + PA_SAMPLE_TYPE, + NULL, + OUTPUT_DEVICE_ID, + SAMPLES_PER_FRAME, /* stereo output */ + PA_SAMPLE_TYPE, + NULL, + OUTPUT_SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + 0, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + playCallback, + &data ); + if( err != paNoError ) goto error; + +/* Record and playback multiple times. */ + for( i=0; i<2; i++ ) + { + printf("Measuring INPUT ------------------------- \n"); + err = MeasureStreamRate( inputStream, &data, &rate ); + if( err != paNoError ) goto error; + ReportRate( rate, INPUT_SAMPLE_RATE ); + + printf("Measuring OUTPUT ------------------------- \n"); + err = MeasureStreamRate( outputStream, &data, &rate ); + if( err != paNoError ) goto error; + ReportRate( rate, OUTPUT_SAMPLE_RATE ); + } + +/* Clean up. */ + err = Pa_CloseStream( inputStream ); + if( err != paNoError ) goto error; + + err = Pa_CloseStream( outputStream ); + if( err != paNoError ) goto error; + + if( err != paNoError ) goto error; + + Pa_Terminate(); + + printf("Test complete.\n"); fflush(stdout); + return 0; + +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + if( err == paHostError ) + { + fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() ); + } + return -1; +} diff --git a/pd/portaudio_v18/pa_tests/debug_test1.c b/pd/portaudio_v18/pa_tests/debug_test1.c new file mode 100644 index 00000000..187d0f5c --- /dev/null +++ b/pd/portaudio_v18/pa_tests/debug_test1.c @@ -0,0 +1,114 @@ +/* + * $Id: debug_test1.c,v 1.1.1.1 2002/01/22 00:52:30 phil Exp $ + patest1.c + Ring modulate the audio input with a 441hz sine wave for 20 seconds + using the Portable Audio api + Author: Ross Bencina + Modifications: + April 5th, 2001 - PLB - Check for NULL inputBuffer. +*/ +#include +#include +#include "portaudio.h" +#ifndef M_PI +#define M_PI (3.14159265) +#endif +typedef struct +{ + float sine[100]; + int phase; + int sampsToGo; +} +patest1data; +static int patest1Callback( void *inputBuffer, void *outputBuffer, + unsigned long bufferFrames, + PaTimestamp outTime, void *userData ) +{ + patest1data *data = (patest1data*)userData; + float *in = (float*)inputBuffer; + float *out = (float*)outputBuffer; + int framesToCalc = bufferFrames; + unsigned long i; + int finished = 0; + if(inputBuffer == NULL) return 0; + if( data->sampsToGo < bufferFrames ) + { + finished = 1; + } + for( i=0; iphase >= 100 ) + data->phase = 0; + } + data->sampsToGo -= bufferFrames; + /* zero remainder of final buffer if not already done */ + for( ; i +#include +#include "portaudio.h" + +/*******************************************************************/ +int main(void); +int main(void) +{ + int i,j; + int numDevices; + const PaDeviceInfo *pdi; + PaError err; + Pa_Initialize(); + numDevices = Pa_CountDevices(); + 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; iname ); + printf("Max Inputs = %d", pdi->maxInputChannels ); + printf(", Max Outputs = %d\n", pdi->maxOutputChannels ); + if( pdi->numSampleRates == -1 ) + { + printf("Sample Rate Range = %f to %f\n", pdi->sampleRates[0], pdi->sampleRates[1] ); + } + else + { + printf("Sample Rates ="); + for( j=0; jnumSampleRates; j++ ) + { + printf(" %8.2f,", pdi->sampleRates[j] ); + } + printf("\n"); + } + printf("Native Sample Formats = "); + if( pdi->nativeSampleFormats & paInt8 ) printf("paInt8, "); + if( pdi->nativeSampleFormats & paUInt8 ) printf("paUInt8, "); + if( pdi->nativeSampleFormats & paInt16 ) printf("paInt16, "); + if( pdi->nativeSampleFormats & paInt32 ) printf("paInt32, "); + if( pdi->nativeSampleFormats & paFloat32 ) printf("paFloat32, "); + if( pdi->nativeSampleFormats & paInt24 ) printf("paInt24, "); + if( pdi->nativeSampleFormats & paPackedInt24 ) printf("paPackedInt24, "); + printf("\n"); + } + 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; +} diff --git a/pd/portaudio_v18/pa_tests/pa_fuzz.c b/pd/portaudio_v18/pa_tests/pa_fuzz.c new file mode 100644 index 00000000..3f0cdb56 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/pa_fuzz.c @@ -0,0 +1,156 @@ +/* + * $Id: pa_fuzz.c,v 1.1.1.1.4.1 2003/02/11 21:41:32 philburk Exp $ + * pa_fuzz.c + * Distort input like a fuzz boz. + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + SAMPLE *out = (SAMPLE*)outputBuffer; + SAMPLE *in = (SAMPLE*)inputBuffer; + unsigned int i; + (void) outTime; /* Prevent unused variable warnings. */ + (void) userData; + + if( inputBuffer == NULL ) + { + for( i=0; i +#include +#include +#include "portaudio.h" + +#ifndef M_PI +#define M_PI (3.14159265) +#endif +#define TWOPI (M_PI * 2.0) + +#define DEFAULT_BUFFER_SIZE (64) + +typedef struct +{ + double left_phase; + double right_phase; +} +paTestData; + +/* Very simple synthesis routine to generate two sine waves. */ +static int paminlatCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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 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; +} +void main( int argc, char **argv ); +void main( int argc, char **argv ) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int go; + int numBuffers = 0; + int minBuffers = 0; + int framesPerBuffer; + double sampleRate = 44100.0; + char str[256]; + printf("paminlat - Determine minimum latency for your computer.\n"); + printf(" usage: paminlat {framesPerBuffer}\n"); + printf(" for example: paminlat 256\n"); + printf("Adjust your stereo until you hear a smooth tone in each speaker.\n"); + printf("Then try to find the smallest number of buffers 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; + /* Ask PortAudio for the recommended minimum number of buffers. */ + numBuffers = minBuffers = Pa_GetMinNumBuffers( framesPerBuffer, sampleRate ); + printf("NumBuffers set to %d based on a call to Pa_GetMinNumBuffers()\n", numBuffers ); + /* Try different numBuffers in a loop. */ + go = 1; + while( go ) + { + + printf("Latency = framesPerBuffer * numBuffers = %d * %d = %d frames = %d msecs.\n", + framesPerBuffer, numBuffers, framesPerBuffer*numBuffers, + (int)((1000 * framesPerBuffer * numBuffers) / sampleRate) ); + err = Pa_OpenStream( + &stream, + paNoDevice, + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + Pa_GetDefaultOutputDeviceID(), /* default output device */ + 2, /* stereo output */ + paFloat32, /* 32 bit floating point output */ + NULL, + sampleRate, + framesPerBuffer, + numBuffers, /* number of buffers */ + 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 number of buffers. */ + printf("\nMove windows around to see if the sound glitches.\n"); + printf("NumBuffers currently %d, enter new number, or 'q' to quit: ", numBuffers ); + gets( str ); + if( str[0] == 'q' ) go = 0; + else + { + numBuffers = atol( str ); + if( numBuffers < minBuffers ) + { + printf( "numBuffers below minimum of %d! Set to minimum!!!\n", minBuffers ); + numBuffers = minBuffers; + } + } + /* 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; +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 ) ); +} diff --git a/pd/portaudio_v18/pa_tests/paqa_devs.c b/pd/portaudio_v18/pa_tests/paqa_devs.c new file mode 100644 index 00000000..92eb6c7a --- /dev/null +++ b/pd/portaudio_v18/pa_tests/paqa_devs.c @@ -0,0 +1,322 @@ +/* + * $Id: paqa_devs.c,v 1.1.1.1.4.1 2003/02/11 21:41:32 philburk Exp $ + * paqa_devs.c + * 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 + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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, PaDeviceID deviceID, double sampleRate, + int numChannels ); +static int TestAdvance( int mode, PaDeviceID deviceID, double sampleRate, + int numChannels, PaSampleFormat format ); +static int QaCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + unsigned long i; + short phase; + PaQaData *data = (PaQaData *) userData; + (void) inputBuffer; + (void) outTime; + + /* Play simple sawtooth wave. */ + if( data->mode == MODE_OUTPUT ) + { + phase = data->sawPhase; + switch( data->format ) + { + case paFloat32: + { + float *out = (float *) outputBuffer; + for( i=0; inumChannels == 2 ) + { + *out++ = (float) (phase * (1.0 / 32768.0)); + } + } + } + break; + + case paInt32: + { + int *out = (int *) outputBuffer; + for( i=0; inumChannels == 2 ) + { + *out++ = ((int) phase ) << 16; + } + } + } + break; + case paInt16: + { + short *out = (short *) outputBuffer; + for( i=0; inumChannels == 2 ) + { + *out++ = phase; + } + } + } + break; + + default: + { + unsigned char *out = (unsigned char *) outputBuffer; + unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample; + for( i=0; isawPhase = phase; + } + /* Are we through yet? */ + if( data->framesLeft > framesPerBuffer ) + { + AddTraceMessage("QaCallback: running. framesLeft", data->framesLeft ); + data->framesLeft -= framesPerBuffer; + return 0; + } + else + { + 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 ); +} +/******************************************************************* +* Try each output device, through its full range of capabilities. */ +static void TestDevices( int mode ) +{ + int id,jc,kr; + int maxChannels; + const PaDeviceInfo *pdi; + int numDevices = Pa_CountDevices(); + /* Iterate through all devices. */ + for( id=0; idmaxInputChannels : pdi->maxOutputChannels; + for( jc=1; jc<=maxChannels; jc++ ) + { + printf("Name = %s\n", pdi->name ); + /* Try each legal sample rate. */ + if( pdi->numSampleRates == -1 ) + { + double low, high; + low = pdi->sampleRates[0]; + high = pdi->sampleRates[1]; + if( low < 8000.0 ) low = 8000.0; + TestFormats( mode, id, low, jc ); +#define TESTSR(sr) {if(((sr)>=low) && ((sr)<=high)) TestFormats( mode, id, (sr), jc ); } + + TESTSR(11025.0); + TESTSR(22050.0); + TESTSR(34567.0); + TESTSR(44100.0); + TestFormats( mode, id, high, jc ); + } + else + { + for( kr=0; krnumSampleRates; kr++ ) + { + TestFormats( mode, id, pdi->sampleRates[kr], jc ); + } + } + } + } +} +/*******************************************************************/ +static void TestFormats( int mode, PaDeviceID deviceID, double sampleRate, + int numChannels ) +{ + TestAdvance( mode, deviceID, sampleRate, numChannels, paFloat32 ); /* */ + TestAdvance( mode, deviceID, sampleRate, numChannels, paInt16 ); /* */ + TestAdvance( mode, deviceID, sampleRate, numChannels, paInt32 ); /* */ +} +/*******************************************************************/ +static int TestAdvance( int mode, PaDeviceID deviceID, double sampleRate, + int numChannels, PaSampleFormat format ) +{ + PortAudioStream *stream = NULL; + PaError result; + PaQaData myData; +#define FRAMES_PER_BUFFER (64) + printf("------ TestAdvance: %s, device = %d, rate = %g, numChannels = %d, format = %d -------\n", + ( mode == MODE_INPUT ) ? "INPUT" : "OUTPUT", + deviceID, sampleRate, numChannels, format); + fflush(stdout); + /* 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; + } + EXPECT( ((result = Pa_OpenStream( + &stream, + ( mode == MODE_INPUT ) ? deviceID : paNoDevice, + ( mode == MODE_INPUT ) ? numChannels : 0, + format, + NULL, + ( mode == MODE_OUTPUT ) ? deviceID : paNoDevice, + ( mode == MODE_OUTPUT ) ? numChannels : 0, + format, + NULL, + sampleRate, + 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 */ + QaCallback, + &myData ) + ) == 0) ); + if( stream ) + { + PaTimestamp oldStamp, newStamp; + unsigned long oldFrames; + int minDelay = ( mode == MODE_INPUT ) ? 1000 : 400; + int minNumBuffers = Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate ); + int msec = (int) ((minNumBuffers * 3 * 1000.0 * FRAMES_PER_BUFFER) / sampleRate); + if( msec < minDelay ) msec = minDelay; + printf("msec = %d\n", msec); /**/ + EXPECT( ((result=Pa_StartStream( stream )) == 0) ); + /* Check to make sure PortAudio is advancing timeStamp. */ + result = paNoError; + oldStamp = Pa_StreamTime(stream); + fflush(stdout); + Pa_Sleep(msec); + newStamp = Pa_StreamTime(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 = %d, myData.framesLeft = %d\n", oldFrames, myData.framesLeft ); /**/ + EXPECT( (oldFrames > myData.framesLeft) ); + EXPECT( ((result=Pa_CloseStream( stream )) == 0) ); + stream = NULL; + } +error: + if( stream != NULL ) Pa_CloseStream( stream ); + fflush(stdout); + return result; +} diff --git a/pd/portaudio_v18/pa_tests/paqa_errs.c b/pd/portaudio_v18/pa_tests/paqa_errs.c new file mode 100644 index 00000000..a26779cc --- /dev/null +++ b/pd/portaudio_v18/pa_tests/paqa_errs.c @@ -0,0 +1,330 @@ +/* + * $Id: paqa_errs.c,v 1.2.4.1 2003/02/11 21:41:32 philburk Exp $ + * paqa_devs.c + * Self Testing Quality Assurance app for PortAudio + * Do lots of bad things to test error reporting. + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +/****************************************** Definitions ***********/ +#define MODE_INPUT (0) +#define MODE_OUTPUT (1) +#define FRAMES_PER_BUFFER (64) +#define SAMPLE_RATE (44100.0) +#define NUM_BUFFERS (0) +typedef struct PaQaData +{ + unsigned long framesLeft; + int numChannels; + int bytesPerSample; + int mode; +} +PaQaData; +/****************************************** Prototypes ***********/ +static void TestDevices( int mode ); +static void TestFormats( int mode, PaDeviceID deviceID, double sampleRate, + int numChannels ); +static int TestBadOpens( void ); +static int TestBadActions( void ); +static int QaCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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( msg, _exp) \ + do \ + { \ + if ((_exp)) {\ + gNumPassed++; \ + } \ + else { \ + printf("\nERROR %s\n - 0x%x - %s for %s\n", (msg), result, Pa_GetErrorText(result), #_exp ); \ + gNumFailed++; \ + goto error; \ + } \ + } while(0) +#define HOPEFOR( msg, _exp) \ + do \ + { \ + if ((_exp)) {\ + gNumPassed++; \ + } \ + else { \ + printf("\nERROR %s\n - 0x%x - %s for %s\n", (msg), 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + unsigned long i; + unsigned char *out = (unsigned char *) outputBuffer; + PaQaData *data = (PaQaData *) userData; + (void) inputBuffer; /* Prevent "unused variable" warnings. */ + (void) outTime; + + /* 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; iframesLeft > framesPerBuffer ) + { + data->framesLeft -= framesPerBuffer; + return 0; + } + else + { + data->framesLeft = 0; + return 1; + } +} +/*******************************************************************/ +int main(void); +int main(void) +{ + PaError result; + EXPECT( "init", ((result=Pa_Initialize()) == 0) ); + TestBadActions(); + TestBadOpens(); +error: + Pa_Terminate(); + printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed ); + return 0; +} +/*******************************************************************/ +static int TestBadOpens( void ) +{ + PortAudioStream *stream = NULL; + PaError result; + PaQaData myData; + /* Setup data for synthesis thread. */ + myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */ + myData.numChannels = 1; + myData.mode = MODE_OUTPUT; + HOPEFOR( "No devices specified.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + paNoDevice, 0, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidDeviceId) ); + HOPEFOR( "Out of range input device specified.",( + (result = Pa_OpenStream( + &stream, + Pa_CountDevices(), 0, paFloat32, NULL, + paNoDevice, 0, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidDeviceId) ); + + HOPEFOR( "Out of range output device specified.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_CountDevices(), 0, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidDeviceId) ); + HOPEFOR( "Zero input channels.",( + (result = Pa_OpenStream( + &stream, + Pa_GetDefaultInputDeviceID(), 0, paFloat32, NULL, + paNoDevice, 0, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidChannelCount) ); + HOPEFOR( "Zero output channels.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 0, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidChannelCount) ); + HOPEFOR( "Nonzero input channels but no device.",( + (result = Pa_OpenStream( + &stream, + Pa_GetDefaultInputDeviceID(), 2, paFloat32, NULL, + paNoDevice, 2, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidChannelCount) ); + + HOPEFOR( "Nonzero output channels but no device.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 2, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidChannelCount) ); + HOPEFOR( "NULL stream pointer.",( + (result = Pa_OpenStream( + NULL, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paBadStreamPtr) ); + HOPEFOR( "Low sample rate.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + 1.0, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidSampleRate) ); + HOPEFOR( "High sample rate.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + 10000000.0, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidSampleRate) ); + HOPEFOR( "NULL callback.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + NULL, + &myData ) + ) == paNullCallback) ); + HOPEFOR( "Bad flag.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + (1<<3), + QaCallback, + &myData ) + ) == paInvalidFlag) ); + +#if 1 /* FIXME - this is legal for some implementations. */ + HOPEFOR( "Use input device as output device.",( + (result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultInputDeviceID(), 2, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidDeviceId) ); + + HOPEFOR( "Use output device as input device.",( + (result = Pa_OpenStream( + &stream, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + paNoDevice, 0, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == paInvalidDeviceId) ); +#endif + + if( stream != NULL ) Pa_CloseStream( stream ); + return result; +} +/*******************************************************************/ +static int TestBadActions( void ) +{ + PortAudioStream *stream = NULL; + PaError result; + PaQaData myData; + /* Setup data for synthesis thread. */ + myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */ + myData.numChannels = 1; + myData.mode = MODE_OUTPUT; + /* Default output. */ + EXPECT( "TestBadActions", ((result = Pa_OpenStream( + &stream, + paNoDevice, 0, paFloat32, NULL, + Pa_GetDefaultOutputDeviceID(), 2, paFloat32, NULL, + SAMPLE_RATE, FRAMES_PER_BUFFER, NUM_BUFFERS, + paClipOff, + QaCallback, + &myData ) + ) == 0) ); + HOPEFOR( "start", ((result = Pa_StartStream( NULL )) == paBadStreamPtr) ); + HOPEFOR( "stop", ((result = Pa_StopStream( NULL )) == paBadStreamPtr) ); + HOPEFOR( "active?", ((result = Pa_StreamActive( NULL )) == paBadStreamPtr) ); + HOPEFOR( "close", ((result = Pa_CloseStream( NULL )) == paBadStreamPtr) ); + HOPEFOR( "time?", ((result = (PaError)Pa_StreamTime( NULL )) != 0) ); + HOPEFOR( "CPULoad?", ((result = (PaError)Pa_GetCPULoad( NULL )) != 0) ); +error: + if( stream != NULL ) Pa_CloseStream( stream ); + return result; +} diff --git a/pd/portaudio_v18/pa_tests/patest1.c b/pd/portaudio_v18/pa_tests/patest1.c new file mode 100644 index 00000000..8ac45ad1 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest1.c @@ -0,0 +1,114 @@ +/* + $Id: patest1.c,v 1.1.1.1 2002/01/22 00:52:33 phil Exp $ + patest1.c + Ring modulate the audio input with a sine wave for 20 seconds + using the Portable Audio api + Author: Ross Bencina + Modifications: + April 5th, 2001 - PLB - Check for NULL inputBuffer. +*/ +#include +#include +#include "portaudio.h" +#ifndef M_PI +#define M_PI (3.14159265) +#endif +typedef struct +{ + float sine[100]; + int phase; + int sampsToGo; +} +patest1data; +static int patest1Callback( void *inputBuffer, void *outputBuffer, + unsigned long bufferFrames, + PaTimestamp outTime, void *userData ) +{ + patest1data *data = (patest1data*)userData; + float *in = (float*)inputBuffer; + float *out = (float*)outputBuffer; + int framesToCalc = bufferFrames; + unsigned long i; + int finished = 0; + /* Check to see if any input data is available. */ + if(inputBuffer == NULL) return 0; + if( data->sampsToGo < bufferFrames ) + { + framesToCalc = data->sampsToGo; + finished = 1; + } + for( i=0; isine[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 +#include +#include +#include "portaudio.h" +#define NUM_SECONDS (1) +#define SAMPLE_RATE (44100) +#ifndef M_PI +#define M_PI (3.14159265) +#endif +#define TABLE_SIZE (200) + +#define BUFFER_TABLE 9 +long buffer_table[] = {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 ); + +static int paSineCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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 paSineCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + short *out = (short*)outputBuffer; + unsigned int i; + int finished = 0; + (void) inputBuffer; /* Prevent "unused variable" warnings. */ + (void) outTime; + + if( data->sampsToGo < framesPerBuffer ) + { + for( i=0; isampsToGo; 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( ; isine[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(void); +int main(void) +{ + int i; + PaError err; + printf("Test opening streams with different buffer sizes\n\n"); + + for (i = 0 ; i < BUFFER_TABLE; i++) + { + printf("Buffer size %d\n", buffer_table[i]); + err = TestOnce(buffer_table[i]); + if( err < 0 ) return 0; + + } +} + + +PaError TestOnce( int buffersize ) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + int totalSamps; + /* initialise sinusoidal wavetable */ + for( i=0; i +#include +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + float amplitude = data->amplitude; + unsigned int i; + (void) inputBuffer; /* Prevent "unused variable" warnings. */ + (void) outTime; + + for( i=0; isine[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; ileft_phase = data->right_phase = 0; + data->amplitude = amplitude; + err = Pa_Initialize(); + if( err != paNoError ) goto error; + err = Pa_OpenStream( + &stream, + paNoDevice,/* default input device */ + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + Pa_GetDefaultOutputDeviceID(), /* default output device */ + 2, /* stereo output */ + paFloat32, /* 32 bit floating point output */ + NULL, + SAMPLE_RATE, + 1024, + 0, /* number of buffers, if zero then use default minimum */ + flags, /* we won't output out of range samples so don't bother clipping them */ + 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_GetCPULoad( stream ) ); + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + Pa_Terminate(); + return paNoError; +error: + return err; +} diff --git a/pd/portaudio_v18/pa_tests/patest_dither.c b/pd/portaudio_v18/pa_tests/patest_dither.c new file mode 100644 index 00000000..c58b9cea --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_dither.c @@ -0,0 +1,152 @@ +/* + * $Id: patest_dither.c,v 1.2 2002/03/21 00:58:45 philburk Exp $ + * patest_dither.c + * 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 + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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, PaStreamFlags flags, float amplitude ); +static int sineCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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 sineCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + float amplitude = data->amplitude; + unsigned int i; + (void) outTime; + (void) inputBuffer; + for( i=0; isine[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; + float amplitude = 32.0 / (1<<15); + printf("PortAudio Test: output EXTREMELY QUIET sine wave with and without dithering.\n"); + /* initialise sinusoidal wavetable */ + for( i=0; ileft_phase = data->right_phase = 0; + data->amplitude = amplitude; + err = Pa_Initialize(); + if( err != paNoError ) goto error; + err = Pa_OpenStream( + &stream, + paNoDevice,/* default input device */ + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + Pa_GetDefaultOutputDeviceID(), /* default output device */ + 2, /* stereo output */ + paFloat32, /* 32 bit floating point output */ + NULL, + SAMPLE_RATE, + 1024, + 0, /* number of buffers, if zero then use default minimum */ + flags, /* we won't output out of range samples so don't bother clipping them */ + sineCallback, + (void *)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_GetCPULoad( stream ) ); + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + Pa_Terminate(); + return paNoError; +error: + return err; +} diff --git a/pd/portaudio_v18/pa_tests/patest_hang.c b/pd/portaudio_v18/pa_tests/patest_hang.c new file mode 100644 index 00000000..d1d67199 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_hang.c @@ -0,0 +1,153 @@ +/* + * $Id: patest_hang.c,v 1.1.4.1 2003/02/11 21:41:32 philburk Exp $ + * Play a sine then hang audio callback to test watchdog. + * + * Authors: + * Ross Bencina + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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( 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; + double phaseInc = 0.02; + double phase = data->phase; + + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + for( i=0; i 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) +{ + PortAudioStream *stream; + 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; + + err = Pa_OpenStream( + &stream, + paNoDevice,/* default input device */ + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + Pa_GetDefaultOutputDeviceID(), /* default output device */ + 1, /* mono output */ + 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; + +/* Gradually increase sleep time. */ + for( i=0; i<10000; i+= 1000 ) + { + printf("Sleep for %d milliseconds in audio callback.\n", i ); + data.sleepFor = i; + fflush(stdout); + Pa_Sleep( ((i<1000) ? 1000 : i) ); + } + + printf("Suffer for 10 seconds.\n"); + fflush(stdout); + 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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_latency.c b/pd/portaudio_v18/pa_tests/patest_latency.c new file mode 100644 index 00000000..39ede0a7 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_latency.c @@ -0,0 +1,176 @@ +/* + * $Id: patest_latency.c,v 1.4 2002/03/21 00:58:45 philburk Exp $ + * Hear the latency caused by big buffers. + * Play a sine wave and change frequency based on letter input. + * + * Author: Phil Burk , and Darren Gibbs + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" + +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (64) + +#if 0 +#define MIN_LATENCY_MSEC (2000) +#define NUM_BUFFERS ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) +#else +#define NUM_BUFFERS (0) +#endif + +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + int i; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + for( i=0; ileft_phase); /* left */ + *out++ = LookupSine(data, data->right_phase); /* right */ + data->left_phase += data->phase_increment; + if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f; + data->right_phase += (data->phase_increment * 1.5f); /* fifth above */ + if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f; + } + return 0; +} +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + int done = 0; + printf("PortAudio Test: enter letter then hit ENTER. numBuffers = %d\n", NUM_BUFFERS ); + /* initialise sinusoidal wavetable */ + for( i=0; i + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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( 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; itoggle ) + { + *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) +{ + PortAudioStream *stream; + 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 0 ) + { + Pa_Sleep( 300 ); + 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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_longsine.c b/pd/portaudio_v18/pa_tests/patest_longsine.c new file mode 100644 index 00000000..7dc8ae56 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_longsine.c @@ -0,0 +1,137 @@ +/* + * $Id: patest_longsine.c,v 1.2 2002/04/30 21:21:30 philburk Exp $ + * patest_longsine.c + * Play a sine wave using the Portable Audio api until ENTER hit. + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + unsigned int i; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + for( i=0; isine[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) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + printf("PortAudio Test: output sine wave.\n"); + + /* initialise sinusoidal wavetable */ + for( i=0; i +#include +#include +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + short *out = (short*)outputBuffer; + unsigned int i; + int finished = 0; + (void) inputBuffer; /* Prevent "unused variable" warnings. */ + (void) outTime; + + if( data->sampsToGo < framesPerBuffer ) + { + /* final buffer... */ + + for( i=0; isampsToGo; 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( ; isine[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 1 ) + { + numLoops = atoi(argv[1]); + } + for( i=0; i + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + +/* Detemine amplitude scaling factor */ + numForScale = data->numSines; + if( numForScale < 8 ) numForScale = 8; /* prevent pops at beginning */ + scaler = 1.0f / numForScale; + + for( i=0; inumSines; 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; + PortAudioStream *stream; + 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 + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" + +#define NUM_SECONDS (10) +#define SAMPLE_RATE (44100) +#define AMPLITUDE (0.8) +#define FRAMES_PER_BUFFER (64) +#define OUTPUT_DEVICE Pa_GetDefaultOutputDeviceID() + +#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( 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; isine[data->phase]; /* left */ + data->phase += 1; + if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE; + } + return finished; +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *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 +#include +#include "portaudio.h" + +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) +#define FREQ_INCR (300.0 / SAMPLE_RATE) +#define MAX_CHANNELS (64) + +#ifndef M_PI +#define M_PI (3.14159265) +#endif + +typedef struct +{ + int numChannels; + double phases[MAX_CHANNELS]; +} +paTestData; + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int patestCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + int frameIndex, channelIndex; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) + { + for( channelIndex=0; channelIndexnumChannels; channelIndex++ ) + { + /* Output sine wave on every channel. */ + *out++ = (float) (0.7 * sin(data->phases[channelIndex])); + + /* Play each channel at a higher frequency. */ + data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex); + if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI); + } + } + + return 0; +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + const PaDeviceInfo *pdi; + paTestData data = {0}; + printf("PortAudio Test: output sine wave on each channel.\n" ); + + err = Pa_Initialize(); + if( err != paNoError ) goto error; + + pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE ); + data.numChannels = pdi->maxOutputChannels; + if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS; + printf("Number of Channels = %d\n", data.numChannels ); + + err = Pa_OpenStream( + &stream, + paNoDevice, /* default input device */ + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + OUTPUT_DEVICE, + data.numChannels, + paFloat32, /* 32 bit floating point output */ + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + 0, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + patestCallback, + &data ); + if( err != paNoError ) goto error; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + printf("Hit ENTER to stop sound.\n"); + fflush(stdout); + getchar(); + + err = Pa_StopStream( stream ); + if( err != paNoError ) goto error; + + Pa_CloseStream( stream ); + Pa_Terminate(); + printf("Test finished.\n"); + return err; +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return err; +} diff --git a/pd/portaudio_v18/pa_tests/patest_pink.c b/pd/portaudio_v18/pa_tests/patest_pink.c new file mode 100644 index 00000000..f3bfdadb --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_pink.c @@ -0,0 +1,245 @@ +/* + * $Id: patest_pink.c,v 1.1.1.1 2002/01/22 00:52:36 phil Exp $ + patest_pink.c + Generate Pink Noise using Gardner method. + Optimization suggested by James McCartney uses a tree + to select which random value to replace. + 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 + 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 + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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<pink_Scalar = 1.0f / pmax; + /* Initialize rows. */ + for( i=0; ipink_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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + int finished; + int i; + int numFrames; + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + (void) inputBuffer; /* Prevent "unused variable" warnings. */ + (void) outTime; + + /* Are we almost at end. */ + if( data->sampsToGo < framesPerBuffer ) + { + numFrames = data->sampsToGo; + finished = 1; + } + else + { + numFrames = framesPerBuffer; + finished = 0; + } + for( i=0; ileftPink ); + *out++ = GeneratePinkNoise( &data->rightPink ); + } + data->sampsToGo -= numFrames; + return finished; +} +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int totalSamps; + /* 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 = 8*44100; /* Play for a few seconds. */ + err = Pa_Initialize(); + if( err != paNoError ) goto error; + /* Open a stereo PortAudio stream so we can hear the result. */ + err = Pa_OpenStream( + &stream, + paNoDevice, + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + Pa_GetDefaultOutputDeviceID(), /* default output device */ + 2, /* stereo output */ + paFloat32, /* 32 bit floating point output */ + NULL, + 44100., + 2048, /* 46 msec buffers */ + 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 for sound to finish.\n"); + while( Pa_StreamActive( stream ) ) + { + Pa_Sleep(100); /* SPIN! */ + } + 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 */ diff --git a/pd/portaudio_v18/pa_tests/patest_record.c b/pd/portaudio_v18/pa_tests/patest_record.c new file mode 100644 index 00000000..f7f79bd3 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_record.c @@ -0,0 +1,325 @@ +/* + * $Id: patest_record.c,v 1.2.4.4 2003/04/16 19:07:56 philburk Exp $ + * patest_record.c + * Record input into an array. + * Optionally save array to a file. + * Playback recorded data. + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" + +/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */ +#define SAMPLE_RATE (44100) +#define NUM_SECONDS (5) +#define NUM_CHANNELS (2) +/* #define DITHER_FLAG (paDitherOff) */ +#define DITHER_FLAG (0) /**/ +#define FRAMES_PER_BUFFER (1024) + +/* Select sample format. */ +#if 1 +#define PA_SAMPLE_TYPE paFloat32 +typedef float SAMPLE; +#define SAMPLE_SILENCE (0.0f) +#elif 0 +#define PA_SAMPLE_TYPE paInt16 +typedef short SAMPLE; +#define SAMPLE_SILENCE (0) +#elif 0 +#define PA_SAMPLE_TYPE paInt8 +typedef char SAMPLE; +#define SAMPLE_SILENCE (0) +#else +#define PA_SAMPLE_TYPE paUInt8 +typedef unsigned char SAMPLE; +#define SAMPLE_SILENCE (128) + +#endif + +typedef struct +{ + int frameIndex; /* Index into sample array. */ + int maxFrameIndex; + SAMPLE *recordedSamples; +} +paTestData; +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int recordCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + SAMPLE *rptr = (SAMPLE*)inputBuffer; + SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS]; + long framesToRecord; + long i; + int finished; + unsigned long framesLeft = data->maxFrameIndex - data->frameIndex; + int samplesToRecord; + + (void) outputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + + if( framesLeft < framesPerBuffer ) + { + framesToRecord = framesLeft; + finished = 1; + } + else + { + framesToRecord = framesPerBuffer; + finished = 0; + } + + samplesToRecord = framesToRecord * NUM_CHANNELS; + + if( inputBuffer == NULL ) + { + for( i=0; iframeIndex += framesToRecord; + return finished; +} + +/* This routine will be called by the PortAudio engine when audio is needed. +** It may be called at interrupt level on some machines so don't do anything +** that could mess up the system like calling malloc() or free(). +*/ +static int playCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS]; + SAMPLE *wptr = (SAMPLE*)outputBuffer; + unsigned int i; + int finished; + unsigned int framesLeft = data->maxFrameIndex - data->frameIndex; + (void) inputBuffer; /* Prevent unused variable warnings. */ + (void) outTime; + int framesToPlay, samplesToPlay, samplesPerBuffer; + + if( framesLeft < framesPerBuffer ) + { + framesToPlay = framesLeft; + finished = 1; + } + else + { + framesToPlay = framesPerBuffer; + finished = 0; + } + + samplesToPlay = framesToPlay * NUM_CHANNELS; + samplesPerBuffer = framesPerBuffer * NUM_CHANNELS; + + for( i=0; iframeIndex += framesToPlay; + + return finished; +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + int totalFrames; + int numSamples; + int numBytes; + SAMPLE max, average, val; + 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 ); + if( data.recordedSamples == NULL ) + { + printf("Could not allocate record array.\n"); + exit(1); + } + for( i=0; i max ) + { + max = val; + } + average += val; + } + + average = average / numSamples; + + if( PA_SAMPLE_TYPE == paFloat32 ) /* This should be done at compile-time with "#if" ?? */ + { /* MIPS-compiler warns at the int-version below. */ + printf("sample max amplitude = %f\n", max ); + printf("sample average = %f\n", average ); + } + else + { + printf("sample max amplitude = %d\n", max ); /* <-- This IS compiled anyhow. */ + printf("sample average = %d\n", average ); + } + + /* Write recorded data to a file. */ +#if 0 + { + FILE *fid; + fid = fopen("recorded.raw", "wb"); + if( fid == NULL ) + { + printf("Could not open file."); + } + else + { + fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid ); + fclose( fid ); + printf("Wrote data to 'recorded.raw'\n"); + } + } +#endif + + /* Playback recorded data. -------------------------------------------- */ + data.frameIndex = 0; + printf("Begin playback.\n"); fflush(stdout); + err = Pa_OpenStream( + &stream, + paNoDevice, + 0, /* NO input */ + PA_SAMPLE_TYPE, + NULL, + Pa_GetDefaultOutputDeviceID(), + NUM_CHANNELS, + PA_SAMPLE_TYPE, + NULL, + SAMPLE_RATE, + FRAMES_PER_BUFFER, /* frames per buffer */ + 0, /* number of buffers, if zero then use default minimum */ + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + playCallback, + &data ); + if( err != paNoError ) goto error; + + if( stream ) + { + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + printf("Waiting for playback to finish.\n"); fflush(stdout); + + while( Pa_StreamActive( stream ) ) Pa_Sleep(100); + + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + printf("Done.\n"); fflush(stdout); + } + free( data.recordedSamples ); + + 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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_ringmix.c b/pd/portaudio_v18/pa_tests/patest_ringmix.c new file mode 100644 index 00000000..9d78ea13 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_ringmix.c @@ -0,0 +1,41 @@ +/* $Id: patest_ringmix.c,v 1.1.1.1 2002/01/22 00:52:37 phil Exp $ */ + +#include "stdio.h" +#include "portaudio.h" +/* This will be called asynchronously by the PortAudio engine. */ +static int myCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, PaTimestamp outTime, void *userData ) +{ + float *out = (float *) outputBuffer; + float *in = (float *) inputBuffer; + float leftInput, rightInput; + unsigned int i; + if( inputBuffer == NULL ) return 0; + /* Read input buffer, process data, and fill output buffer. */ + for( i=0; i +#include +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + /* Cast data passed through stream to our structure. */ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + unsigned int i; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + for( i=0; ileft_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) +{ + PortAudioStream *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 */ + 0, /* number of buffers, if zero then use default minimum */ + 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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_sine.c b/pd/portaudio_v18/pa_tests/patest_sine.c new file mode 100644 index 00000000..162fac02 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_sine.c @@ -0,0 +1,141 @@ +/* + * $Id: patest_sine.c,v 1.2.4.1 2003/02/11 21:41:32 philburk Exp $ + * patest_sine.c + * Play a sine wave using the Portable Audio api for several seconds. + * + * Authors: + * Ross Bencina + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" + +#define NUM_SECONDS (10) +#define SAMPLE_RATE (44100) +#define AMPLITUDE (0.9) +#define FRAMES_PER_BUFFER (64) +#define OUTPUT_DEVICE Pa_GetDefaultOutputDeviceID() +//#define OUTPUT_DEVICE (2) + +#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( 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; isine[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 finished; +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d, devID = %d\n", + SAMPLE_RATE, FRAMES_PER_BUFFER, OUTPUT_DEVICE); + /* initialise sinusoidal wavetable */ + for( i=0; i + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +#define NUM_SECONDS (8) +#define SAMPLE_RATE (44100) +#define TEST_UNSIGNED (1) +#if TEST_UNSIGNED +#define TEST_FORMAT paUInt8 +#else +#define TEST_FORMAT paInt8 +#endif +#ifndef M_PI +#define M_PI (3.14159265) +#endif +#define TABLE_SIZE (200) +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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + char *out = (char*)outputBuffer; + 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; isine[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) +{ + PortAudioStream *stream; + PaError err; + paTestData data; + int i; + int 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 +#include +#include "portaudio.h" + +#define NUM_SECONDS (5) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (512) +#define LEFT_FREQ ((2 * SAMPLE_RATE)/FRAMES_PER_BUFFER) /* So we hit 1.0 */ +#define RIGHT_FREQ (500.0) +#define AMPLITUDE (0.9) + +/* Select ONE format for testing. */ +#define TEST_UINT8 (0) +#define TEST_INT8 (0) +#define TEST_INT16 (0) +#define TEST_INT32 (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_INT32 +#define TEST_FORMAT paInt32 +typedef long SAMPLE_t; +#define SAMPLE_ZERO (0) +#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(0x7FFFFFFF * (x))) +#define FORMAT_NAME "Signed 32 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; + int i; + int framesToCalc; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + if( data->framesToGo < framesPerBuffer ) + { + framesToCalc = data->framesToGo; + data->framesToGo = 0; + finished = 1; + } + else + { + framesToCalc = framesPerBuffer; + data->framesToGo -= framesPerBuffer; + } + + for( i=0; ileft_phase += (LEFT_FREQ / SAMPLE_RATE); + if( data->left_phase > 1.0) data->left_phase -= 1.0; + *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) +{ + 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 ); fflush(stdout); + while( Pa_StreamActive( stream ) ) Pa_Sleep(10); + + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + Pa_Terminate(); + + printf("PortAudio Test Finished: " FORMAT_NAME "\n"); + + return err; +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return err; +} diff --git a/pd/portaudio_v18/pa_tests/patest_sine_time.c b/pd/portaudio_v18/pa_tests/patest_sine_time.c new file mode 100644 index 00000000..e9bc33da --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_sine_time.c @@ -0,0 +1,205 @@ +/* + * $Id: patest_sine_time.c,v 1.2 2002/03/21 00:58:45 philburk Exp $ + * patest_sine_time.c + * Play a sine wave using the Portable Audio api for several seconds. + * Pausing in the middle. + * use the Pa_StreamTime() and Pa_StreamActive() calls. + * + * Authors: + * Ross Bencina + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +#define NUM_SECONDS (8) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (64) +#define NUM_BUFFERS (0) +#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 framesToGo; + volatile PaTimestamp 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + int i; + int framesToCalc; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + data->outTime = outTime; + + if( data->framesToGo < framesPerBuffer ) + { + framesToCalc = data->framesToGo; + data->framesToGo = 0; + finished = 1; + } + else + { + framesToCalc = framesPerBuffer; + data->framesToGo -= framesPerBuffer; + } + + for( i=0; isine[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++ ) + { + *out++ = 0; /* left */ + *out++ = 0; /* right */ + } + return finished; +} +/*******************************************************************/ +static void ReportStreamTime( PortAudioStream *stream, paTestData *data ); +static void ReportStreamTime( PortAudioStream *stream, paTestData *data ) +{ + PaTimestamp streamTime, latency, outTime; + + streamTime = Pa_StreamTime( stream ); + outTime = data->outTime; + if( outTime < 0.0 ) + { + printf("Stream time = %8.1f\n", streamTime ); + } + else + { + latency = outTime - streamTime; + printf("Stream time = %8.1f, outTime = %8.1f, latency = %8.1f\n", + streamTime, outTime, latency ); + } + fflush(stdout); +} + +/*******************************************************************/ +int main(void); +int main(void) +{ + PortAudioStream *stream; + PaError err; + paTestData DATA; + int i; + int totalSamps; + printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER); + /* initialise sinusoidal wavetable */ + for( i=0; i + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com + * Copyright (c) 1999-2000 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID()) +#define SLEEP_DUR (200) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) +#define LATENCY_MSEC (3000) +#define NUM_BUFFERS ((LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) +#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; + PaTimestamp 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + float value; + unsigned int i = 0; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + data->outTime = outTime; + if( !data->done ) + { + for( i=0; iframeCounter >= 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 = 1; + 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( ; idone = 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; + err = Pa_OpenStream( + &stream, + paNoDevice,/* default input device */ + 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, /* 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; + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + if( data->stopMode == MODE_FINISH ) + { + while( Pa_StreamActive( stream ) ) + { + /*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime, + data->noteCounter, data->repeatCounter ); + fflush(stdout); /**/ + Pa_Sleep( SLEEP_DUR ); + } + } + 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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_sync.c b/pd/portaudio_v18/pa_tests/patest_sync.c new file mode 100644 index 00000000..c70fbb35 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_sync.c @@ -0,0 +1,227 @@ +/* + * $Id: patest_sync.c,v 1.1.1.1 2002/01/22 00:52:40 phil Exp $ + * patest_sync.c + * 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 Pa_StreamTime(). + * Foreground outputs video (printf) in sync with audio. + * Repeat. + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#include "portaudio.h" +#define NUM_BEEPS (6) +#define SAMPLE_RATE (44100) +#define FRAMES_PER_BUFFER (256) +#define BEEP_DURATION (1000) +#define LATENCY_MSEC (2000) +#define SLEEP_MSEC (10) +#define TIMEOUT_MSEC ((3 * LATENCY_MSEC) / (2 * SLEEP_MSEC)) +#define NUM_BUFFERS ((LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000)) +#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; + int requestBeep; /* Set by foreground, cleared by background. */ + PaTimestamp beepTime; + int beepCount; +} +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 = 22222; /* 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + /* Cast data passed through stream to our structure. */ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + unsigned int i; + (void) inputBuffer; + + for( i=0; istate ) + { + case STATE_BKG_IDLE: + /* Schedule beep at some random time in the future. */ + if( data->requestBeep ) + { + int random = GenerateRandomNumber() >> 14; + data->beepTime = outTime + (i + random + (SAMPLE_RATE/4)); + data->state = STATE_BKG_PENDING; + data->requestBeep = 0; + data->left_phase = data->right_phase = 0.0; + } + *out++ = 0.0; /* left */ + *out++ = 0.0; /* right */ + break; + case STATE_BKG_PENDING: + if( (outTime + i) >= data->beepTime ) + { + data->state = STATE_BKG_BEEPING; + data->beepCount = BEEP_DURATION; + } + *out++ = 0.0; /* left */ + *out++ = 0.0; /* right */ + break; + case STATE_BKG_BEEPING: + if( data->beepCount <= 0 ) + { + data->state = STATE_BKG_IDLE; + *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) +{ + PortAudioStream *stream; + PaError err; + paTestData DATA; + int i, timeout; + PaTimestamp previousTime; + 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; + /* 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, + FRAMES_PER_BUFFER, + NUM_BUFFERS, + patestCallback, + &DATA ); + if( err != paNoError ) goto error; + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + previousTime = Pa_StreamTime( stream ); + for( i=0; i 0 ) ) Pa_Sleep(SLEEP_MSEC); + if( timeout <= 0 ) + { + fprintf( stderr, "Timed out waiting for background to acknowledge request.\n" ); + goto error; + } + /* Wait for scheduled beep time. */ + timeout = TIMEOUT_MSEC + (10000/SLEEP_MSEC); + while( (Pa_StreamTime( stream ) < DATA.beepTime) && (timeout-- > 0 ) ) + { + Pa_Sleep(SLEEP_MSEC); + } + if( timeout <= 0 ) + { + fprintf( stderr, "Timed out waiting for time. Now = %g, Beep for %g.\n", + Pa_StreamTime( stream ), DATA.beepTime ); + goto error; + } + /* Beep should be sounding now so print synchronized BEEP. */ + printf("BEEP"); + fflush(stdout); + printf(" at %d, delta = %d\n", + (long) DATA.beepTime, (long) (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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_toomanysines.c b/pd/portaudio_v18/pa_tests/patest_toomanysines.c new file mode 100644 index 00000000..53ca8950 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_toomanysines.c @@ -0,0 +1,175 @@ +/* + * $Id: patest_toomanysines.c,v 1.2.4.1 2003/02/11 21:41:32 philburk Exp $ + * Play more sine waves than we can handle in real time as a stress test, + * + * Authors: + * Ross Bencina + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + paTestData *data = (paTestData*)userData; + float *out = (float*)outputBuffer; + unsigned long i; + int j; + int finished = 0; + (void) outTime; /* Prevent unused variable warnings. */ + (void) inputBuffer; + + for( i=0; inumSines; 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) +{ + PortAudioStream *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; + err = Pa_OpenStream( + &stream, + paNoDevice,/* default input device */ + 0, /* no input */ + paFloat32, /* 32 bit floating point input */ + NULL, + Pa_GetDefaultOutputDeviceID(), /* default output device */ + 1, /* mono output */ + 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; + + /* Determine number of sines required to get to 50% */ + do + { + data.numSines++; + Pa_Sleep( 100 ); + + load = Pa_GetCPULoad( stream ); + printf("numSines = %d, CPU load = %f\n", data.numSines, load ); + fflush(stdout); + } + 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_GetCPULoad( stream ); + printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load ); + fflush(stdout); + + } + + 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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_two_rates.c b/pd/portaudio_v18/pa_tests/patest_two_rates.c new file mode 100644 index 00000000..350ce043 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_two_rates.c @@ -0,0 +1,168 @@ +/* + * $Id: patest_two_rates.c,v 1.1.2.1 2003/02/11 21:42:24 philburk Exp $ + * patest_two_rates.c + * Play two streams at different rates to make sure they don't interfere. + * + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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; +} diff --git a/pd/portaudio_v18/pa_tests/patest_underflow.c b/pd/portaudio_v18/pa_tests/patest_underflow.c new file mode 100644 index 00000000..1547b2e4 --- /dev/null +++ b/pd/portaudio_v18/pa_tests/patest_underflow.c @@ -0,0 +1,151 @@ +/* + * $Id: patest_underflow.c,v 1.1.1.1 2002/01/22 00:52:40 phil Exp $ + * patest_underflow.c + * Simulate an output buffer underflow condition. + * Tests whether the stream can be stopped when underflowing buffers. + * + * Authors: + * Ross Bencina + * Phil Burk + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.audiomulch.com/portaudio/ + * 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. + * + * 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. + * + * 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. + * + */ +#include +#include +#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( 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; isine[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) +{ + PortAudioStream *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 +#include +#include "portaudio.h" + +#define INPUT_DEVICE Pa_GetDefaultInputDeviceID() +#define OUTPUT_DEVICE Pa_GetDefaultOutputDeviceID() + +/* +** 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 FRAMES_PER_BUFFER (64) + +#if 1 +#define PA_SAMPLE_TYPE paFloat32 +typedef float SAMPLE; +#else +#define PA_SAMPLE_TYPE paInt16 +typedef short SAMPLE; +#endif +static int wireCallback( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, 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( void *inputBuffer, void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime, void *userData ) +{ + SAMPLE *out = (SAMPLE*)outputBuffer; + SAMPLE *in = (SAMPLE*)inputBuffer; + unsigned int i; + (void) outTime; + int samplesPerFrame; + int numSamples; + + samplesPerFrame = (int) userData; + numSamples = framesPerBuffer * samplesPerFrame; + + /* This may get called with NULL inputBuffer during initial setup. */ + if( inputBuffer == NULL ) + { + for( i=0; imaxInputChannels < outputInfo->maxOutputChannels) ? + inputInfo->maxInputChannels : outputInfo->maxOutputChannels; + + printf("maxInputChannels channels = %d\n", inputInfo->maxInputChannels ); + printf("maxOutputChannels channels = %d\n", outputInfo->maxOutputChannels ); + if( numChannels > 0 ) + { + printf("Using %d channels.\n", numChannels ); + + err = Pa_OpenStream( + &stream, + INPUT_DEVICE, + numChannels, + PA_SAMPLE_TYPE, + NULL, + OUTPUT_DEVICE, + numChannels, + 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 */ + wireCallback, + (void *) numChannels ); /* pass numChannels to callback */ + if( err != paNoError ) goto error; + + err = Pa_StartStream( stream ); + if( err != paNoError ) goto error; + + printf("Full duplex sound test in progress.\n"); + printf("Hit ENTER to exit test.\n"); fflush(stdout); + getchar(); + + printf("Closing stream.\n"); + err = Pa_CloseStream( stream ); + if( err != paNoError ) goto error; + } + else + { + printf("Sorry, not enough channels.\n"); + } + Pa_Terminate(); + + printf("Full duplex sound 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 ) ); + return -1; +} -- cgit v1.2.1