first commit
This commit is contained in:
13
third_party/portaudio/test/CMakeLists.txt
vendored
Normal file
13
third_party/portaudio/test/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Test projects
|
||||
# Use the macro to add test projects
|
||||
|
||||
MACRO(ADD_TEST appl_name)
|
||||
ADD_EXECUTABLE(${appl_name} "${appl_name}.c")
|
||||
TARGET_LINK_LIBRARIES(${appl_name} portaudio_static)
|
||||
SET_TARGET_PROPERTIES(${appl_name}
|
||||
PROPERTIES
|
||||
FOLDER "Test"
|
||||
)
|
||||
ENDMACRO(ADD_TEST)
|
||||
|
||||
ADD_TEST(patest_longsine)
|
||||
52
third_party/portaudio/test/README.txt
vendored
Normal file
52
third_party/portaudio/test/README.txt
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
TODO - This should be moved into a doxydoc page.
|
||||
|
||||
For more information on the TestPlan please visit:
|
||||
|
||||
http://www.portaudio.com/trac/wiki/TestPlan
|
||||
|
||||
This directory contains various programs to test PortAudio. The files
|
||||
named patest_* are tests.
|
||||
|
||||
All following tests are up to date with the V19 API. They should all compile
|
||||
(without any warnings on GCC 3.3). Note that this does not necessarily mean that
|
||||
the tests pass, just that they compile.
|
||||
|
||||
x- paqa_devs.c
|
||||
x- paqa_errs.c (needs reviewing)
|
||||
x- patest1.c
|
||||
x- patest_buffer.c
|
||||
x- patest_callbackstop.c
|
||||
x- patest_clip.c (last test fails, dither doesn't currently force clip in V19)
|
||||
x- patest_dither.c
|
||||
x- patest_hang.c
|
||||
x- patest_latency.c
|
||||
x- patest_leftright.c
|
||||
x- patest_longsine.c
|
||||
x- patest_many.c
|
||||
x- patest_maxsines.c
|
||||
x- patest_mono.c
|
||||
x- patest_multi_sine.c
|
||||
x- patest_pink.c
|
||||
x- patest_prime.c
|
||||
x- patest_read_record.c
|
||||
x- patest_record.c
|
||||
x- patest_ringmix.c
|
||||
x- patest_saw.c
|
||||
x- patest_sine.c
|
||||
x- patest_sine8.c
|
||||
x- patest_sine_formats.c
|
||||
x- patest_sine_time.c
|
||||
x- patest_start_stop.c
|
||||
x- patest_stop.c
|
||||
x- patest_sync.c
|
||||
x- patest_toomanysines.c
|
||||
x- patest_two_rates.c
|
||||
x- patest_underflow.c
|
||||
x- patest_wire.c
|
||||
x- patest_write_sine.c
|
||||
x- pa_devs.c
|
||||
x- pa_fuzz.c
|
||||
x- pa_minlat.c
|
||||
|
||||
Note that Phil Burk deleted the debug_* tests on 2/26/11. They were just hacked
|
||||
versions of old V18 tests. If we need to debug then we can just hack a working V19 test.
|
||||
205
third_party/portaudio/test/pa_minlat.c
vendored
Normal file
205
third_party/portaudio/test/pa_minlat.c
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/** @file pa_minlat.c
|
||||
@ingroup test_src
|
||||
@brief Experiment with different numbers of buffers to determine the
|
||||
minimum latency for a computer.
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TWOPI (M_PI * 2.0)
|
||||
|
||||
#define DEFAULT_BUFFER_SIZE (32)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double left_phase;
|
||||
double right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* Very simple synthesis routine to generate two sine waves. */
|
||||
static int paminlatCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned int i;
|
||||
double left_phaseInc = 0.02;
|
||||
double right_phaseInc = 0.06;
|
||||
|
||||
double left_phase = data->left_phase;
|
||||
double right_phase = data->right_phase;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
left_phase += left_phaseInc;
|
||||
if( left_phase > TWOPI ) left_phase -= TWOPI;
|
||||
*out++ = (float) sin( left_phase );
|
||||
|
||||
right_phase += right_phaseInc;
|
||||
if( right_phase > TWOPI ) right_phase -= TWOPI;
|
||||
*out++ = (float) sin( right_phase );
|
||||
}
|
||||
|
||||
data->left_phase = left_phase;
|
||||
data->right_phase = right_phase;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv );
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int go;
|
||||
int outLatency = 0;
|
||||
int minLatency = DEFAULT_BUFFER_SIZE * 2;
|
||||
int framesPerBuffer;
|
||||
double sampleRate = 44100.0;
|
||||
char str[256];
|
||||
char *line;
|
||||
|
||||
printf("pa_minlat - Determine minimum latency for your computer.\n");
|
||||
printf(" usage: pa_minlat {userBufferSize}\n");
|
||||
printf(" for example: pa_minlat 64\n");
|
||||
printf("Adjust your stereo until you hear a smooth tone in each speaker.\n");
|
||||
printf("Then try to find the smallest number of frames that still sounds smooth.\n");
|
||||
printf("Note that the sound will stop momentarily when you change the number of buffers.\n");
|
||||
|
||||
/* Get bufferSize from command line. */
|
||||
framesPerBuffer = ( argc > 1 ) ? atol( argv[1] ) : DEFAULT_BUFFER_SIZE;
|
||||
printf("Frames per buffer = %d\n", framesPerBuffer );
|
||||
|
||||
data.left_phase = data.right_phase = 0.0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outLatency = sampleRate * 200.0 / 1000.0; /* 200 msec. */
|
||||
|
||||
/* Try different numBuffers in a loop. */
|
||||
go = 1;
|
||||
while( go )
|
||||
{
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
|
||||
outputParameters.channelCount = 2; /* Stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
|
||||
outputParameters.suggestedLatency = (double)outLatency / sampleRate; /* In seconds. */
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
printf("Latency = %d frames = %6.1f msec.\n", outLatency, outputParameters.suggestedLatency * 1000.0 );
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
sampleRate,
|
||||
framesPerBuffer,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
paminlatCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
if( stream == NULL ) goto error;
|
||||
|
||||
/* Start audio. */
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* Ask user for a new nlatency. */
|
||||
printf("\nMove windows around to see if the sound glitches.\n");
|
||||
printf("Latency now %d, enter new number of frames, or 'q' to quit: ", outLatency );
|
||||
line = fgets( str, 256, stdin );
|
||||
if( line == NULL )
|
||||
{
|
||||
go = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
/* Get rid of newline */
|
||||
size_t l = strlen( str ) - 1;
|
||||
if( str[ l ] == '\n')
|
||||
str[ l ] = '\0';
|
||||
}
|
||||
|
||||
|
||||
if( str[0] == 'q' ) go = 0;
|
||||
else
|
||||
{
|
||||
outLatency = atol( str );
|
||||
if( outLatency < minLatency )
|
||||
{
|
||||
printf( "Latency below minimum of %d! Set to minimum!!!\n", minLatency );
|
||||
outLatency = minLatency;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* Stop sound until ENTER hit. */
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
}
|
||||
printf("A good setting for latency would be somewhat higher than\n");
|
||||
printf("the minimum latency that worked.\n");
|
||||
printf("PortAudio: Test finished.\n");
|
||||
Pa_Terminate();
|
||||
return 0;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return 1;
|
||||
}
|
||||
208
third_party/portaudio/test/patest1.c
vendored
Normal file
208
third_party/portaudio/test/patest1.c
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
/** @file patest1.c
|
||||
@ingroup test_src
|
||||
@brief Ring modulate the audio input with a sine wave for 20 seconds.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[100];
|
||||
int phase;
|
||||
int sampsToGo;
|
||||
}
|
||||
patest1data;
|
||||
|
||||
static int patest1Callback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
patest1data *data = (patest1data*)userData;
|
||||
float *in = (float*)inputBuffer;
|
||||
float *out = (float*)outputBuffer;
|
||||
int framesToCalc = framesPerBuffer;
|
||||
unsigned long i = 0;
|
||||
int finished;
|
||||
|
||||
if( data->sampsToGo < framesPerBuffer )
|
||||
{
|
||||
framesToCalc = data->sampsToGo;
|
||||
finished = paComplete;
|
||||
}
|
||||
else
|
||||
{
|
||||
finished = paContinue;
|
||||
}
|
||||
|
||||
for( ; i<framesToCalc; i++ )
|
||||
{
|
||||
*out++ = *in++ * data->sine[data->phase]; /* left */
|
||||
*out++ = *in++ * data->sine[data->phase++]; /* right */
|
||||
if( data->phase >= 100 )
|
||||
data->phase = 0;
|
||||
}
|
||||
|
||||
data->sampsToGo -= framesToCalc;
|
||||
|
||||
/* zero remainder of final buffer if not already done */
|
||||
for( ; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = 0; /* left */
|
||||
*out++ = 0; /* right */
|
||||
}
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]);
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
patest1data data;
|
||||
int i;
|
||||
PaStreamParameters inputParameters, outputParameters;
|
||||
const PaHostErrorInfo* herr;
|
||||
|
||||
printf("patest1.c\n"); fflush(stdout);
|
||||
printf("Ring modulate input for 20 seconds.\n"); fflush(stdout);
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<100; i++ )
|
||||
data.sine[i] = sin( ((double)i/100.) * M_PI * 2. );
|
||||
data.phase = 0;
|
||||
data.sampsToGo = SAMPLE_RATE * 20; /* 20 seconds. */
|
||||
|
||||
/* initialise portaudio subsystem */
|
||||
err = Pa_Initialize();
|
||||
|
||||
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
|
||||
if (inputParameters.device == paNoDevice) {
|
||||
fprintf(stderr, "Error: No input default device.\n");
|
||||
goto done;
|
||||
}
|
||||
inputParameters.channelCount = 2; /* stereo input */
|
||||
inputParameters.sampleFormat = paFloat32; /* 32 bit floating point input */
|
||||
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto done;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
&outputParameters,
|
||||
(double)SAMPLE_RATE, /* Samplerate in Hertz. */
|
||||
512, /* Small buffers */
|
||||
paClipOff, /* We won't output out of range samples so don't bother clipping them. */
|
||||
patest1Callback,
|
||||
&data );
|
||||
if( err != paNoError ) goto done;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto done;
|
||||
|
||||
printf( "Press any key to end.\n" ); fflush(stdout);
|
||||
|
||||
getc( stdin ); /* wait for input before exiting */
|
||||
|
||||
err = Pa_AbortStream( stream );
|
||||
if( err != paNoError ) goto done;
|
||||
|
||||
printf( "Waiting for stream to complete...\n" );
|
||||
|
||||
/* sleep until playback has finished */
|
||||
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(1000);
|
||||
if( err < 0 ) goto done;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto done;
|
||||
|
||||
done:
|
||||
Pa_Terminate();
|
||||
|
||||
if( err != paNoError )
|
||||
{
|
||||
fprintf( stderr, "An error occurred while using portaudio\n" );
|
||||
if( err == paUnanticipatedHostError )
|
||||
{
|
||||
fprintf( stderr, " unanticipated host error.\n");
|
||||
herr = Pa_GetLastHostErrorInfo();
|
||||
if (herr)
|
||||
{
|
||||
fprintf( stderr, " Error number: %ld\n", herr->errorCode );
|
||||
if (herr->errorText)
|
||||
fprintf( stderr, " Error text: %s\n", herr->errorText );
|
||||
}
|
||||
else
|
||||
fprintf( stderr, " Pa_GetLastHostErrorInfo() failed!\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( stderr, " Error number: %d\n", err );
|
||||
fprintf( stderr, " Error text: %s\n", Pa_GetErrorText( err ) );
|
||||
}
|
||||
|
||||
err = 1; /* Always return 0 or 1, but no other return codes. */
|
||||
}
|
||||
|
||||
printf( "bye\n" );
|
||||
|
||||
return err;
|
||||
}
|
||||
206
third_party/portaudio/test/patest_buffer.c
vendored
Normal file
206
third_party/portaudio/test/patest_buffer.c
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
/** @file patest_buffer.c
|
||||
@ingroup test_src
|
||||
@brief Test opening streams with different buffer sizes.
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
#define NUM_SECONDS (3)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (200)
|
||||
|
||||
#define BUFFER_TABLE 14
|
||||
long buffer_table[] = {paFramesPerBufferUnspecified,16,32,64,128,200,256,500,512,600,723,1000,1024,2345};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
unsigned int sampsToGo;
|
||||
}
|
||||
paTestData;
|
||||
PaError TestOnce( int buffersize, PaDeviceIndex );
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patest1Callback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
short *out = (short*)outputBuffer;
|
||||
unsigned int i;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent "unused variable" warnings. */
|
||||
|
||||
if( data->sampsToGo < framesPerBuffer )
|
||||
{
|
||||
/* final buffer... */
|
||||
|
||||
for( i=0; i<data->sampsToGo; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
/* zero remainder of final buffer */
|
||||
for( ; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = 0; /* left */
|
||||
*out++ = 0; /* right */
|
||||
}
|
||||
|
||||
finished = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
data->sampsToGo -= framesPerBuffer;
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(int argc, char **args);
|
||||
int main(int argc, char **args)
|
||||
{
|
||||
int i;
|
||||
int device = -1;
|
||||
PaError err;
|
||||
printf("Test opening streams with different buffer sizes\n");
|
||||
if( argc > 1 ) {
|
||||
device=atoi( args[1] );
|
||||
printf("Using device number %d.\n\n", device );
|
||||
} else {
|
||||
printf("Using default device.\n\n" );
|
||||
}
|
||||
|
||||
for (i = 0 ; i < BUFFER_TABLE; i++)
|
||||
{
|
||||
printf("Buffer size %ld\n", buffer_table[i]);
|
||||
err = TestOnce(buffer_table[i], device);
|
||||
if( err < 0 ) return 0;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PaError TestOnce( int buffersize, PaDeviceIndex device )
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int totalSamps;
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
if( device == -1 )
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
else
|
||||
outputParameters.device = device ;
|
||||
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paInt16; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
buffersize, /* frames per buffer */
|
||||
(paClipOff | paDitherOff),
|
||||
patest1Callback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Waiting for sound to finish.\n");
|
||||
Pa_Sleep(1000*NUM_SECONDS);
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
return paNoError;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
fprintf( stderr, "Host Error message: %s\n", Pa_GetLastHostErrorInfo()->errorText );
|
||||
return err;
|
||||
}
|
||||
252
third_party/portaudio/test/patest_callbackstop.c
vendored
Normal file
252
third_party/portaudio/test/patest_callbackstop.c
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
/** @file patest_callbackstop.c
|
||||
@ingroup test_src
|
||||
@brief Test the paComplete callback result code.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (5)
|
||||
#define NUM_LOOPS (4)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (67)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int phase;
|
||||
unsigned long generatedFramesCount;
|
||||
volatile int callbackReturnedPaComplete;
|
||||
volatile int callbackInvokedAfterReturningPaComplete;
|
||||
char message[100];
|
||||
}
|
||||
TestData;
|
||||
|
||||
/*
|
||||
This routine will be called by the PortAudio stream when audio is needed.
|
||||
It may be called at interrupt level on some machines so don't do anything
|
||||
that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int TestCallback( const void *input, void *output,
|
||||
unsigned long frameCount,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
TestData *data = (TestData*)userData;
|
||||
float *out = (float*)output;
|
||||
unsigned long i;
|
||||
float x;
|
||||
|
||||
(void) input; /* Prevent unused variable warnings. */
|
||||
(void) timeInfo;
|
||||
(void) statusFlags;
|
||||
|
||||
|
||||
if( data->callbackReturnedPaComplete )
|
||||
data->callbackInvokedAfterReturningPaComplete = 1;
|
||||
|
||||
for( i=0; i<frameCount; i++ )
|
||||
{
|
||||
/* generate tone */
|
||||
|
||||
x = data->sine[ data->phase++ ];
|
||||
if( data->phase >= TABLE_SIZE )
|
||||
data->phase -= TABLE_SIZE;
|
||||
|
||||
*out++ = x; /* left */
|
||||
*out++ = x; /* right */
|
||||
}
|
||||
|
||||
data->generatedFramesCount += frameCount;
|
||||
if( data->generatedFramesCount >= (NUM_SECONDS * SAMPLE_RATE) )
|
||||
{
|
||||
data->callbackReturnedPaComplete = 1;
|
||||
return paComplete;
|
||||
}
|
||||
else
|
||||
{
|
||||
return paContinue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called by portaudio when playback is done.
|
||||
*/
|
||||
static void StreamFinished( void* userData )
|
||||
{
|
||||
TestData *data = (TestData *) userData;
|
||||
printf( "Stream Completed: %s\n", data->message );
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
TestData data;
|
||||
int i, j;
|
||||
|
||||
|
||||
printf( "PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER );
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice();
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* output will be in-range, so no need to clip */
|
||||
TestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
sprintf( data.message, "Loop: XX" );
|
||||
err = Pa_SetStreamFinishedCallback( stream, &StreamFinished );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Repeating test %d times.\n", NUM_LOOPS );
|
||||
|
||||
for( i=0; i < NUM_LOOPS; ++i )
|
||||
{
|
||||
data.phase = 0;
|
||||
data.generatedFramesCount = 0;
|
||||
data.callbackReturnedPaComplete = 0;
|
||||
data.callbackInvokedAfterReturningPaComplete = 0;
|
||||
sprintf( data.message, "Loop: %d", i );
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
|
||||
/* wait for the callback to complete generating NUM_SECONDS of tone */
|
||||
|
||||
do
|
||||
{
|
||||
Pa_Sleep( 500 );
|
||||
}
|
||||
while( !data.callbackReturnedPaComplete );
|
||||
|
||||
printf( "Callback returned paComplete.\n" );
|
||||
printf( "Waiting for buffers to finish playing...\n" );
|
||||
|
||||
/* wait for stream to become inactive,
|
||||
or for a timeout of approximately NUM_SECONDS
|
||||
*/
|
||||
|
||||
j = 0;
|
||||
while( (err = Pa_IsStreamActive( stream )) == 1 && j < NUM_SECONDS * 2 )
|
||||
{
|
||||
printf(".\n" );
|
||||
Pa_Sleep( 500 );
|
||||
++j;
|
||||
}
|
||||
|
||||
if( err < 0 )
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
else if( err == 1 )
|
||||
{
|
||||
printf( "TEST FAILED: Timed out waiting for buffers to finish playing.\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Buffers finished.\n" );
|
||||
}
|
||||
|
||||
if( data.callbackInvokedAfterReturningPaComplete )
|
||||
{
|
||||
printf( "TEST FAILED: Callback was invoked after returning paComplete.\n" );
|
||||
}
|
||||
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf( "sleeping for 1 second...\n" );
|
||||
Pa_Sleep( 1000 );
|
||||
}
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
190
third_party/portaudio/test/patest_clip.c
vendored
Normal file
190
third_party/portaudio/test/patest_clip.c
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
/** @file patest_clip.c
|
||||
@ingroup test_src
|
||||
@brief Play a sine wave for several seconds at an amplitude
|
||||
that would require clipping.
|
||||
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (4)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (200)
|
||||
|
||||
typedef struct paTestData
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
float amplitude;
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
PaError PlaySine( paTestData *data, unsigned long flags, float amplitude );
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int sineCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
float amplitude = data->amplitude;
|
||||
unsigned int i;
|
||||
(void) inputBuffer; /* Prevent "unused variable" warnings. */
|
||||
(void) timeInfo;
|
||||
(void) statusFlags;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = amplitude * data->sine[data->left_phase]; /* left */
|
||||
*out++ = amplitude * data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
|
||||
printf("PortAudio Test: output sine wave with and without clipping.\n");
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
printf("\nHalf amplitude. Should sound like sine wave.\n"); fflush(stdout);
|
||||
err = PlaySine( &data, paClipOff | paDitherOff, 0.5f );
|
||||
if( err < 0 ) goto error;
|
||||
|
||||
printf("\nFull amplitude. Should sound like sine wave.\n"); fflush(stdout);
|
||||
err = PlaySine( &data, paClipOff | paDitherOff, 0.999f );
|
||||
if( err < 0 ) goto error;
|
||||
|
||||
printf("\nOver range with clipping and dithering turned OFF. Should sound very nasty.\n");
|
||||
fflush(stdout);
|
||||
err = PlaySine( &data, paClipOff | paDitherOff, 1.1f );
|
||||
if( err < 0 ) goto error;
|
||||
|
||||
printf("\nOver range with clipping and dithering turned ON. Should sound smoother than previous.\n");
|
||||
fflush(stdout);
|
||||
err = PlaySine( &data, paNoFlag, 1.1f );
|
||||
if( err < 0 ) goto error;
|
||||
|
||||
printf("\nOver range with paClipOff but dithering ON.\n"
|
||||
"That forces clipping ON so it should sound the same as previous.\n");
|
||||
fflush(stdout);
|
||||
err = PlaySine( &data, paClipOff, 1.1f );
|
||||
if( err < 0 ) goto error;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return 1;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
PaError PlaySine( paTestData *data, unsigned long flags, float amplitude )
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
|
||||
data->left_phase = data->right_phase = 0;
|
||||
data->amplitude = amplitude;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
1024,
|
||||
flags,
|
||||
sineCallback,
|
||||
data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad( stream ) );
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
return paNoError;
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
395
third_party/portaudio/test/patest_converters.c
vendored
Normal file
395
third_party/portaudio/test/patest_converters.c
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
/** @file patest_converters.c
|
||||
@ingroup test_src
|
||||
@brief Tests the converter functions in pa_converters.c
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Link with pa_dither.c and pa_converters.c
|
||||
|
||||
see http://www.portaudio.com/trac/wiki/V19ConvertersStatus for a discussion of this.
|
||||
*/
|
||||
/*
|
||||
* $Id: $
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2008 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_converters.h"
|
||||
#include "pa_dither.h"
|
||||
#include "pa_types.h"
|
||||
#include "pa_endianness.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define MAX_PER_CHANNEL_FRAME_COUNT (2048)
|
||||
#define MAX_CHANNEL_COUNT (8)
|
||||
|
||||
|
||||
#define SAMPLE_FORMAT_COUNT (6)
|
||||
|
||||
static PaSampleFormat sampleFormats_[ SAMPLE_FORMAT_COUNT ] =
|
||||
{ paFloat32, paInt32, paInt24, paInt16, paInt8, paUInt8 }; /* all standard PA sample formats */
|
||||
|
||||
static const char* sampleFormatNames_[SAMPLE_FORMAT_COUNT] =
|
||||
{ "paFloat32", "paInt32", "paInt24", "paInt16", "paInt8", "paUInt8" };
|
||||
|
||||
|
||||
static const char* abbreviatedSampleFormatNames_[SAMPLE_FORMAT_COUNT] =
|
||||
{ "f32", "i32", "i24", "i16", " i8", "ui8" };
|
||||
|
||||
|
||||
PaError My_Pa_GetSampleSize( PaSampleFormat format );
|
||||
|
||||
/*
|
||||
available flags are paClipOff and paDitherOff
|
||||
clipping is usually applied for float -> int conversions
|
||||
dither is usually applied for all downconversions (ie anything but 8bit->8bit conversions
|
||||
*/
|
||||
|
||||
static int CanClip( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat )
|
||||
{
|
||||
if( sourceFormat == paFloat32 && destinationFormat != sourceFormat )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CanDither( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat )
|
||||
{
|
||||
if( sourceFormat < destinationFormat && sourceFormat != paInt8 )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void GenerateOneCycleSineReference( double *out, int frameCount, int strideFrames )
|
||||
{
|
||||
int i;
|
||||
for( i=0; i < frameCount; ++i ){
|
||||
*out = sin( ((double)i/(double)frameCount) * 2. * M_PI );
|
||||
out += strideFrames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void GenerateOneCycleSine( PaSampleFormat format, void *buffer, int frameCount, int strideFrames )
|
||||
{
|
||||
switch( format ){
|
||||
|
||||
case paFloat32:
|
||||
{
|
||||
int i;
|
||||
float *out = (float*)buffer;
|
||||
for( i=0; i < frameCount; ++i ){
|
||||
*out = (float).9 * sin( ((double)i/(double)frameCount) * 2. * M_PI );
|
||||
out += strideFrames;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case paInt32:
|
||||
{
|
||||
int i;
|
||||
PaInt32 *out = (PaInt32*)buffer;
|
||||
for( i=0; i < frameCount; ++i ){
|
||||
*out = (PaInt32)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7FFFFFFF);
|
||||
out += strideFrames;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case paInt24:
|
||||
{
|
||||
int i;
|
||||
unsigned char *out = (unsigned char*)buffer;
|
||||
for( i=0; i < frameCount; ++i ){
|
||||
signed long temp = (PaInt32)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7FFFFFFF);
|
||||
|
||||
#if defined(PA_LITTLE_ENDIAN)
|
||||
out[0] = (unsigned char)(temp >> 8) & 0xFF;
|
||||
out[1] = (unsigned char)(temp >> 16) & 0xFF;
|
||||
out[2] = (unsigned char)(temp >> 24) & 0xFF;
|
||||
#elif defined(PA_BIG_ENDIAN)
|
||||
out[0] = (unsigned char)(temp >> 24) & 0xFF;
|
||||
out[1] = (unsigned char)(temp >> 16) & 0xFF;
|
||||
out[2] = (unsigned char)(temp >> 8) & 0xFF;
|
||||
#endif
|
||||
out += 3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case paInt16:
|
||||
{
|
||||
int i;
|
||||
PaInt16 *out = (PaInt16*)buffer;
|
||||
for( i=0; i < frameCount; ++i ){
|
||||
*out = (PaInt16)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7FFF );
|
||||
out += strideFrames;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case paInt8:
|
||||
{
|
||||
int i;
|
||||
signed char *out = (signed char*)buffer;
|
||||
for( i=0; i < frameCount; ++i ){
|
||||
*out = (signed char)(.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ) * 0x7F );
|
||||
out += strideFrames;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case paUInt8:
|
||||
{
|
||||
int i;
|
||||
unsigned char *out = (unsigned char*)buffer;
|
||||
for( i=0; i < frameCount; ++i ){
|
||||
*out = (unsigned char)( .5 * (1. + (.9 * sin( ((double)i/(double)frameCount) * 2. * M_PI ))) * 0xFF );
|
||||
out += strideFrames;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int TestNonZeroPresent( void *buffer, int size )
|
||||
{
|
||||
char *p = (char*)buffer;
|
||||
int i;
|
||||
|
||||
for( i=0; i < size; ++i ){
|
||||
|
||||
if( *p != 0 )
|
||||
return 1;
|
||||
++p;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float MaximumAbsDifference( float* sourceBuffer, float* referenceBuffer, int count )
|
||||
{
|
||||
float result = 0;
|
||||
float difference;
|
||||
while( count-- ){
|
||||
difference = fabs( *sourceBuffer++ - *referenceBuffer++ );
|
||||
if( difference > result )
|
||||
result = difference;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main( const char **argv, int argc )
|
||||
{
|
||||
PaUtilTriangularDitherGenerator ditherState;
|
||||
PaUtilConverter *converter;
|
||||
void *destinationBuffer, *sourceBuffer;
|
||||
double *referenceBuffer;
|
||||
int sourceFormatIndex, destinationFormatIndex;
|
||||
PaSampleFormat sourceFormat, destinationFormat;
|
||||
PaStreamFlags flags;
|
||||
int passFailMatrix[SAMPLE_FORMAT_COUNT][SAMPLE_FORMAT_COUNT]; // [source][destination]
|
||||
float noiseAmplitudeMatrix[SAMPLE_FORMAT_COUNT][SAMPLE_FORMAT_COUNT]; // [source][destination]
|
||||
float amp;
|
||||
|
||||
#define FLAG_COMBINATION_COUNT (4)
|
||||
PaStreamFlags flagCombinations[FLAG_COMBINATION_COUNT] = { paNoFlag, paClipOff, paDitherOff, paClipOff | paDitherOff };
|
||||
const char *flagCombinationNames[FLAG_COMBINATION_COUNT] = { "paNoFlag", "paClipOff", "paDitherOff", "paClipOff | paDitherOff" };
|
||||
int flagCombinationIndex;
|
||||
|
||||
PaUtil_InitializeTriangularDitherState( &ditherState );
|
||||
|
||||
/* allocate more than enough space, we use sizeof(float) but we need to fit any 32 bit datum */
|
||||
|
||||
destinationBuffer = (void*)malloc( MAX_PER_CHANNEL_FRAME_COUNT * MAX_CHANNEL_COUNT * sizeof(float) );
|
||||
sourceBuffer = (void*)malloc( MAX_PER_CHANNEL_FRAME_COUNT * MAX_CHANNEL_COUNT * sizeof(float) );
|
||||
referenceBuffer = (void*)malloc( MAX_PER_CHANNEL_FRAME_COUNT * MAX_CHANNEL_COUNT * sizeof(float) );
|
||||
|
||||
|
||||
/* the first round of tests simply iterates through the buffer combinations testing
|
||||
that putting something in gives something out */
|
||||
|
||||
printf( "= Sine wave in, something out =\n" );
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
GenerateOneCycleSine( paFloat32, referenceBuffer, MAX_PER_CHANNEL_FRAME_COUNT, 1 );
|
||||
|
||||
for( flagCombinationIndex = 0; flagCombinationIndex < FLAG_COMBINATION_COUNT; ++flagCombinationIndex ){
|
||||
flags = flagCombinations[flagCombinationIndex];
|
||||
|
||||
printf( "\n" );
|
||||
printf( "== flags = %s ==\n", flagCombinationNames[flagCombinationIndex] );
|
||||
|
||||
for( sourceFormatIndex = 0; sourceFormatIndex < SAMPLE_FORMAT_COUNT; ++sourceFormatIndex ){
|
||||
for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){
|
||||
sourceFormat = sampleFormats_[sourceFormatIndex];
|
||||
destinationFormat = sampleFormats_[destinationFormatIndex];
|
||||
//printf( "%s -> %s ", sampleFormatNames_[ sourceFormatIndex ], sampleFormatNames_[ destinationFormatIndex ] );
|
||||
|
||||
converter = PaUtil_SelectConverter( sourceFormat, destinationFormat, flags );
|
||||
|
||||
/* source is a sinewave */
|
||||
GenerateOneCycleSine( sourceFormat, sourceBuffer, MAX_PER_CHANNEL_FRAME_COUNT, 1 );
|
||||
|
||||
/* zero destination */
|
||||
memset( destinationBuffer, 0, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( destinationFormat ) );
|
||||
|
||||
(*converter)( destinationBuffer, 1, sourceBuffer, 1, MAX_PER_CHANNEL_FRAME_COUNT, &ditherState );
|
||||
|
||||
/*
|
||||
Other ways we could test this would be:
|
||||
- pass a constant, check for a constant (wouldn't work with dither)
|
||||
- pass alternating +/-, check for the same...
|
||||
*/
|
||||
if( TestNonZeroPresent( destinationBuffer, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( destinationFormat ) ) ){
|
||||
//printf( "PASSED\n" );
|
||||
passFailMatrix[sourceFormatIndex][destinationFormatIndex] = 1;
|
||||
}else{
|
||||
//printf( "FAILED\n" );
|
||||
passFailMatrix[sourceFormatIndex][destinationFormatIndex] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* try to measure the noise floor (comparing output signal to a float32 sine wave) */
|
||||
|
||||
if( passFailMatrix[sourceFormatIndex][destinationFormatIndex] ){
|
||||
|
||||
/* convert destination back to paFloat32 into source */
|
||||
converter = PaUtil_SelectConverter( destinationFormat, paFloat32, paNoFlag );
|
||||
|
||||
memset( sourceBuffer, 0, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( paFloat32 ) );
|
||||
(*converter)( sourceBuffer, 1, destinationBuffer, 1, MAX_PER_CHANNEL_FRAME_COUNT, &ditherState );
|
||||
|
||||
if( TestNonZeroPresent( sourceBuffer, MAX_PER_CHANNEL_FRAME_COUNT * My_Pa_GetSampleSize( paFloat32 ) ) ){
|
||||
|
||||
noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex] = MaximumAbsDifference( (float*)sourceBuffer, (float*)referenceBuffer, MAX_PER_CHANNEL_FRAME_COUNT );
|
||||
|
||||
}else{
|
||||
/* can't test noise floor because there is no conversion from dest format to float available */
|
||||
noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex] = -1; // mark as failed
|
||||
}
|
||||
}else{
|
||||
noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex] = -1; // mark as failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
printf( "=== Output contains non-zero data ===\n" );
|
||||
printf( "Key: . - pass, X - fail\n" );
|
||||
printf( "{{{\n" ); // trac preformated text tag
|
||||
printf( "in| out: " );
|
||||
for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){
|
||||
printf( " %s ", abbreviatedSampleFormatNames_[destinationFormatIndex] );
|
||||
}
|
||||
printf( "\n" );
|
||||
|
||||
for( sourceFormatIndex = 0; sourceFormatIndex < SAMPLE_FORMAT_COUNT; ++sourceFormatIndex ){
|
||||
printf( "%s ", abbreviatedSampleFormatNames_[sourceFormatIndex] );
|
||||
for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){
|
||||
printf( " %s ", (passFailMatrix[sourceFormatIndex][destinationFormatIndex])? " ." : " X" );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( "}}}\n" ); // trac preformated text tag
|
||||
|
||||
printf( "\n" );
|
||||
printf( "=== Combined dynamic range (src->dest->float32) ===\n" );
|
||||
printf( "Key: Noise amplitude in dBfs, X - fail (either above failed or dest->float32 failed)\n" );
|
||||
printf( "{{{\n" ); // trac preformated text tag
|
||||
printf( "in| out: " );
|
||||
for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){
|
||||
printf( " %s ", abbreviatedSampleFormatNames_[destinationFormatIndex] );
|
||||
}
|
||||
printf( "\n" );
|
||||
|
||||
for( sourceFormatIndex = 0; sourceFormatIndex < SAMPLE_FORMAT_COUNT; ++sourceFormatIndex ){
|
||||
printf( " %s ", abbreviatedSampleFormatNames_[sourceFormatIndex] );
|
||||
for( destinationFormatIndex = 0; destinationFormatIndex < SAMPLE_FORMAT_COUNT; ++destinationFormatIndex ){
|
||||
amp = noiseAmplitudeMatrix[sourceFormatIndex][destinationFormatIndex];
|
||||
if( amp < 0. )
|
||||
printf( " X " );
|
||||
else
|
||||
printf( " % 6.1f ", 20.*log10(amp) );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
printf( "}}}\n" ); // trac preformated text tag
|
||||
}
|
||||
|
||||
|
||||
free( destinationBuffer );
|
||||
free( sourceBuffer );
|
||||
free( referenceBuffer );
|
||||
}
|
||||
|
||||
// copied here for now otherwise we need to include the world just for this function.
|
||||
PaError My_Pa_GetSampleSize( PaSampleFormat format )
|
||||
{
|
||||
int result;
|
||||
|
||||
switch( format & ~paNonInterleaved )
|
||||
{
|
||||
|
||||
case paUInt8:
|
||||
case paInt8:
|
||||
result = 1;
|
||||
break;
|
||||
|
||||
case paInt16:
|
||||
result = 2;
|
||||
break;
|
||||
|
||||
case paInt24:
|
||||
result = 3;
|
||||
break;
|
||||
|
||||
case paFloat32:
|
||||
case paInt32:
|
||||
result = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
result = paSampleFormatNotSupported;
|
||||
break;
|
||||
}
|
||||
|
||||
return (PaError) result;
|
||||
}
|
||||
190
third_party/portaudio/test/patest_dither.c
vendored
Normal file
190
third_party/portaudio/test/patest_dither.c
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
/** @file patest_dither.c
|
||||
@ingroup test_src
|
||||
@brief Attempt to hear difference between dithered and non-dithered signal.
|
||||
|
||||
This only has an effect if the native format is 16 bit.
|
||||
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (5)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (200)
|
||||
|
||||
typedef struct paTestData
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
float amplitude;
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int sineCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo *timeInfo,
|
||||
PaStreamCallbackFlags statusFlags, void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
float amplitude = data->amplitude;
|
||||
unsigned int i;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = amplitude * data->sine[data->left_phase]; /* left */
|
||||
*out++ = amplitude * data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
V18 version did not call Pa_Terminate() if Pa_Initialize() failed.
|
||||
This V19 version ALWAYS calls Pa_Terminate(). PS.
|
||||
*/
|
||||
PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude );
|
||||
PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude )
|
||||
{
|
||||
PaStream* stream;
|
||||
PaStreamParameters outputParameters;
|
||||
PaError err;
|
||||
|
||||
data->left_phase = data->right_phase = 0;
|
||||
data->amplitude = amplitude;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if (err != paNoError)
|
||||
goto done;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto done;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
|
||||
/* When you change this, also */
|
||||
/* adapt the callback routine! */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )
|
||||
->defaultLowOutputLatency; /* Low latency. */
|
||||
err = Pa_OpenStream( &stream,
|
||||
NULL, /* No input. */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
1024, /* frames per buffer */
|
||||
flags,
|
||||
sineCallback,
|
||||
(void*)data );
|
||||
if (err != paNoError)
|
||||
goto done;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if (err != paNoError)
|
||||
goto done;
|
||||
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad(stream));
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
done:
|
||||
Pa_Sleep( 250 ); /* Just a small silence. */
|
||||
Pa_Terminate();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaError err;
|
||||
paTestData DATA;
|
||||
int i;
|
||||
float amplitude = 4.0 / (1<<15);
|
||||
|
||||
printf("PortAudio Test: output EXTREMELY QUIET sine wave with and without dithering.\n");
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
DATA.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
printf("\nNo treatment..\n"); fflush(stdout);
|
||||
err = PlaySine( &DATA, paClipOff | paDitherOff, amplitude );
|
||||
if( err < 0 ) goto done;
|
||||
|
||||
printf("\nClip..\n");
|
||||
fflush(stdout);
|
||||
err = PlaySine( &DATA, paDitherOff, amplitude );
|
||||
if( err < 0 ) goto done;
|
||||
|
||||
printf("\nClip and Dither..\n");
|
||||
fflush(stdout);
|
||||
err = PlaySine( &DATA, paNoFlag, amplitude );
|
||||
done:
|
||||
if (err)
|
||||
{
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
err = 1; /* Though PlaySine() already called Pa_Terminate(), */
|
||||
} /* we may still call Pa_GetErrorText(). */
|
||||
else
|
||||
printf("\n(Don't forget to turn the VOLUME DOWN after listening so carefully.)\n");
|
||||
return err; /* 0 or 1. */
|
||||
}
|
||||
513
third_party/portaudio/test/patest_dsound_find_best_latency_params.c
vendored
Normal file
513
third_party/portaudio/test/patest_dsound_find_best_latency_params.c
vendored
Normal file
@@ -0,0 +1,513 @@
|
||||
/*
|
||||
* $Id: $
|
||||
* Portable Audio I/O Library
|
||||
* Windows DirectSound low level buffer user guided parameters search
|
||||
*
|
||||
* Copyright (c) 2010-2011 Ross Bencina
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#define _WIN32_WINNT 0x0501 /* for GetNativeSystemInfo */
|
||||
#include <windows.h>
|
||||
//#include <mmsystem.h> /* required when using pa_win_wmme.h */
|
||||
|
||||
#include <conio.h> /* for _getch */
|
||||
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_ds.h"
|
||||
|
||||
|
||||
#define DEFAULT_SAMPLE_RATE (44100.)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (2048)
|
||||
|
||||
#define CHANNEL_COUNT (2)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/* functions to query and print Windows version information */
|
||||
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process;
|
||||
|
||||
static BOOL IsWow64()
|
||||
{
|
||||
BOOL bIsWow64 = FALSE;
|
||||
|
||||
//IsWow64Process is not available on all supported versions of Windows.
|
||||
//Use GetModuleHandle to get a handle to the DLL that contains the function
|
||||
//and GetProcAddress to get a pointer to the function if available.
|
||||
|
||||
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
|
||||
GetModuleHandle(TEXT("kernel32")),"IsWow64Process" );
|
||||
|
||||
if(NULL != fnIsWow64Process)
|
||||
{
|
||||
if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
|
||||
{
|
||||
//handle error
|
||||
}
|
||||
}
|
||||
return bIsWow64;
|
||||
}
|
||||
|
||||
static void printWindowsVersionInfo( FILE *fp )
|
||||
{
|
||||
OSVERSIONINFOEX osVersionInfoEx;
|
||||
SYSTEM_INFO systemInfo;
|
||||
const char *osName = "Unknown";
|
||||
const char *osProductType = "";
|
||||
const char *processorArchitecture = "Unknown";
|
||||
|
||||
memset( &osVersionInfoEx, 0, sizeof(OSVERSIONINFOEX) );
|
||||
osVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
GetVersionEx( &osVersionInfoEx );
|
||||
|
||||
|
||||
if( osVersionInfoEx.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ){
|
||||
switch( osVersionInfoEx.dwMinorVersion ){
|
||||
case 0: osName = "Windows 95"; break;
|
||||
case 10: osName = "Windows 98"; break; // could also be 98SE (I've seen code discriminate based
|
||||
// on osInfo.Version.Revision.ToString() == "2222A")
|
||||
case 90: osName = "Windows Me"; break;
|
||||
}
|
||||
}else if( osVersionInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT ){
|
||||
switch( osVersionInfoEx.dwMajorVersion ){
|
||||
case 3: osName = "Windows NT 3.51"; break;
|
||||
case 4: osName = "Windows NT 4.0"; break;
|
||||
case 5: switch( osVersionInfoEx.dwMinorVersion ){
|
||||
case 0: osName = "Windows 2000"; break;
|
||||
case 1: osName = "Windows XP"; break;
|
||||
case 2:
|
||||
if( osVersionInfoEx.wSuiteMask & 0x00008000 /*VER_SUITE_WH_SERVER*/ ){
|
||||
osName = "Windows Home Server";
|
||||
}else{
|
||||
if( osVersionInfoEx.wProductType == VER_NT_WORKSTATION ){
|
||||
osName = "Windows XP Professional x64 Edition (?)";
|
||||
}else{
|
||||
if( GetSystemMetrics(/*SM_SERVERR2*/89) == 0 )
|
||||
osName = "Windows Server 2003";
|
||||
else
|
||||
osName = "Windows Server 2003 R2";
|
||||
}
|
||||
}break;
|
||||
}break;
|
||||
case 6:switch( osVersionInfoEx.dwMinorVersion ){
|
||||
case 0:
|
||||
if( osVersionInfoEx.wProductType == VER_NT_WORKSTATION )
|
||||
osName = "Windows Vista";
|
||||
else
|
||||
osName = "Windows Server 2008";
|
||||
break;
|
||||
case 1:
|
||||
if( osVersionInfoEx.wProductType == VER_NT_WORKSTATION )
|
||||
osName = "Windows 7";
|
||||
else
|
||||
osName = "Windows Server 2008 R2";
|
||||
break;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
if(osVersionInfoEx.dwMajorVersion == 4)
|
||||
{
|
||||
if(osVersionInfoEx.wProductType == VER_NT_WORKSTATION)
|
||||
osProductType = "Workstation";
|
||||
else if(osVersionInfoEx.wProductType == VER_NT_SERVER)
|
||||
osProductType = "Server";
|
||||
}
|
||||
else if(osVersionInfoEx.dwMajorVersion == 5)
|
||||
{
|
||||
if(osVersionInfoEx.wProductType == VER_NT_WORKSTATION)
|
||||
{
|
||||
if((osVersionInfoEx.wSuiteMask & VER_SUITE_PERSONAL) == VER_SUITE_PERSONAL)
|
||||
osProductType = "Home Edition"; // Windows XP Home Edition
|
||||
else
|
||||
osProductType = "Professional"; // Windows XP / Windows 2000 Professional
|
||||
}
|
||||
else if(osVersionInfoEx.wProductType == VER_NT_SERVER)
|
||||
{
|
||||
if(osVersionInfoEx.dwMinorVersion == 0)
|
||||
{
|
||||
if((osVersionInfoEx.wSuiteMask & VER_SUITE_DATACENTER) == VER_SUITE_DATACENTER)
|
||||
osProductType = "Datacenter Server"; // Windows 2000 Datacenter Server
|
||||
else if((osVersionInfoEx.wSuiteMask & VER_SUITE_ENTERPRISE) == VER_SUITE_ENTERPRISE)
|
||||
osProductType = "Advanced Server"; // Windows 2000 Advanced Server
|
||||
else
|
||||
osProductType = "Server"; // Windows 2000 Server
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((osVersionInfoEx.wSuiteMask & VER_SUITE_DATACENTER) == VER_SUITE_DATACENTER)
|
||||
osProductType = "Datacenter Edition"; // Windows Server 2003 Datacenter Edition
|
||||
else if((osVersionInfoEx.wSuiteMask & VER_SUITE_ENTERPRISE) == VER_SUITE_ENTERPRISE)
|
||||
osProductType = "Enterprise Edition"; // Windows Server 2003 Enterprise Edition
|
||||
else if((osVersionInfoEx.wSuiteMask & VER_SUITE_BLADE) == VER_SUITE_BLADE)
|
||||
osProductType = "Web Edition"; // Windows Server 2003 Web Edition
|
||||
else
|
||||
osProductType = "Standard Edition"; // Windows Server 2003 Standard Edition
|
||||
}
|
||||
}
|
||||
|
||||
memset( &systemInfo, 0, sizeof(SYSTEM_INFO) );
|
||||
GetNativeSystemInfo( &systemInfo );
|
||||
|
||||
if( systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
|
||||
processorArchitecture = "x86";
|
||||
else if( systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
|
||||
processorArchitecture = "x64";
|
||||
else if( systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
|
||||
processorArchitecture = "Itanium";
|
||||
|
||||
|
||||
fprintf( fp, "OS name and edition: %s %s\n", osName, osProductType );
|
||||
fprintf( fp, "OS version: %d.%d.%d %S\n",
|
||||
osVersionInfoEx.dwMajorVersion, osVersionInfoEx.dwMinorVersion,
|
||||
osVersionInfoEx.dwBuildNumber, osVersionInfoEx.szCSDVersion );
|
||||
fprintf( fp, "Processor architecture: %s\n", processorArchitecture );
|
||||
fprintf( fp, "WoW64 process: %s\n", IsWow64() ? "Yes" : "No" );
|
||||
}
|
||||
|
||||
static void printTimeAndDate( FILE *fp )
|
||||
{
|
||||
struct tm *local;
|
||||
time_t t;
|
||||
|
||||
t = time(NULL);
|
||||
local = localtime(&t);
|
||||
fprintf(fp, "Local time and date: %s", asctime(local));
|
||||
local = gmtime(&t);
|
||||
fprintf(fp, "UTC time and date: %s", asctime(local));
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
double phase;
|
||||
double phaseIncrement;
|
||||
volatile int fadeIn;
|
||||
volatile int fadeOut;
|
||||
double amp;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
static paTestData data;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i,j;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float x = data->sine[(int)data->phase];
|
||||
data->phase += data->phaseIncrement;
|
||||
if( data->phase >= TABLE_SIZE ){
|
||||
data->phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
x *= data->amp;
|
||||
if( data->fadeIn ){
|
||||
data->amp += .001;
|
||||
if( data->amp >= 1. )
|
||||
data->fadeIn = 0;
|
||||
}else if( data->fadeOut ){
|
||||
if( data->amp > 0 )
|
||||
data->amp -= .001;
|
||||
}
|
||||
|
||||
for( j = 0; j < CHANNEL_COUNT; ++j ){
|
||||
*out++ = x;
|
||||
}
|
||||
}
|
||||
|
||||
if( data->amp > 0 )
|
||||
return paContinue;
|
||||
else
|
||||
return paComplete;
|
||||
}
|
||||
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
|
||||
static int playUntilKeyPress( int deviceIndex, float sampleRate,
|
||||
int framesPerUserBuffer, int framesPerDSoundBuffer )
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaWinDirectSoundStreamInfo directSoundStreamInfo;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
int c;
|
||||
|
||||
outputParameters.device = deviceIndex;
|
||||
outputParameters.channelCount = CHANNEL_COUNT;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
|
||||
outputParameters.suggestedLatency = 0; /*Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;*/
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
directSoundStreamInfo.size = sizeof(PaWinDirectSoundStreamInfo);
|
||||
directSoundStreamInfo.hostApiType = paDirectSound;
|
||||
directSoundStreamInfo.version = 2;
|
||||
directSoundStreamInfo.flags = paWinDirectSoundUseLowLevelLatencyParameters;
|
||||
directSoundStreamInfo.framesPerBuffer = framesPerDSoundBuffer;
|
||||
outputParameters.hostApiSpecificStreamInfo = &directSoundStreamInfo;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
sampleRate,
|
||||
framesPerUserBuffer,
|
||||
paClipOff | paPrimeOutputBuffersUsingStreamCallback, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
data.amp = 0;
|
||||
data.fadeIn = 1;
|
||||
data.fadeOut = 0;
|
||||
data.phase = 0;
|
||||
data.phaseIncrement = 15 + ((rand()%100) / 10); // randomise pitch
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
do{
|
||||
printf( "Trying buffer size %d.\nIf it sounds smooth (without clicks or glitches) press 'y', if it sounds bad press 'n' ('q' to quit)\n", framesPerDSoundBuffer );
|
||||
c = tolower(_getch());
|
||||
if( c == 'q' ){
|
||||
Pa_Terminate();
|
||||
exit(0);
|
||||
}
|
||||
}while( c != 'y' && c != 'n' );
|
||||
|
||||
data.fadeOut = 1;
|
||||
while( Pa_IsStreamActive(stream) == 1 )
|
||||
Pa_Sleep( 100 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
return (c == 'y') ? YES : NO;
|
||||
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
static void usage( int dsoundHostApiIndex )
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf( stderr, "PortAudio DirectSound output latency user guided test\n" );
|
||||
fprintf( stderr, "Usage: x.exe dsound-device-index [sampleRate]\n" );
|
||||
fprintf( stderr, "Invalid device index. Use one of these:\n" );
|
||||
for( i=0; i < Pa_GetDeviceCount(); ++i ){
|
||||
|
||||
if( Pa_GetDeviceInfo(i)->hostApi == dsoundHostApiIndex && Pa_GetDeviceInfo(i)->maxOutputChannels > 0 )
|
||||
fprintf( stderr, "%d (%s)\n", i, Pa_GetDeviceInfo(i)->name );
|
||||
}
|
||||
Pa_Terminate();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
ideas:
|
||||
o- could be testing with 80% CPU load
|
||||
o- could test with different channel counts
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
PaError err;
|
||||
int i;
|
||||
int deviceIndex;
|
||||
int dsoundBufferSize, smallestWorkingBufferSize;
|
||||
int smallestWorkingBufferingLatencyFrames;
|
||||
int min, max, mid;
|
||||
int testResult;
|
||||
FILE *resultsFp;
|
||||
int dsoundHostApiIndex;
|
||||
const PaHostApiInfo *dsoundHostApiInfo;
|
||||
double sampleRate = DEFAULT_SAMPLE_RATE;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
dsoundHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( paDirectSound );
|
||||
dsoundHostApiInfo = Pa_GetHostApiInfo( dsoundHostApiIndex );
|
||||
|
||||
if( argc > 3 )
|
||||
usage(dsoundHostApiIndex);
|
||||
|
||||
deviceIndex = dsoundHostApiInfo->defaultOutputDevice;
|
||||
if( argc >= 2 ){
|
||||
deviceIndex = -1;
|
||||
if( sscanf( argv[1], "%d", &deviceIndex ) != 1 )
|
||||
usage(dsoundHostApiInfo);
|
||||
if( deviceIndex < 0 || deviceIndex >= Pa_GetDeviceCount() || Pa_GetDeviceInfo(deviceIndex)->hostApi != dsoundHostApiIndex ){
|
||||
usage(dsoundHostApiInfo);
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
|
||||
|
||||
if( argc >= 3 ){
|
||||
if( sscanf( argv[2], "%lf", &sampleRate ) != 1 )
|
||||
usage(dsoundHostApiIndex);
|
||||
}
|
||||
|
||||
printf( "Testing with sample rate %f.\n", (float)sampleRate );
|
||||
|
||||
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
data.phase = 0;
|
||||
|
||||
resultsFp = fopen( "results.txt", "at" );
|
||||
fprintf( resultsFp, "*** DirectSound smallest working output buffer sizes\n" );
|
||||
|
||||
printTimeAndDate( resultsFp );
|
||||
printWindowsVersionInfo( resultsFp );
|
||||
|
||||
fprintf( resultsFp, "audio device: %s\n", Pa_GetDeviceInfo( deviceIndex )->name );
|
||||
fflush( resultsFp );
|
||||
|
||||
fprintf( resultsFp, "Sample rate: %f\n", (float)sampleRate );
|
||||
fprintf( resultsFp, "Smallest working buffer size (frames), Smallest working buffering latency (frames), Smallest working buffering latency (Seconds)\n" );
|
||||
|
||||
|
||||
/*
|
||||
Binary search after Niklaus Wirth
|
||||
from http://en.wikipedia.org/wiki/Binary_search_algorithm#The_algorithm
|
||||
*/
|
||||
min = 1;
|
||||
max = (int)(sampleRate * .3); /* we assume that this size works 300ms */
|
||||
smallestWorkingBufferSize = 0;
|
||||
|
||||
do{
|
||||
mid = min + ((max - min) / 2);
|
||||
|
||||
dsoundBufferSize = mid;
|
||||
testResult = playUntilKeyPress( deviceIndex, sampleRate, 0, dsoundBufferSize );
|
||||
|
||||
if( testResult == YES ){
|
||||
max = mid - 1;
|
||||
smallestWorkingBufferSize = dsoundBufferSize;
|
||||
}else{
|
||||
min = mid + 1;
|
||||
}
|
||||
|
||||
}while( (min <= max) && (testResult == YES || testResult == NO) );
|
||||
|
||||
smallestWorkingBufferingLatencyFrames = smallestWorkingBufferSize; /* not strictly true, but we're using an unspecified callback size, so kind of */
|
||||
|
||||
printf( "Smallest working buffer size is: %d\n", smallestWorkingBufferSize );
|
||||
printf( "Corresponding to buffering latency of %d frames, or %f seconds.\n", smallestWorkingBufferingLatencyFrames, smallestWorkingBufferingLatencyFrames / sampleRate );
|
||||
|
||||
fprintf( resultsFp, "%d, %d, %f\n", smallestWorkingBufferSize, smallestWorkingBufferingLatencyFrames, smallestWorkingBufferingLatencyFrames / sampleRate );
|
||||
fflush( resultsFp );
|
||||
|
||||
|
||||
/* power of 2 test. iterate to the smallest power of two that works */
|
||||
|
||||
smallestWorkingBufferSize = 0;
|
||||
dsoundBufferSize = 64;
|
||||
|
||||
do{
|
||||
testResult = playUntilKeyPress( deviceIndex, sampleRate, 0, dsoundBufferSize );
|
||||
|
||||
if( testResult == YES ){
|
||||
smallestWorkingBufferSize = dsoundBufferSize;
|
||||
}else{
|
||||
dsoundBufferSize *= 2;
|
||||
}
|
||||
|
||||
}while( (dsoundBufferSize <= (int)(sampleRate * .3)) && testResult == NO );
|
||||
|
||||
smallestWorkingBufferingLatencyFrames = smallestWorkingBufferSize; /* not strictly true, but we're using an unspecified callback size, so kind of */
|
||||
|
||||
fprintf( resultsFp, "%d, %d, %f\n", smallestWorkingBufferSize, smallestWorkingBufferingLatencyFrames, smallestWorkingBufferingLatencyFrames / sampleRate );
|
||||
fflush( resultsFp );
|
||||
|
||||
|
||||
fprintf( resultsFp, "###\n" );
|
||||
fclose( resultsFp );
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the PortAudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
186
third_party/portaudio/test/patest_dsound_low_level_latency_params.c
vendored
Normal file
186
third_party/portaudio/test/patest_dsound_low_level_latency_params.c
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* $Id: $
|
||||
* Portable Audio I/O Library
|
||||
* Windows DirectSound low level buffer parameters test
|
||||
*
|
||||
* Copyright (c) 2011 Ross Bencina
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_ds.h"
|
||||
|
||||
#define NUM_SECONDS (6)
|
||||
#define SAMPLE_RATE (44100)
|
||||
|
||||
#define DSOUND_FRAMES_PER_HOST_BUFFER (256*2) //(440*10)
|
||||
|
||||
#define FRAMES_PER_BUFFER 256
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (2048)
|
||||
|
||||
#define CHANNEL_COUNT (2)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
double phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i,j;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float x = data->sine[(int)data->phase];
|
||||
data->phase += 20;
|
||||
if( data->phase >= TABLE_SIZE ){
|
||||
data->phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
for( j = 0; j < CHANNEL_COUNT; ++j ){
|
||||
*out++ = x;
|
||||
}
|
||||
}
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaWinDirectSoundStreamInfo dsoundStreamInfo;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int deviceIndex;
|
||||
|
||||
printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paDirectSound ) )->defaultOutputDevice;
|
||||
if( argc == 2 ){
|
||||
sscanf( argv[1], "%d", &deviceIndex );
|
||||
}
|
||||
|
||||
printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
data.phase = 0;
|
||||
|
||||
outputParameters.device = deviceIndex;
|
||||
outputParameters.channelCount = CHANNEL_COUNT;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
|
||||
outputParameters.suggestedLatency = 0; /*Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;*/
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
dsoundStreamInfo.size = sizeof(PaWinDirectSoundStreamInfo);
|
||||
dsoundStreamInfo.hostApiType = paDirectSound;
|
||||
dsoundStreamInfo.version = 2;
|
||||
dsoundStreamInfo.flags = paWinDirectSoundUseLowLevelLatencyParameters;
|
||||
dsoundStreamInfo.framesPerBuffer = DSOUND_FRAMES_PER_HOST_BUFFER;
|
||||
outputParameters.hostApiSpecificStreamInfo = &dsoundStreamInfo;
|
||||
|
||||
|
||||
if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){
|
||||
printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
|
||||
}else{
|
||||
printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
|
||||
}
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
204
third_party/portaudio/test/patest_dsound_surround.c
vendored
Normal file
204
third_party/portaudio/test/patest_dsound_surround.c
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* $Id: $
|
||||
* Portable Audio I/O Library
|
||||
* Windows DirectSound surround sound output test
|
||||
*
|
||||
* Copyright (c) 2007 Ross Bencina
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <windows.h> /* required when using pa_win_wmme.h */
|
||||
#include <mmsystem.h> /* required when using pa_win_wmme.h */
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_ds.h"
|
||||
|
||||
#define NUM_SECONDS (12)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (100)
|
||||
|
||||
#define CHANNEL_COUNT (6)
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int phase;
|
||||
int currentChannel;
|
||||
int cycleCount;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i,j;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
for( j = 0; j < CHANNEL_COUNT; ++j ){
|
||||
if( j == data->currentChannel && data->cycleCount < 4410 ){
|
||||
*out++ = data->sine[data->phase];
|
||||
data->phase += 1 + j; // play each channel at a different pitch so they can be distinguished
|
||||
if( data->phase >= TABLE_SIZE ){
|
||||
data->phase -= TABLE_SIZE;
|
||||
}
|
||||
}else{
|
||||
*out++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
data->cycleCount++;
|
||||
if( data->cycleCount > 44100 ){
|
||||
data->cycleCount = 0;
|
||||
|
||||
++data->currentChannel;
|
||||
if( data->currentChannel >= CHANNEL_COUNT )
|
||||
data->currentChannel -= CHANNEL_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaWinDirectSoundStreamInfo directSoundStreamInfo;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int deviceIndex;
|
||||
|
||||
printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paDirectSound ) )->defaultOutputDevice;
|
||||
if( argc == 2 ){
|
||||
sscanf( argv[1], "%d", &deviceIndex );
|
||||
}
|
||||
|
||||
printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
data.phase = 0;
|
||||
data.currentChannel = 0;
|
||||
data.cycleCount = 0;
|
||||
|
||||
outputParameters.device = deviceIndex;
|
||||
outputParameters.channelCount = CHANNEL_COUNT;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
/* it's not strictly necessary to provide a channelMask for surround sound
|
||||
output. But if you want to be sure which channel mask PortAudio will use
|
||||
then you should supply one */
|
||||
directSoundStreamInfo.size = sizeof(PaWinDirectSoundStreamInfo);
|
||||
directSoundStreamInfo.hostApiType = paDirectSound;
|
||||
directSoundStreamInfo.version = 1;
|
||||
directSoundStreamInfo.flags = paWinDirectSoundUseChannelMask;
|
||||
directSoundStreamInfo.channelMask = PAWIN_SPEAKER_5POINT1; /* request 5.1 output format */
|
||||
outputParameters.hostApiSpecificStreamInfo = &directSoundStreamInfo;
|
||||
|
||||
if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){
|
||||
printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
|
||||
}else{
|
||||
printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
|
||||
}
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
164
third_party/portaudio/test/patest_hang.c
vendored
Normal file
164
third_party/portaudio/test/patest_hang.c
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
/** @file patest_hang.c
|
||||
@ingroup test_src
|
||||
@brief Play a sine then hang audio callback to test watchdog.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (1024)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TWOPI (M_PI * 2.0)
|
||||
|
||||
typedef struct paTestData
|
||||
{
|
||||
int sleepFor;
|
||||
double phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
int finished = 0;
|
||||
double phaseInc = 0.02;
|
||||
double phase = data->phase;
|
||||
|
||||
(void) inputBuffer; /* Prevent unused argument warning. */
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
phase += phaseInc;
|
||||
if( phase > TWOPI ) phase -= TWOPI;
|
||||
/* This is not a very efficient way to calc sines. */
|
||||
*out++ = (float) sin( phase ); /* mono */
|
||||
}
|
||||
|
||||
if( data->sleepFor > 0 )
|
||||
{
|
||||
Pa_Sleep( data->sleepFor );
|
||||
}
|
||||
|
||||
data->phase = phase;
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStream* stream;
|
||||
PaStreamParameters outputParameters;
|
||||
PaError err;
|
||||
int i;
|
||||
paTestData data = {0};
|
||||
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER );
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 1; /* Mono output. */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point. */
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)
|
||||
->defaultLowOutputLatency;
|
||||
err = Pa_OpenStream(&stream,
|
||||
NULL, /* No input. */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* No out of range samples. */
|
||||
patestCallback,
|
||||
&data);
|
||||
if (err != paNoError) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* Gradually increase sleep time. */
|
||||
/* Was: for( i=0; i<10000; i+= 1000 ) */
|
||||
for(i=0; i <= 1000; i += 100)
|
||||
{
|
||||
printf("Sleep for %d milliseconds in audio callback.\n", i );
|
||||
data.sleepFor = i;
|
||||
Pa_Sleep( ((i<1000) ? 1000 : i) );
|
||||
}
|
||||
|
||||
printf("Suffer for 10 seconds.\n");
|
||||
Pa_Sleep( 10000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
236
third_party/portaudio/test/patest_in_overflow.c
vendored
Normal file
236
third_party/portaudio/test/patest_in_overflow.c
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/** @file patest_in_overflow.c
|
||||
@ingroup test_src
|
||||
@brief Count input overflows (using paInputOverflow flag) under
|
||||
overloaded and normal conditions.
|
||||
This test uses the same method to overload the stream as does
|
||||
patest_out_underflow.c -- it generates sine waves until the cpu load
|
||||
exceeds a certain level. However this test is only concerned with
|
||||
input and so doesn't output any sound.
|
||||
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2004 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define MAX_SINES (500)
|
||||
#define MAX_LOAD (1.2)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (512)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TWOPI (M_PI * 2.0)
|
||||
|
||||
typedef struct paTestData
|
||||
{
|
||||
int sineCount;
|
||||
double phases[MAX_SINES];
|
||||
int countOverflows;
|
||||
int inputOverflowCount;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float out; /* variable to hold dummy output */
|
||||
unsigned long i;
|
||||
int j;
|
||||
int finished = paContinue;
|
||||
(void) timeInfo; /* Prevent unused variable warning. */
|
||||
(void) inputBuffer; /* Prevent unused variable warning. */
|
||||
(void) outputBuffer; /* Prevent unused variable warning. */
|
||||
|
||||
if( data->countOverflows && (statusFlags & paInputOverflow) )
|
||||
data->inputOverflowCount++;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float output = 0.0;
|
||||
double phaseInc = 0.02;
|
||||
double phase;
|
||||
|
||||
for( j=0; j<data->sineCount; j++ )
|
||||
{
|
||||
/* Advance phase of next oscillator. */
|
||||
phase = data->phases[j];
|
||||
phase += phaseInc;
|
||||
if( phase > TWOPI ) phase -= TWOPI;
|
||||
|
||||
phaseInc *= 1.02;
|
||||
if( phaseInc > 0.5 ) phaseInc *= 0.5;
|
||||
|
||||
/* This is not a very efficient way to calc sines. */
|
||||
output += (float) sin( phase );
|
||||
data->phases[j] = phase;
|
||||
}
|
||||
/* this is an input-only stream so we don't actually use the output */
|
||||
out = (float) (output / data->sineCount);
|
||||
(void) out; /* suppress unused variable warning*/
|
||||
}
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters inputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
int safeSineCount, stressedSineCount;
|
||||
int safeOverflowCount, stressedOverflowCount;
|
||||
paTestData data = {0};
|
||||
double load;
|
||||
|
||||
|
||||
printf("PortAudio Test: input only, no sound output. Load callback by performing calculations, count input overflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
|
||||
if (inputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default input device.\n");
|
||||
goto error;
|
||||
}
|
||||
inputParameters.channelCount = 1; /* mono output */
|
||||
inputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
NULL, /* no output */
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Establishing load conditions...\n" );
|
||||
|
||||
/* Determine number of sines required to get to 50% */
|
||||
do
|
||||
{
|
||||
data.sineCount++;
|
||||
Pa_Sleep( 100 );
|
||||
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
|
||||
}
|
||||
while( load < 0.5 && data.sineCount < (MAX_SINES-1));
|
||||
|
||||
safeSineCount = data.sineCount;
|
||||
|
||||
/* Calculate target stress value then ramp up to that level*/
|
||||
stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
|
||||
if( stressedSineCount > MAX_SINES )
|
||||
stressedSineCount = MAX_SINES;
|
||||
for( ; data.sineCount < stressedSineCount; data.sineCount++ )
|
||||
{
|
||||
Pa_Sleep( 100 );
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load );
|
||||
}
|
||||
|
||||
printf("Counting overflows for 5 seconds.\n");
|
||||
data.countOverflows = 1;
|
||||
Pa_Sleep( 5000 );
|
||||
|
||||
stressedOverflowCount = data.inputOverflowCount;
|
||||
|
||||
data.countOverflows = 0;
|
||||
data.sineCount = safeSineCount;
|
||||
|
||||
printf("Resuming safe load...\n");
|
||||
Pa_Sleep( 1500 );
|
||||
data.inputOverflowCount = 0;
|
||||
Pa_Sleep( 1500 );
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
|
||||
|
||||
printf("Counting overflows for 5 seconds.\n");
|
||||
data.countOverflows = 1;
|
||||
Pa_Sleep( 5000 );
|
||||
|
||||
safeOverflowCount = data.inputOverflowCount;
|
||||
|
||||
printf("Stop stream.\n");
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
|
||||
if( stressedOverflowCount == 0 )
|
||||
printf("Test failed, no input overflows detected under stress.\n");
|
||||
else if( safeOverflowCount != 0 )
|
||||
printf("Test failed, %d unexpected overflows detected under safe load.\n", safeOverflowCount);
|
||||
else
|
||||
printf("Test passed, %d expected input overflows detected under stress, 0 unexpected overflows detected under safe load.\n", stressedOverflowCount );
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
343
third_party/portaudio/test/patest_jack_wasapi.c
vendored
Normal file
343
third_party/portaudio/test/patest_jack_wasapi.c
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
/** @file pa_test_jack_wasapi.c
|
||||
@ingroup test_src
|
||||
@brief Print out jack information for WASAPI endpoints
|
||||
@author Reid Bishop <rbish@attglobal.net>
|
||||
*/
|
||||
/*
|
||||
* $Id: pa_test_jack_wasapi.c 1368 2008-03-01 00:38:27Z rbishop $
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2010 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_wasapi.h"
|
||||
|
||||
|
||||
/*
|
||||
* Helper function to determine if a given enum is present in mask variable
|
||||
*
|
||||
*/
|
||||
static int IsInMask(int val, int val2)
|
||||
{
|
||||
return ((val & val2) == val2);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine enumerates through the ChannelMapping for the IJackDescription
|
||||
*/
|
||||
|
||||
static void EnumIJackChannels(int channelMapping)
|
||||
{
|
||||
printf("Channel Mapping: ");
|
||||
if(channelMapping == PAWIN_SPEAKER_DIRECTOUT)
|
||||
{
|
||||
printf("DIRECTOUT\n");
|
||||
return;
|
||||
}
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_LEFT))
|
||||
printf("FRONT_LEFT, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_RIGHT))
|
||||
printf("FRONT_RIGHT, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_CENTER))
|
||||
printf("FRONT_CENTER, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_LOW_FREQUENCY))
|
||||
printf("LOW_FREQUENCY, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_BACK_LEFT))
|
||||
printf("BACK_LEFT, ");
|
||||
if(IsInMask(channelMapping,PAWIN_SPEAKER_BACK_RIGHT))
|
||||
printf("BACK_RIGHT, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER))
|
||||
printf("FRONT_LEFT_OF_CENTER, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER))
|
||||
printf("FRONT_RIGHT_OF_CENTER, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_BACK_CENTER))
|
||||
printf("BACK_CENTER, ");
|
||||
if(IsInMask(channelMapping,PAWIN_SPEAKER_SIDE_LEFT))
|
||||
printf("SIDE_LEFT, ");
|
||||
if(IsInMask(channelMapping,PAWIN_SPEAKER_SIDE_RIGHT))
|
||||
printf("SIDE_RIGHT, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_CENTER))
|
||||
printf("TOP_CENTER, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_FRONT_LEFT))
|
||||
printf("TOP_FRONT_LEFT, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_FRONT_CENTER))
|
||||
printf("TOP_FRONT_CENTER, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_FRONT_RIGHT))
|
||||
printf("TOP_FRONT_RIGHT, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_BACK_LEFT))
|
||||
printf("TOP_BACK_LEFT, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_BACK_CENTER))
|
||||
printf("TOP_BACK_CENTER, ");
|
||||
if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_BACK_RIGHT))
|
||||
printf("TOP_BACK_RIGHT, ");
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine enumerates through the Jack Connection Types enums for IJackDescription
|
||||
*/
|
||||
static void EnumIJackConnectionType(int cType)
|
||||
{
|
||||
printf("Connection Type: ");
|
||||
switch(cType)
|
||||
{
|
||||
case eJackConnTypeUnknown:
|
||||
printf("eJackConnTypeUnknown");
|
||||
break;
|
||||
case eJackConnType3Point5mm:
|
||||
printf("eJackConnType3Point5mm");
|
||||
break;
|
||||
case eJackConnTypeQuarter:
|
||||
printf("eJackConnTypeQuarter");
|
||||
break;
|
||||
case eJackConnTypeAtapiInternal:
|
||||
printf("eJackConnTypeAtapiInternal");
|
||||
break;
|
||||
case eJackConnTypeRCA:
|
||||
printf("eJackConnTypeRCA");
|
||||
break;
|
||||
case eJackConnTypeOptical:
|
||||
printf("eJackConnTypeOptical");
|
||||
break;
|
||||
case eJackConnTypeOtherDigital:
|
||||
printf("eJackConnTypeOtherDigital");
|
||||
break;
|
||||
case eJackConnTypeOtherAnalog:
|
||||
printf("eJackConnTypeOtherAnalog");
|
||||
break;
|
||||
case eJackConnTypeMultichannelAnalogDIN:
|
||||
printf("eJackConnTypeMultichannelAnalogDIN");
|
||||
break;
|
||||
case eJackConnTypeXlrProfessional:
|
||||
printf("eJackConnTypeXlrProfessional");
|
||||
break;
|
||||
case eJackConnTypeRJ11Modem:
|
||||
printf("eJackConnTypeRJ11Modem");
|
||||
break;
|
||||
case eJackConnTypeCombination:
|
||||
printf("eJackConnTypeCombination");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine enumerates through the GeoLocation enums for the IJackDescription
|
||||
*/
|
||||
static void EnumIJackGeoLocation(int iVal)
|
||||
{
|
||||
printf("Geometric Location: ");
|
||||
switch(iVal)
|
||||
{
|
||||
case eJackGeoLocRear:
|
||||
printf("eJackGeoLocRear");
|
||||
break;
|
||||
case eJackGeoLocFront:
|
||||
printf("eJackGeoLocFront");
|
||||
break;
|
||||
case eJackGeoLocLeft:
|
||||
printf("eJackGeoLocLeft");
|
||||
break;
|
||||
case eJackGeoLocRight:
|
||||
printf("eJackGeoLocRight");
|
||||
break;
|
||||
case eJackGeoLocTop:
|
||||
printf("eJackGeoLocTop");
|
||||
break;
|
||||
case eJackGeoLocBottom:
|
||||
printf("eJackGeoLocBottom");
|
||||
break;
|
||||
case eJackGeoLocRearPanel:
|
||||
printf("eJackGeoLocRearPanel");
|
||||
break;
|
||||
case eJackGeoLocRiser:
|
||||
printf("eJackGeoLocRiser");
|
||||
break;
|
||||
case eJackGeoLocInsideMobileLid:
|
||||
printf("eJackGeoLocInsideMobileLid");
|
||||
break;
|
||||
case eJackGeoLocDrivebay:
|
||||
printf("eJackGeoLocDrivebay");
|
||||
break;
|
||||
case eJackGeoLocHDMI:
|
||||
printf("eJackGeoLocHDMI");
|
||||
break;
|
||||
case eJackGeoLocOutsideMobileLid:
|
||||
printf("eJackGeoLocOutsideMobileLid");
|
||||
break;
|
||||
case eJackGeoLocATAPI:
|
||||
printf("eJackGeoLocATAPI");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine enumerates through the GenLocation enums for the IJackDescription
|
||||
*/
|
||||
static void EnumIJackGenLocation(int iVal)
|
||||
{
|
||||
printf("General Location: ");
|
||||
switch(iVal)
|
||||
{
|
||||
case eJackGenLocPrimaryBox:
|
||||
printf("eJackGenLocPrimaryBox");
|
||||
break;
|
||||
case eJackGenLocInternal:
|
||||
printf("eJackGenLocInternal");
|
||||
break;
|
||||
case eJackGenLocSeparate:
|
||||
printf("eJackGenLocSeparate");
|
||||
break;
|
||||
case eJackGenLocOther:
|
||||
printf("eJackGenLocOther");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine enumerates through the PortConnection enums for the IJackDescription
|
||||
*/
|
||||
static void EnumIJackPortConnection(int iVal)
|
||||
{
|
||||
printf("Port Type: ");
|
||||
switch(iVal)
|
||||
{
|
||||
case eJackPortConnJack:
|
||||
printf("eJackPortConnJack");
|
||||
break;
|
||||
case eJackPortConnIntegratedDevice:
|
||||
printf("eJackPortConnIntegratedDevice");
|
||||
break;
|
||||
case eJackPortConnBothIntegratedAndJack:
|
||||
printf("eJackPortConnBothIntegratedAndJack");
|
||||
break;
|
||||
case eJackPortConnUnknown:
|
||||
printf("eJackPortConnUnknown");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine retrieves and parses the KSJACK_DESCRIPTION structure for
|
||||
* the provided device ID.
|
||||
*/
|
||||
static PaError GetJackInformation(int deviceId)
|
||||
{
|
||||
PaError err;
|
||||
int i;
|
||||
int jackCount = 0;
|
||||
PaWasapiJackDescription jackDesc;
|
||||
|
||||
err = PaWasapi_GetJackCount(deviceId, &jackCount);
|
||||
if( err != paNoError ) return err;
|
||||
|
||||
fprintf( stderr,"Number of Jacks: %d \n", jackCount );
|
||||
|
||||
for( i = 0; i<jackCount; i++ )
|
||||
{
|
||||
fprintf( stderr,"Jack #%d:\n", i );
|
||||
|
||||
err = PaWasapi_GetJackDescription(deviceId, i, &jackDesc);
|
||||
if( err != paNoError )
|
||||
{
|
||||
fprintf( stderr,"Failed getting description." );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Is connected: %s\n",(jackDesc.isConnected)?"true":"false");
|
||||
EnumIJackChannels(jackDesc.channelMapping);
|
||||
EnumIJackConnectionType(jackDesc.connectionType);
|
||||
EnumIJackGeoLocation(jackDesc.geoLocation);
|
||||
EnumIJackGenLocation(jackDesc.genLocation);
|
||||
EnumIJackPortConnection(jackDesc.portConnection);
|
||||
printf("Jack Color: 0x%06X\n", jackDesc.color);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaError err;
|
||||
const PaDeviceInfo *device;
|
||||
int i;
|
||||
int jackCount = 0;
|
||||
int isInput = 0;
|
||||
|
||||
printf("PortAudio Test: WASAPI Jack Configuration");
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* Find all WASAPI devices */
|
||||
for( i = 0; i < Pa_GetDeviceCount(); ++i )
|
||||
{
|
||||
device = Pa_GetDeviceInfo(i);
|
||||
if( Pa_GetDeviceInfo(i)->hostApi == Pa_HostApiTypeIdToHostApiIndex(paWASAPI) )
|
||||
{
|
||||
if( device->maxOutputChannels == 0 )
|
||||
{
|
||||
isInput = 1;
|
||||
}
|
||||
printf("------------------------------------------\n");
|
||||
printf("Device: %s",device->name);
|
||||
if(isInput)
|
||||
printf(" (Input) %d Channels\n",device->maxInputChannels);
|
||||
else
|
||||
printf(" (Output) %d Channels\n",device->maxOutputChannels);
|
||||
// Try to see if this WASAPI device can provide Jack information
|
||||
err = GetJackInformation(i);
|
||||
if( err != paNoError ) goto error;
|
||||
}
|
||||
}
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
193
third_party/portaudio/test/patest_latency.c
vendored
Normal file
193
third_party/portaudio/test/patest_latency.c
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
/** @file
|
||||
@ingroup test_src
|
||||
@brief Hear the latency caused by big buffers.
|
||||
Play a sine wave and change frequency based on letter input.
|
||||
@author Phil Burk <philburk@softsynth.com>, and Darren Gibbs
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice())
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
|
||||
#define MIN_FREQ (100.0f)
|
||||
#define CalcPhaseIncrement(freq) ((freq)/SAMPLE_RATE)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (400)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
|
||||
float phase_increment;
|
||||
float left_phase;
|
||||
float right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
float LookupSine( paTestData *data, float phase );
|
||||
/* Convert phase between and 1.0 to sine value
|
||||
* using linear interpolation.
|
||||
*/
|
||||
float LookupSine( paTestData *data, float phase )
|
||||
{
|
||||
float fIndex = phase*TABLE_SIZE;
|
||||
int index = (int) fIndex;
|
||||
float fract = fIndex - index;
|
||||
float lo = data->sine[index];
|
||||
float hi = data->sine[index+1];
|
||||
float val = lo + fract*(hi-lo);
|
||||
return val;
|
||||
}
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
int i;
|
||||
|
||||
(void) inputBuffer; /* Prevent unused variable warning. */
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = LookupSine(data, data->left_phase); /* left */
|
||||
*out++ = LookupSine(data, data->right_phase); /* right */
|
||||
data->left_phase += data->phase_increment;
|
||||
if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f;
|
||||
data->right_phase += (data->phase_increment * 1.5f); /* fifth above */
|
||||
if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStream *stream;
|
||||
PaStreamParameters outputParameters;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int done = 0;
|
||||
|
||||
printf("PortAudio Test: enter letter then hit ENTER.\n" );
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = 0.90f * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point. */
|
||||
data.left_phase = data.right_phase = 0.0;
|
||||
data.phase_increment = CalcPhaseIncrement(MIN_FREQ);
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
|
||||
|
||||
outputParameters.device = OUTPUT_DEVICE;
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
printf("Requested output latency = %.4f seconds.\n", outputParameters.suggestedLatency );
|
||||
printf("%d frames per buffer.\n.", FRAMES_PER_BUFFER );
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Play ASCII keyboard. Hit 'q' to stop. (Use RETURN key on Mac)\n");
|
||||
fflush(stdout);
|
||||
while ( !done )
|
||||
{
|
||||
float freq;
|
||||
int index;
|
||||
char c;
|
||||
do
|
||||
{
|
||||
c = getchar();
|
||||
}
|
||||
while( c < ' '); /* Strip white space and control chars. */
|
||||
|
||||
if( c == 'q' ) done = 1;
|
||||
index = c % 26;
|
||||
freq = MIN_FREQ + (index * 40.0);
|
||||
data.phase_increment = CalcPhaseIncrement(freq);
|
||||
}
|
||||
printf("Call Pa_StopStream()\n");
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
185
third_party/portaudio/test/patest_leftright.c
vendored
Normal file
185
third_party/portaudio/test/patest_leftright.c
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/** @file patest_leftright.c
|
||||
@ingroup test_src
|
||||
@brief Play different tone sine waves that
|
||||
alternate between left and right channel.
|
||||
|
||||
The low tone should be on the left channel.
|
||||
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (8)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (512)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (200)
|
||||
#define BALANCE_DELTA (0.001)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
float targetBalance; // 0.0 = left, 1.0 = right
|
||||
float currentBalance;
|
||||
} paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer,
|
||||
void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
int finished = 0;
|
||||
/* Prevent unused variable warnings. */
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
// Smoothly pan between left and right.
|
||||
if( data->currentBalance < data->targetBalance )
|
||||
{
|
||||
data->currentBalance += BALANCE_DELTA;
|
||||
}
|
||||
else if( data->currentBalance > data->targetBalance )
|
||||
{
|
||||
data->currentBalance -= BALANCE_DELTA;
|
||||
}
|
||||
// Apply left/right balance.
|
||||
*out++ = data->sine[data->left_phase] * (1.0f - data->currentBalance); /* left */
|
||||
*out++ = data->sine[data->right_phase] * data->currentBalance; /* right */
|
||||
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStream *stream;
|
||||
PaStreamParameters outputParameters;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
printf("Play different tone sine waves that alternate between left and right channel.\n");
|
||||
printf("The low tone should be on the left channel.\n");
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
data.currentBalance = 0.0;
|
||||
data.targetBalance = 0.0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream( &stream,
|
||||
NULL, /* No input. */
|
||||
&outputParameters, /* As above. */
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for several seconds.\n");
|
||||
for( i=0; i<4; i++ )
|
||||
{
|
||||
printf("Hear low sound on left side.\n");
|
||||
data.targetBalance = 0.01;
|
||||
Pa_Sleep( 1000 );
|
||||
|
||||
printf("Hear high sound on right side.\n");
|
||||
data.targetBalance = 0.99;
|
||||
Pa_Sleep( 1000 );
|
||||
}
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
151
third_party/portaudio/test/patest_longsine.c
vendored
Normal file
151
third_party/portaudio/test/patest_longsine.c
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/** @file patest_longsine.c
|
||||
@ingroup test_src
|
||||
@brief Play a sine wave until ENTER hit.
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback(const void* inputBuffer,
|
||||
void* outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void* userData)
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned int i;
|
||||
(void) inputBuffer; /* Prevent unused argument warning. */
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
printf("PortAudio Test: output sine wave.\n");
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream( &stream,
|
||||
NULL, /* No input. */
|
||||
&outputParameters, /* As above. */
|
||||
SAMPLE_RATE,
|
||||
256, /* Frames per buffer. */
|
||||
paClipOff, /* No out of range samples expected. */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Hit ENTER to stop program.\n");
|
||||
getchar();
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
210
third_party/portaudio/test/patest_many.c
vendored
Normal file
210
third_party/portaudio/test/patest_many.c
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
/** @file patest_many.c
|
||||
@ingroup test_src
|
||||
@brief Start and stop the PortAudio Driver multiple times.
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
#define NUM_SECONDS (1)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
short sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
unsigned int sampsToGo;
|
||||
}
|
||||
paTestData;
|
||||
PaError TestOnce( void );
|
||||
static int patest1Callback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData );
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patest1Callback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
short *out = (short*)outputBuffer;
|
||||
unsigned int i;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent "unused variable" warnings. */
|
||||
|
||||
if( data->sampsToGo < framesPerBuffer )
|
||||
{
|
||||
/* final buffer... */
|
||||
|
||||
for( i=0; i<data->sampsToGo; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
/* zero remainder of final buffer */
|
||||
for( ; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = 0; /* left */
|
||||
*out++ = 0; /* right */
|
||||
}
|
||||
|
||||
finished = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
data->sampsToGo -= framesPerBuffer;
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
/*******************************************************************/
|
||||
#ifdef MACINTOSH
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
PaError err;
|
||||
int numLoops = 10;
|
||||
printf("Loop %d times.\n", numLoops );
|
||||
for( i=0; i<numLoops; i++ )
|
||||
{
|
||||
printf("Loop %d out of %d.\n", i+1, numLoops );
|
||||
err = TestOnce();
|
||||
if( err < 0 ) return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int main(int argc, char **argv);
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
PaError err;
|
||||
int i, numLoops = 10;
|
||||
if( argc > 1 )
|
||||
{
|
||||
numLoops = atoi(argv[1]);
|
||||
}
|
||||
for( i=0; i<numLoops; i++ )
|
||||
{
|
||||
printf("Loop %d out of %d.\n", i+1, numLoops );
|
||||
err = TestOnce();
|
||||
if( err < 0 ) return 1;
|
||||
}
|
||||
printf("Test complete.\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
PaError TestOnce( void )
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int totalSamps;
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paInt16;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
1024, /* frames per buffer */
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patest1Callback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Waiting for sound to finish.\n");
|
||||
Pa_Sleep(1000);
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
return paNoError;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
216
third_party/portaudio/test/patest_maxsines.c
vendored
Normal file
216
third_party/portaudio/test/patest_maxsines.c
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
/** @file patest_maxsines.c
|
||||
@ingroup test_src
|
||||
@brief How many sine waves can we calculate and play in less than 80% CPU Load.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define MAX_SINES (2000)
|
||||
#define MAX_USAGE (0.5)
|
||||
#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 (1024)
|
||||
|
||||
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 0.0 and 1.0 to sine value
|
||||
* using linear interpolation.
|
||||
*/
|
||||
float LookupSine( paTestData *data, float phase );
|
||||
float LookupSine( paTestData *data, float phase )
|
||||
{
|
||||
float fIndex = phase*TABLE_SIZE;
|
||||
int index = (int) fIndex;
|
||||
float fract = fIndex - index;
|
||||
float lo = data->sine[index];
|
||||
float hi = data->sine[index+1];
|
||||
float val = lo + fract*(hi-lo);
|
||||
return val;
|
||||
}
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback(const void* inputBuffer,
|
||||
void* outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void* userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
float outSample;
|
||||
float scaler;
|
||||
int numForScale;
|
||||
unsigned long i;
|
||||
int j;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent unused argument warning. */
|
||||
|
||||
/* Determine amplitude scaling factor */
|
||||
numForScale = data->numSines;
|
||||
if( numForScale < 8 ) numForScale = 8; /* prevent pops at beginning */
|
||||
scaler = 1.0f / numForScale;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float output = 0.0;
|
||||
float phaseInc = MIN_PHASE_INC;
|
||||
float phase;
|
||||
for( j=0; j<data->numSines; j++ )
|
||||
{
|
||||
/* Advance phase of next oscillator. */
|
||||
phase = data->phases[j];
|
||||
phase += phaseInc;
|
||||
if( phase >= 1.0 ) phase -= 1.0;
|
||||
|
||||
output += LookupSine(data, phase);
|
||||
data->phases[j] = phase;
|
||||
|
||||
phaseInc *= 1.02f;
|
||||
if( phaseInc > MAX_PHASE_INC ) phaseInc = MIN_PHASE_INC;
|
||||
}
|
||||
|
||||
outSample = (float) (output * scaler);
|
||||
*out++ = outSample; /* Left */
|
||||
*out++ = outSample; /* Right */
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
PaStream* stream;
|
||||
PaStreamParameters outputParameters;
|
||||
PaError err;
|
||||
paTestData data = {0};
|
||||
double load;
|
||||
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* Stereo output. */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output. */
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)
|
||||
->defaultHighOutputLatency;
|
||||
err = Pa_OpenStream(&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* No out of range samples should occur. */
|
||||
patestCallback,
|
||||
&data);
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
/* Play an increasing number of sine waves until we hit MAX_USAGE */
|
||||
do {
|
||||
data.numSines += 10;
|
||||
Pa_Sleep(200);
|
||||
load = Pa_GetStreamCpuLoad(stream);
|
||||
printf("numSines = %d, CPU load = %f\n", data.numSines, load );
|
||||
fflush(stdout);
|
||||
} while((load < MAX_USAGE) && (data.numSines < MAX_SINES));
|
||||
|
||||
Pa_Sleep(2000); /* Stay for 2 seconds at max CPU. */
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
155
third_party/portaudio/test/patest_mono.c
vendored
Normal file
155
third_party/portaudio/test/patest_mono.c
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
/** @file patest_mono.c
|
||||
@ingroup test_src
|
||||
@brief Play a monophonic sine wave using the Portable Audio api for several seconds.
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Authors:
|
||||
* Ross Bencina <rossb@audiomulch.com>
|
||||
* Phil Burk <philburk@softsynth.com>
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (10)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define AMPLITUDE (0.8)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
#define OUTPUT_DEVICE Pa_GetDefaultOutputDevice()
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
int finished = 0;
|
||||
/* avoid unused variable warnings */
|
||||
(void) inputBuffer;
|
||||
(void) timeInfo;
|
||||
(void) statusFlags;
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->phase]; /* left */
|
||||
data->phase += 1;
|
||||
if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE;
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
printf("PortAudio Test: output MONO sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) (AMPLITUDE * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
|
||||
}
|
||||
data.phase = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = OUTPUT_DEVICE;
|
||||
outputParameters.channelCount = 1; /* MONO output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS ); fflush(stdout);
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
205
third_party/portaudio/test/patest_multi_sine.c
vendored
Normal file
205
third_party/portaudio/test/patest_multi_sine.c
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/** @file patest_multi_sine.c
|
||||
@ingroup test_src
|
||||
@brief Play a different sine wave on each channel.
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (128)
|
||||
#define FREQ_INCR (300.0 / SAMPLE_RATE)
|
||||
#define MAX_CHANNELS (64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short interleaved; /* Nonzero for interleaved / zero for non-interleaved. */
|
||||
int numChannels; /* Actually used. */
|
||||
double phases[MAX_CHANNELS]; /* Each channel gets its' own frequency. */
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback(const void* inputBuffer,
|
||||
void* outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void* userData)
|
||||
{
|
||||
int frameIndex, channelIndex;
|
||||
float** outputs = (float**)outputBuffer;
|
||||
paTestData* data = (paTestData*)userData;
|
||||
|
||||
(void) inputBuffer; /* Prevent unused arg warning. */
|
||||
if (data->interleaved)
|
||||
{
|
||||
float *out = (float*)outputBuffer; /* interleaved version */
|
||||
for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
|
||||
{
|
||||
for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
|
||||
{
|
||||
/* Output sine wave on every channel. */
|
||||
*out++ = (float) sin(data->phases[channelIndex]);
|
||||
|
||||
/* Play each channel at a higher frequency. */
|
||||
data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
|
||||
if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
|
||||
{
|
||||
for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
|
||||
{
|
||||
/* Output sine wave on every channel. */
|
||||
outputs[channelIndex][frameIndex] = (float) sin(data->phases[channelIndex]);
|
||||
|
||||
/* Play each channel at a higher frequency. */
|
||||
data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
|
||||
if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int test(short interleaved)
|
||||
{
|
||||
PaStream* stream;
|
||||
PaStreamParameters outputParameters;
|
||||
PaError err;
|
||||
const PaDeviceInfo* pdi;
|
||||
paTestData data;
|
||||
short n;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device, max channels. */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
return paInvalidDevice;
|
||||
}
|
||||
pdi = Pa_GetDeviceInfo(outputParameters.device);
|
||||
outputParameters.channelCount = pdi->maxOutputChannels;
|
||||
if (outputParameters.channelCount > MAX_CHANNELS)
|
||||
outputParameters.channelCount = MAX_CHANNELS;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = pdi->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
data.interleaved = interleaved;
|
||||
data.numChannels = outputParameters.channelCount;
|
||||
for (n = 0; n < data.numChannels; n++)
|
||||
data.phases[n] = 0.0; /* Phases wrap and maybe don't need initialisation. */
|
||||
printf("%d ", data.numChannels);
|
||||
if (interleaved)
|
||||
printf("interleaved ");
|
||||
else
|
||||
{
|
||||
printf(" non-interleaved ");
|
||||
outputParameters.sampleFormat |= paNonInterleaved;
|
||||
}
|
||||
printf("channels.\n");
|
||||
|
||||
err = Pa_OpenStream(&stream,
|
||||
NULL, /* No input. */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE, /* Sample rate. */
|
||||
FRAMES_PER_BUFFER, /* Frames per buffer. */
|
||||
paClipOff, /* Samples never out of range, no clipping. */
|
||||
patestCallback,
|
||||
&data);
|
||||
if (err == paNoError)
|
||||
{
|
||||
err = Pa_StartStream(stream);
|
||||
if (err == paNoError)
|
||||
{
|
||||
printf("Hit ENTER to stop this test.\n");
|
||||
getchar();
|
||||
err = Pa_StopStream(stream);
|
||||
}
|
||||
Pa_CloseStream( stream );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
PaError err;
|
||||
|
||||
printf("PortAudio Test: output sine wave on each channel.\n" );
|
||||
|
||||
err = Pa_Initialize();
|
||||
if (err != paNoError)
|
||||
goto done;
|
||||
|
||||
err = test(1); /* 1 means interleaved. */
|
||||
if (err != paNoError)
|
||||
goto done;
|
||||
|
||||
err = test(0); /* 0 means not interleaved. */
|
||||
if (err != paNoError)
|
||||
goto done;
|
||||
|
||||
printf("Test finished.\n");
|
||||
done:
|
||||
if (err)
|
||||
{
|
||||
fprintf(stderr, "An error occurred while using the portaudio stream\n");
|
||||
fprintf(stderr, "Error number: %d\n", err );
|
||||
fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
Pa_Terminate();
|
||||
return 0;
|
||||
}
|
||||
251
third_party/portaudio/test/patest_out_underflow.c
vendored
Normal file
251
third_party/portaudio/test/patest_out_underflow.c
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
/** @file patest_out_underflow.c
|
||||
@ingroup test_src
|
||||
@brief Count output underflows (using paOutputUnderflow flag)
|
||||
under overloaded and normal conditions.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2004 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define MAX_SINES (1000)
|
||||
#define MAX_LOAD (1.2)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (512)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TWOPI (M_PI * 2.0)
|
||||
|
||||
typedef struct paTestData
|
||||
{
|
||||
int sineCount;
|
||||
double phases[MAX_SINES];
|
||||
int countUnderflows;
|
||||
int outputUnderflowCount;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
int j;
|
||||
int finished = paContinue;
|
||||
(void) timeInfo; /* Prevent unused variable warning. */
|
||||
(void) inputBuffer; /* Prevent unused variable warning. */
|
||||
|
||||
|
||||
if( data->countUnderflows && (statusFlags & paOutputUnderflow) )
|
||||
{
|
||||
data->outputUnderflowCount++;
|
||||
}
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float output = 0.0;
|
||||
double phaseInc = 0.02;
|
||||
double phase;
|
||||
|
||||
for( j=0; j<data->sineCount; j++ )
|
||||
{
|
||||
/* Advance phase of next oscillator. */
|
||||
phase = data->phases[j];
|
||||
phase += phaseInc;
|
||||
if( phase > TWOPI ) phase -= TWOPI;
|
||||
|
||||
phaseInc *= 1.02;
|
||||
if( phaseInc > 0.5 ) phaseInc *= 0.5;
|
||||
|
||||
/* This is not a very efficient way to calc sines. */
|
||||
output += (float) sin( phase );
|
||||
data->phases[j] = phase;
|
||||
}
|
||||
*out++ = (float) (output / data->sineCount);
|
||||
}
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
int safeSineCount, stressedSineCount;
|
||||
int sineCount;
|
||||
int safeUnderflowCount, stressedUnderflowCount;
|
||||
paTestData data = {0};
|
||||
double load;
|
||||
double suggestedLatency;
|
||||
|
||||
|
||||
printf("PortAudio Test: output sine waves, count underflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 1; /* mono output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.suggestedLatency = suggestedLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Establishing load conditions...\n" );
|
||||
|
||||
/* Determine number of sines required to get to 50% */
|
||||
do
|
||||
{
|
||||
Pa_Sleep( 100 );
|
||||
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
|
||||
|
||||
if( load < 0.3 )
|
||||
{
|
||||
data.sineCount += 10;
|
||||
}
|
||||
else if( load < 0.4 )
|
||||
{
|
||||
data.sineCount += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.sineCount += 1;
|
||||
}
|
||||
}
|
||||
while( load < 0.5 && data.sineCount < (MAX_SINES-1));
|
||||
|
||||
safeSineCount = data.sineCount;
|
||||
|
||||
/* Calculate target stress value then ramp up to that level*/
|
||||
stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
|
||||
if( stressedSineCount > MAX_SINES )
|
||||
stressedSineCount = MAX_SINES;
|
||||
sineCount = data.sineCount;
|
||||
for( ; sineCount < stressedSineCount; sineCount+=4 )
|
||||
{
|
||||
data.sineCount = sineCount;
|
||||
Pa_Sleep( 100 );
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("STRESSING: sineCount = %d, CPU load = %f\n", sineCount, load );
|
||||
}
|
||||
|
||||
printf("Counting underflows for 2 seconds.\n");
|
||||
data.countUnderflows = 1;
|
||||
Pa_Sleep( 2000 );
|
||||
|
||||
stressedUnderflowCount = data.outputUnderflowCount;
|
||||
|
||||
data.countUnderflows = 0;
|
||||
data.sineCount = safeSineCount;
|
||||
|
||||
printf("Resuming safe load...\n");
|
||||
Pa_Sleep( 1500 );
|
||||
data.outputUnderflowCount = 0;
|
||||
Pa_Sleep( 1500 );
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
|
||||
|
||||
printf("Counting underflows for 5 seconds.\n");
|
||||
data.countUnderflows = 1;
|
||||
Pa_Sleep( 5000 );
|
||||
|
||||
safeUnderflowCount = data.outputUnderflowCount;
|
||||
|
||||
printf("Stop stream.\n");
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
|
||||
printf("suggestedLatency = %f\n", suggestedLatency);
|
||||
|
||||
// Report pass or fail
|
||||
if( stressedUnderflowCount == 0 )
|
||||
printf("Test FAILED, no output underflows detected under stress.\n");
|
||||
else
|
||||
printf("Test %s, %d expected output underflows detected under stress, "
|
||||
"%d unexpected underflows detected under safe load.\n",
|
||||
(safeUnderflowCount == 0) ? "PASSED" : "FAILED",
|
||||
stressedUnderflowCount, safeUnderflowCount );
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
234
third_party/portaudio/test/patest_prime.c
vendored
Normal file
234
third_party/portaudio/test/patest_prime.c
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
/** @file patest_prime.c
|
||||
@ingroup test_src
|
||||
@brief Test stream priming mode.
|
||||
@author Ross Bencina http://www.audiomulch.com/~rossb
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
|
||||
#define NUM_BEEPS (3)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define SAMPLE_PERIOD (1.0/44100.0)
|
||||
#define FRAMES_PER_BUFFER (256)
|
||||
#define BEEP_DURATION (400)
|
||||
#define IDLE_DURATION (SAMPLE_RATE*2) /* 2 seconds */
|
||||
#define SLEEP_MSEC (50)
|
||||
|
||||
#define STATE_BKG_IDLE (0)
|
||||
#define STATE_BKG_BEEPING (1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float leftPhase;
|
||||
float rightPhase;
|
||||
int state;
|
||||
int beepCountdown;
|
||||
int idleCountdown;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
static void InitializeTestData( paTestData *testData )
|
||||
{
|
||||
testData->leftPhase = 0;
|
||||
testData->rightPhase = 0;
|
||||
testData->state = STATE_BKG_BEEPING;
|
||||
testData->beepCountdown = BEEP_DURATION;
|
||||
testData->idleCountdown = IDLE_DURATION;
|
||||
}
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo *timeInfo,
|
||||
PaStreamCallbackFlags statusFlags, void *userData )
|
||||
{
|
||||
/* Cast data passed through stream to our structure. */
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned int i;
|
||||
int result = paContinue;
|
||||
|
||||
/* suppress unused parameter warnings */
|
||||
(void) inputBuffer;
|
||||
(void) timeInfo;
|
||||
(void) statusFlags;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
switch( data->state )
|
||||
{
|
||||
case STATE_BKG_IDLE:
|
||||
*out++ = 0.0; /* left */
|
||||
*out++ = 0.0; /* right */
|
||||
--data->idleCountdown;
|
||||
|
||||
if( data->idleCountdown <= 0 ) result = paComplete;
|
||||
break;
|
||||
|
||||
case STATE_BKG_BEEPING:
|
||||
if( data->beepCountdown <= 0 )
|
||||
{
|
||||
data->state = STATE_BKG_IDLE;
|
||||
*out++ = 0.0; /* left */
|
||||
*out++ = 0.0; /* right */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Play sawtooth wave. */
|
||||
*out++ = data->leftPhase; /* left */
|
||||
*out++ = data->rightPhase; /* right */
|
||||
/* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
|
||||
data->leftPhase += 0.01f;
|
||||
/* When signal reaches top, drop back down. */
|
||||
if( data->leftPhase >= 1.0f ) data->leftPhase -= 2.0f;
|
||||
/* higher pitch so we can distinguish left and right. */
|
||||
data->rightPhase += 0.03f;
|
||||
if( data->rightPhase >= 1.0f ) data->rightPhase -= 2.0f;
|
||||
}
|
||||
--data->beepCountdown;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
static PaError DoTest( int flags )
|
||||
{
|
||||
PaStream *stream;
|
||||
PaError err = paNoError;
|
||||
paTestData data;
|
||||
PaStreamParameters outputParameters;
|
||||
|
||||
InitializeTestData( &data );
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice();
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
outputParameters.sampleFormat = paFloat32;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
|
||||
|
||||
/* Open an audio I/O stream. */
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER, /* frames per buffer */
|
||||
paClipOff | flags, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("hear \"BEEP\"\n" );
|
||||
fflush(stdout);
|
||||
|
||||
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(SLEEP_MSEC);
|
||||
if( err < 0 ) goto error;
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
return err;
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaError err = paNoError;
|
||||
int i;
|
||||
|
||||
/* Initialize library before making any other calls. */
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("PortAudio Test: Testing stream playback with no priming.\n");
|
||||
printf("PortAudio Test: you should see BEEP before you hear it.\n");
|
||||
printf("BEEP %d times.\n", NUM_BEEPS );
|
||||
|
||||
for( i=0; i< NUM_BEEPS; ++i )
|
||||
{
|
||||
err = DoTest( 0 );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("PortAudio Test: Testing stream playback with priming.\n");
|
||||
printf("PortAudio Test: you should see BEEP around the same time you hear it.\n");
|
||||
for( i=0; i< NUM_BEEPS; ++i )
|
||||
{
|
||||
err = DoTest( paPrimeOutputBuffersUsingStreamCallback );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("Test finished.\n");
|
||||
|
||||
Pa_Terminate();
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
243
third_party/portaudio/test/patest_read_record.c
vendored
Normal file
243
third_party/portaudio/test/patest_read_record.c
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/** @file patest_read_record.c
|
||||
@ingroup test_src
|
||||
@brief Record input into an array; Save array to a file; Playback recorded
|
||||
data. Implemented using the blocking API (Pa_ReadStream(), Pa_WriteStream() )
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
@author Ross Bencina rossb@audiomulch.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
/* #define SAMPLE_RATE (17932) // Test failure to open with this value. */
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (1024)
|
||||
#define NUM_SECONDS (5)
|
||||
#define NUM_CHANNELS (2)
|
||||
/* #define DITHER_FLAG (paDitherOff) */
|
||||
#define DITHER_FLAG (0) /**/
|
||||
|
||||
/* Select sample format. */
|
||||
#if 1
|
||||
#define PA_SAMPLE_TYPE paFloat32
|
||||
typedef float SAMPLE;
|
||||
#define SAMPLE_SILENCE (0.0f)
|
||||
#define PRINTF_S_FORMAT "%.8f"
|
||||
#elif 1
|
||||
#define PA_SAMPLE_TYPE paInt16
|
||||
typedef short SAMPLE;
|
||||
#define SAMPLE_SILENCE (0)
|
||||
#define PRINTF_S_FORMAT "%d"
|
||||
#elif 0
|
||||
#define PA_SAMPLE_TYPE paInt8
|
||||
typedef char SAMPLE;
|
||||
#define SAMPLE_SILENCE (0)
|
||||
#define PRINTF_S_FORMAT "%d"
|
||||
#else
|
||||
#define PA_SAMPLE_TYPE paUInt8
|
||||
typedef unsigned char SAMPLE;
|
||||
#define SAMPLE_SILENCE (128)
|
||||
#define PRINTF_S_FORMAT "%d"
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters inputParameters, outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
SAMPLE *recordedSamples;
|
||||
int i;
|
||||
int totalFrames;
|
||||
int numSamples;
|
||||
int numBytes;
|
||||
SAMPLE max, average, val;
|
||||
|
||||
|
||||
printf("patest_read_record.c\n"); fflush(stdout);
|
||||
|
||||
totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
|
||||
numSamples = totalFrames * NUM_CHANNELS;
|
||||
|
||||
numBytes = numSamples * sizeof(SAMPLE);
|
||||
recordedSamples = (SAMPLE *) malloc( numBytes );
|
||||
if( recordedSamples == NULL )
|
||||
{
|
||||
printf("Could not allocate record array.\n");
|
||||
exit(1);
|
||||
}
|
||||
for( i=0; i<numSamples; i++ ) recordedSamples[i] = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
|
||||
if (inputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default input device.\n");
|
||||
goto error;
|
||||
}
|
||||
inputParameters.channelCount = NUM_CHANNELS;
|
||||
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
|
||||
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
/* Record some audio. -------------------------------------------- */
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
NULL, /* &outputParameters, */
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
NULL, /* no callback, use blocking API */
|
||||
NULL ); /* no callback, so no callback userData */
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Now recording!!\n"); fflush(stdout);
|
||||
|
||||
err = Pa_ReadStream( stream, recordedSamples, totalFrames );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* Measure maximum peak amplitude. */
|
||||
max = 0;
|
||||
average = 0;
|
||||
for( i=0; i<numSamples; i++ )
|
||||
{
|
||||
val = recordedSamples[i];
|
||||
if( val < 0 ) val = -val; /* ABS */
|
||||
if( val > max )
|
||||
{
|
||||
max = val;
|
||||
}
|
||||
average += val;
|
||||
}
|
||||
|
||||
average = average / numSamples;
|
||||
|
||||
printf("Sample max amplitude = "PRINTF_S_FORMAT"\n", max );
|
||||
printf("Sample average = "PRINTF_S_FORMAT"\n", average );
|
||||
/* Was as below. Better choose at compile time because this
|
||||
keeps generating compiler-warnings:
|
||||
if( PA_SAMPLE_TYPE == paFloat32 )
|
||||
{
|
||||
printf("sample max amplitude = %f\n", max );
|
||||
printf("sample average = %f\n", average );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("sample max amplitude = %d\n", max );
|
||||
printf("sample average = %d\n", average );
|
||||
}
|
||||
*/
|
||||
/* Write recorded data to a file. */
|
||||
#if 0
|
||||
{
|
||||
FILE *fid;
|
||||
fid = fopen("recorded.raw", "wb");
|
||||
if( fid == NULL )
|
||||
{
|
||||
printf("Could not open file.");
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite( recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
|
||||
fclose( fid );
|
||||
printf("Wrote data to 'recorded.raw'\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Playback recorded data. -------------------------------------------- */
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = NUM_CHANNELS;
|
||||
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
printf("Begin playback.\n"); fflush(stdout);
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
NULL, /* no callback, use blocking API */
|
||||
NULL ); /* no callback, so no callback userData */
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
if( stream )
|
||||
{
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Waiting for playback to finish.\n"); fflush(stdout);
|
||||
|
||||
err = Pa_WriteStream( stream, recordedSamples, totalFrames );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
printf("Done.\n"); fflush(stdout);
|
||||
}
|
||||
free( recordedSamples );
|
||||
|
||||
Pa_Terminate();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return -1;
|
||||
}
|
||||
86
third_party/portaudio/test/patest_ringmix.c
vendored
Normal file
86
third_party/portaudio/test/patest_ringmix.c
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/** @file patest_ringmix.c
|
||||
@ingroup test_src
|
||||
@brief Ring modulate inputs to left output, mix inputs to right output.
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
|
||||
#include "stdio.h"
|
||||
#include "portaudio.h"
|
||||
/* This will be called asynchronously by the PortAudio engine. */
|
||||
static int myCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
const float *in = (const float *) inputBuffer;
|
||||
float *out = (float *) outputBuffer;
|
||||
float leftInput, rightInput;
|
||||
unsigned int i;
|
||||
|
||||
/* Read input buffer, process data, and fill output buffer. */
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
leftInput = *in++; /* Get interleaved samples from input buffer. */
|
||||
rightInput = *in++;
|
||||
*out++ = leftInput * rightInput; /* ring modulation */
|
||||
*out++ = 0.5f * (leftInput + rightInput); /* mix */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Open a PortAudioStream to input and output audio data. */
|
||||
int main(void)
|
||||
{
|
||||
PaStream *stream;
|
||||
Pa_Initialize();
|
||||
Pa_OpenDefaultStream(
|
||||
&stream,
|
||||
2, 2, /* stereo input and output */
|
||||
paFloat32, 44100.0,
|
||||
64, /* 64 frames per buffer */
|
||||
myCallback, NULL );
|
||||
Pa_StartStream( stream );
|
||||
Pa_Sleep( 10000 ); /* Sleep for 10 seconds while processing. */
|
||||
Pa_StopStream( stream );
|
||||
Pa_CloseStream( stream );
|
||||
Pa_Terminate();
|
||||
return 0;
|
||||
}
|
||||
216
third_party/portaudio/test/patest_sine8.c
vendored
Normal file
216
third_party/portaudio/test/patest_sine8.c
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
/** @file patest_sine8.c
|
||||
@ingroup test_src
|
||||
@brief Test 8 bit data: play a sine wave for several seconds.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (8)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define TABLE_SIZE (200)
|
||||
#define TEST_UNSIGNED (0)
|
||||
|
||||
#if TEST_UNSIGNED
|
||||
#define TEST_FORMAT paUInt8
|
||||
typedef unsigned char sample_t;
|
||||
#define SILENCE ((sample_t)0x80)
|
||||
#else
|
||||
#define TEST_FORMAT paInt8
|
||||
typedef char sample_t;
|
||||
#define SILENCE ((sample_t)0x00)
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sample_t sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
unsigned int framesToGo;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
sample_t *out = (sample_t*)outputBuffer;
|
||||
int i;
|
||||
int framesToCalc;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent unused variable warnings. */
|
||||
|
||||
if( data->framesToGo < framesPerBuffer )
|
||||
{
|
||||
framesToCalc = data->framesToGo;
|
||||
data->framesToGo = 0;
|
||||
finished = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesToCalc = framesPerBuffer;
|
||||
data->framesToGo -= framesPerBuffer;
|
||||
}
|
||||
|
||||
for( i=0; i<framesToCalc; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
/* zero remainder of final buffer */
|
||||
for( ; i<(int)framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = SILENCE; /* left */
|
||||
*out++ = SILENCE; /* right */
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream* stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
PaTime streamOpened;
|
||||
int i, totalSamps;
|
||||
|
||||
#if TEST_UNSIGNED
|
||||
printf("PortAudio Test: output UNsigned 8 bit sine wave.\n");
|
||||
#else
|
||||
printf("PortAudio Test: output signed 8 bit sine wave.\n");
|
||||
#endif
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = SILENCE + (char) (127.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* Stereo output. */
|
||||
outputParameters.sampleFormat = TEST_FORMAT;
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
err = Pa_OpenStream( &stream,
|
||||
NULL, /* No input. */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
256, /* Frames per buffer. */
|
||||
paClipOff, /* We won't output out of range samples so don't bother clipping them. */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
streamOpened = Pa_GetStreamTime( stream ); /* Time in seconds when stream was opened (approx). */
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
/* Watch until sound is halfway finished. */
|
||||
/* (Was ( Pa_StreamTime( stream ) < (totalSamps/2) ) in V18. */
|
||||
while( (Pa_GetStreamTime( stream ) - streamOpened) < (PaTime)NUM_SECONDS / 2.0 )
|
||||
Pa_Sleep(10);
|
||||
|
||||
/* Stop sound. */
|
||||
printf("Stopping Stream.\n");
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
printf("Pause for 2 seconds.\n");
|
||||
Pa_Sleep( 2000 );
|
||||
|
||||
printf("Starting again.\n");
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
printf("Waiting for sound to finish.\n");
|
||||
|
||||
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
|
||||
Pa_Sleep(100);
|
||||
if( err < 0 )
|
||||
goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError )
|
||||
goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
190
third_party/portaudio/test/patest_sine_channelmaps.c
vendored
Normal file
190
third_party/portaudio/test/patest_sine_channelmaps.c
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* patest_sine_channelmaps.c
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
/** @file patest_sine_channelmaps.c
|
||||
@ingroup test_src
|
||||
@brief Plays sine waves using sme simple channel maps.
|
||||
Designed for use with CoreAudio, but should made to work with other APIs
|
||||
@author Bjorn Roche <bjorn@xowave.com>
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "pa_mac_core.h"
|
||||
#endif
|
||||
|
||||
#define NUM_SECONDS (5)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
#ifdef __APPLE__
|
||||
PaMacCoreStreamInfo macInfo;
|
||||
const SInt32 channelMap[4] = { -1, -1, 0, 1 };
|
||||
#endif
|
||||
int i;
|
||||
|
||||
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
printf("Output will be mapped to channels 2 and 3 instead of 0 and 1.\n");
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/** setup host specific info */
|
||||
#ifdef __APPLE__
|
||||
PaMacCore_SetupStreamInfo( &macInfo, paMacCorePlayNice );
|
||||
PaMacCore_SetupChannelMap( &macInfo, channelMap, 4 );
|
||||
|
||||
for( i=0; i<4; ++i )
|
||||
printf( "channel %d name: %s\n", i, PaMacCore_GetChannelName( Pa_GetDefaultOutputDevice(), i, false ) );
|
||||
#else
|
||||
printf( "Channel mapping not supported on this platform. Reverting to normal sine test.\n" );
|
||||
#endif
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
#ifdef __APPLE__
|
||||
outputParameters.hostApiSpecificStreamInfo = &macInfo;
|
||||
#else
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
#endif
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
203
third_party/portaudio/test/patest_sine_formats.c
vendored
Normal file
203
third_party/portaudio/test/patest_sine_formats.c
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/** @file patest_sine_formats.c
|
||||
@ingroup test_src
|
||||
@brief Play a sine wave for several seconds. Test various data formats.
|
||||
@author Phil Burk
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (10)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (512)
|
||||
#define LEFT_FREQ (SAMPLE_RATE/256.0) /* So we hit 1.0 */
|
||||
#define RIGHT_FREQ (500.0)
|
||||
#define AMPLITUDE (1.0)
|
||||
|
||||
/* Select ONE format for testing. */
|
||||
#define TEST_UINT8 (0)
|
||||
#define TEST_INT8 (0)
|
||||
#define TEST_INT16 (1)
|
||||
#define TEST_FLOAT32 (0)
|
||||
|
||||
#if TEST_UINT8
|
||||
#define TEST_FORMAT paUInt8
|
||||
typedef unsigned char SAMPLE_t;
|
||||
#define SAMPLE_ZERO (0x80)
|
||||
#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
|
||||
#define FORMAT_NAME "Unsigned 8 Bit"
|
||||
|
||||
#elif TEST_INT8
|
||||
#define TEST_FORMAT paInt8
|
||||
typedef char SAMPLE_t;
|
||||
#define SAMPLE_ZERO (0)
|
||||
#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
|
||||
#define FORMAT_NAME "Signed 8 Bit"
|
||||
|
||||
#elif TEST_INT16
|
||||
#define TEST_FORMAT paInt16
|
||||
typedef short SAMPLE_t;
|
||||
#define SAMPLE_ZERO (0)
|
||||
#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x)))
|
||||
#define FORMAT_NAME "Signed 16 Bit"
|
||||
|
||||
#elif TEST_FLOAT32
|
||||
#define TEST_FORMAT paFloat32
|
||||
typedef float SAMPLE_t;
|
||||
#define SAMPLE_ZERO (0.0)
|
||||
#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x))
|
||||
#define FORMAT_NAME "Float 32 Bit"
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double left_phase;
|
||||
double right_phase;
|
||||
unsigned int framesToGo;
|
||||
}
|
||||
paTestData;
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer,
|
||||
void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
SAMPLE_t *out = (SAMPLE_t *)outputBuffer;
|
||||
int i;
|
||||
int framesToCalc;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent unused variable warnings. */
|
||||
|
||||
if( data->framesToGo < framesPerBuffer )
|
||||
{
|
||||
framesToCalc = data->framesToGo;
|
||||
data->framesToGo = 0;
|
||||
finished = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesToCalc = framesPerBuffer;
|
||||
data->framesToGo -= framesPerBuffer;
|
||||
}
|
||||
|
||||
for( i=0; i<framesToCalc; i++ )
|
||||
{
|
||||
data->left_phase += (LEFT_FREQ / SAMPLE_RATE);
|
||||
if( data->left_phase > 1.0) data->left_phase -= 1.0;
|
||||
*out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. )));
|
||||
|
||||
data->right_phase += (RIGHT_FREQ / SAMPLE_RATE);
|
||||
if( data->right_phase > 1.0) data->right_phase -= 1.0;
|
||||
*out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. )));
|
||||
}
|
||||
/* zero remainder of final buffer */
|
||||
for( ; i<(int)framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = SAMPLE_ZERO; /* left */
|
||||
*out++ = SAMPLE_ZERO; /* right */
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStream *stream;
|
||||
PaStreamParameters outputParameters;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int totalSamps;
|
||||
|
||||
printf("PortAudio Test: output " FORMAT_NAME "\n");
|
||||
|
||||
data.left_phase = data.right_phase = 0.0;
|
||||
data.framesToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
|
||||
outputParameters.channelCount = 2; /* Stereo output */
|
||||
outputParameters.sampleFormat = TEST_FORMAT; /* Selected above. */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
err = Pa_OpenStream( &stream,
|
||||
NULL, /* No input. */
|
||||
&outputParameters, /* As above. */
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS );
|
||||
|
||||
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
|
||||
if( err < 0 ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
|
||||
printf("PortAudio Test Finished: " FORMAT_NAME "\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
182
third_party/portaudio/test/patest_sine_srate.c
vendored
Normal file
182
third_party/portaudio/test/patest_sine_srate.c
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* $Id: patest_sine.c 1097 2006-08-26 08:27:53Z rossb $
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
/** @file patest_sine_srate_mac.c
|
||||
@ingroup test_src
|
||||
@brief Plays sine waves at 44100 and 48000,
|
||||
and forces the hardware to change if this is a mac.
|
||||
Designed for use with CoreAudio.
|
||||
@author Bjorn Roche <bjorn@xowave.com>
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "pa_mac_core.h"
|
||||
#endif
|
||||
|
||||
#define NUM_SECONDS (5)
|
||||
#define SAMPLE_RATE1 (44100)
|
||||
#define SAMPLE_RATE2 (48000)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
#ifdef __APPLE__
|
||||
PaMacCoreStreamInfo macInfo;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
for( i=0; i<2; ++i ) {
|
||||
const float sr = i ? SAMPLE_RATE2 : SAMPLE_RATE1;
|
||||
printf("PortAudio Test: output sine wave. SR = %g, BufSize = %d\n", sr, FRAMES_PER_BUFFER);
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
/** setup host specific info */
|
||||
#ifdef __APPLE__
|
||||
PaMacCore_SetupStreamInfo( &macInfo, paMacCorePro );
|
||||
outputParameters.hostApiSpecificStreamInfo = &macInfo;
|
||||
#else
|
||||
printf( "Hardware SR changing not being tested on this platform.\n" );
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
#endif
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
sr,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
}
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
219
third_party/portaudio/test/patest_sine_time.c
vendored
Normal file
219
third_party/portaudio/test/patest_sine_time.c
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
/** @file patest_sine_time.c
|
||||
@ingroup test_src
|
||||
@brief Play a sine wave for several seconds, pausing in the middle.
|
||||
Uses the Pa_GetStreamTime() call.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
|
||||
#define NUM_SECONDS (8)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TWOPI (M_PI * 2.0)
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double left_phase;
|
||||
double right_phase;
|
||||
volatile PaTime outTime;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned int i;
|
||||
|
||||
double left_phaseInc = 0.02;
|
||||
double right_phaseInc = 0.06;
|
||||
|
||||
double left_phase = data->left_phase;
|
||||
double right_phase = data->right_phase;
|
||||
|
||||
(void) statusFlags; /* Prevent unused variable warnings. */
|
||||
(void) inputBuffer;
|
||||
|
||||
data->outTime = timeInfo->outputBufferDacTime;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
left_phase += left_phaseInc;
|
||||
if( left_phase > TWOPI ) left_phase -= TWOPI;
|
||||
*out++ = (float) sin( left_phase );
|
||||
|
||||
right_phase += right_phaseInc;
|
||||
if( right_phase > TWOPI ) right_phase -= TWOPI;
|
||||
*out++ = (float) sin( right_phase );
|
||||
}
|
||||
|
||||
data->left_phase = left_phase;
|
||||
data->right_phase = right_phase;
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
static void ReportStreamTime( PaStream *stream, paTestData *data );
|
||||
static void ReportStreamTime( PaStream *stream, paTestData *data )
|
||||
{
|
||||
PaTime streamTime, latency, outTime;
|
||||
|
||||
streamTime = Pa_GetStreamTime( stream );
|
||||
outTime = data->outTime;
|
||||
if( outTime < 0.0 )
|
||||
{
|
||||
printf("Stream time = %8.1f\n", streamTime );
|
||||
}
|
||||
else
|
||||
{
|
||||
latency = outTime - streamTime;
|
||||
printf("Stream time = %8.4f, outTime = %8.4f, latency = %8.4f\n",
|
||||
streamTime, outTime, latency );
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
PaTime startTime;
|
||||
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
data.left_phase = data.right_phase = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* Watch until sound is halfway finished. */
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS/2 ); fflush(stdout);
|
||||
|
||||
data.outTime = -1.0; /* mark time for callback as undefined */
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
startTime = Pa_GetStreamTime( stream );
|
||||
|
||||
do
|
||||
{
|
||||
ReportStreamTime( stream, &data );
|
||||
Pa_Sleep(100);
|
||||
} while( (Pa_GetStreamTime( stream ) - startTime) < (NUM_SECONDS/2) );
|
||||
|
||||
/* Stop sound for 2 seconds. */
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Pause for 2 seconds.\n"); fflush(stdout);
|
||||
Pa_Sleep( 2000 );
|
||||
|
||||
data.outTime = -1.0; /* mark time for callback as undefined */
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
startTime = Pa_GetStreamTime( stream );
|
||||
|
||||
printf("Play until sound is finished.\n"); fflush(stdout);
|
||||
do
|
||||
{
|
||||
ReportStreamTime( stream, &data );
|
||||
Pa_Sleep(100);
|
||||
} while( (Pa_GetStreamTime( stream ) - startTime) < (NUM_SECONDS/2) );
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
174
third_party/portaudio/test/patest_start_stop.c
vendored
Normal file
174
third_party/portaudio/test/patest_start_stop.c
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/** @file patest_start_stop.c
|
||||
@ingroup test_src
|
||||
@brief Play a sine wave for several seconds. Start and stop the stream multiple times.
|
||||
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define OUTPUT_DEVICE Pa_GetDefaultOutputDevice() /* default output device */
|
||||
|
||||
#define NUM_SECONDS (3)
|
||||
#define NUM_LOOPS (4)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (400)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
|
||||
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = OUTPUT_DEVICE;
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
for( i=0; i<NUM_LOOPS; i++ )
|
||||
{
|
||||
data.left_phase = data.right_phase = 0;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Stopped.\n" );
|
||||
Pa_Sleep( 1000 );
|
||||
}
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
324
third_party/portaudio/test/patest_stop.c
vendored
Normal file
324
third_party/portaudio/test/patest_stop.c
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
/** @file patest_stop.c
|
||||
@ingroup test_src
|
||||
@brief Test different ways of stopping audio.
|
||||
|
||||
Test the three ways of stopping audio:
|
||||
- calling Pa_StopStream(),
|
||||
- calling Pa_AbortStream(),
|
||||
- and returning a 1 from the callback function.
|
||||
|
||||
A long latency is set up so that you can hear the difference.
|
||||
Then a simple 8 note sequence is repeated twice.
|
||||
The program will print what you should hear.
|
||||
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice())
|
||||
#define SLEEP_DUR (200)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (256)
|
||||
#define LATENCY_SECONDS (3.f)
|
||||
#define FRAMES_PER_NOTE (SAMPLE_RATE/2)
|
||||
#define MAX_REPEATS (2)
|
||||
#define FUNDAMENTAL (400.0f / SAMPLE_RATE)
|
||||
#define NOTE_0 (FUNDAMENTAL * 1.0f / 1.0f)
|
||||
#define NOTE_1 (FUNDAMENTAL * 5.0f / 4.0f)
|
||||
#define NOTE_2 (FUNDAMENTAL * 4.0f / 3.0f)
|
||||
#define NOTE_3 (FUNDAMENTAL * 3.0f / 2.0f)
|
||||
#define NOTE_4 (FUNDAMENTAL * 2.0f / 1.0f)
|
||||
#define MODE_FINISH (0)
|
||||
#define MODE_STOP (1)
|
||||
#define MODE_ABORT (2)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (400)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float waveform[TABLE_SIZE + 1]; /* Add one for guard point for interpolation. */
|
||||
float phase_increment;
|
||||
float phase;
|
||||
float *tune;
|
||||
int notesPerTune;
|
||||
int frameCounter;
|
||||
int noteCounter;
|
||||
int repeatCounter;
|
||||
PaTime outTime;
|
||||
int stopMode;
|
||||
int done;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/************* Prototypes *****************************/
|
||||
int TestStopMode( paTestData *data );
|
||||
float LookupWaveform( paTestData *data, float phase );
|
||||
|
||||
/******************************************************
|
||||
* Convert phase between 0.0 and 1.0 to waveform value
|
||||
* using linear interpolation.
|
||||
*/
|
||||
float LookupWaveform( paTestData *data, float phase )
|
||||
{
|
||||
float fIndex = phase*TABLE_SIZE;
|
||||
int index = (int) fIndex;
|
||||
float fract = fIndex - index;
|
||||
float lo = data->waveform[index];
|
||||
float hi = data->waveform[index+1];
|
||||
float val = lo + fract*(hi-lo);
|
||||
return val;
|
||||
}
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
float value;
|
||||
unsigned int i = 0;
|
||||
int finished = paContinue;
|
||||
|
||||
(void) inputBuffer; /* Prevent unused variable warnings. */
|
||||
(void) timeInfo;
|
||||
(void) statusFlags;
|
||||
|
||||
|
||||
/* data->outTime = outTime; */
|
||||
|
||||
if( !data->done )
|
||||
{
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
/* Are we done with this note? */
|
||||
if( data->frameCounter >= FRAMES_PER_NOTE )
|
||||
{
|
||||
data->noteCounter += 1;
|
||||
data->frameCounter = 0;
|
||||
/* Are we done with this tune? */
|
||||
if( data->noteCounter >= data->notesPerTune )
|
||||
{
|
||||
data->noteCounter = 0;
|
||||
data->repeatCounter += 1;
|
||||
/* Are we totally done? */
|
||||
if( data->repeatCounter >= MAX_REPEATS )
|
||||
{
|
||||
data->done = 1;
|
||||
if( data->stopMode == MODE_FINISH )
|
||||
{
|
||||
finished = paComplete;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
data->phase_increment = data->tune[data->noteCounter];
|
||||
}
|
||||
value = LookupWaveform(data, data->phase);
|
||||
*out++ = value; /* left */
|
||||
*out++ = value; /* right */
|
||||
data->phase += data->phase_increment;
|
||||
if( data->phase >= 1.0f ) data->phase -= 1.0f;
|
||||
|
||||
data->frameCounter += 1;
|
||||
}
|
||||
}
|
||||
/* zero remainder of final buffer */
|
||||
for( ; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = 0; /* left */
|
||||
*out++ = 0; /* right */
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
paTestData data;
|
||||
int i;
|
||||
float simpleTune[] = { NOTE_0, NOTE_1, NOTE_2, NOTE_3, NOTE_4, NOTE_3, NOTE_2, NOTE_1 };
|
||||
|
||||
printf("PortAudio Test: play song and test stopping. ask for %f seconds latency\n", LATENCY_SECONDS );
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.waveform[i] = (float) (
|
||||
(0.2 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )) +
|
||||
(0.2 * sin( ((double)(3*i)/(double)TABLE_SIZE) * M_PI * 2. )) +
|
||||
(0.1 * sin( ((double)(5*i)/(double)TABLE_SIZE) * M_PI * 2. ))
|
||||
);
|
||||
}
|
||||
data.waveform[TABLE_SIZE] = data.waveform[0]; /* Set guard point. */
|
||||
data.tune = &simpleTune[0];
|
||||
data.notesPerTune = sizeof(simpleTune) / sizeof(float);
|
||||
|
||||
printf("Test MODE_FINISH - callback returns 1.\n");
|
||||
printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
|
||||
data.stopMode = MODE_FINISH;
|
||||
if( TestStopMode( &data ) != paNoError )
|
||||
{
|
||||
printf("Test of MODE_FINISH failed!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("Test MODE_STOP - stop when song is done.\n");
|
||||
printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
|
||||
data.stopMode = MODE_STOP;
|
||||
if( TestStopMode( &data ) != paNoError )
|
||||
{
|
||||
printf("Test of MODE_STOP failed!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("Test MODE_ABORT - abort immediately.\n");
|
||||
printf("Should hear last repetition cut short by %f seconds.\n", LATENCY_SECONDS);
|
||||
data.stopMode = MODE_ABORT;
|
||||
if( TestStopMode( &data ) != paNoError )
|
||||
{
|
||||
printf("Test of MODE_ABORT failed!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TestStopMode( paTestData *data )
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
|
||||
data->done = 0;
|
||||
data->phase = 0.0;
|
||||
data->frameCounter = 0;
|
||||
data->noteCounter = 0;
|
||||
data->repeatCounter = 0;
|
||||
data->phase_increment = data->tune[data->noteCounter];
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = OUTPUT_DEVICE;
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = LATENCY_SECONDS;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER, /* frames per buffer */
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
if( data->stopMode == MODE_FINISH )
|
||||
{
|
||||
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
|
||||
{
|
||||
/*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
|
||||
data->noteCounter, data->repeatCounter );
|
||||
fflush(stdout); */
|
||||
Pa_Sleep( SLEEP_DUR );
|
||||
}
|
||||
if( err < 0 ) goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
while( data->repeatCounter < MAX_REPEATS )
|
||||
{
|
||||
/*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
|
||||
data->noteCounter, data->repeatCounter );
|
||||
fflush(stdout); */
|
||||
Pa_Sleep( SLEEP_DUR );
|
||||
}
|
||||
}
|
||||
|
||||
if( data->stopMode == MODE_ABORT )
|
||||
{
|
||||
printf("Call Pa_AbortStream()\n");
|
||||
err = Pa_AbortStream( stream );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Call Pa_StopStream()\n");
|
||||
err = Pa_StopStream( stream );
|
||||
}
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Call Pa_CloseStream()\n"); fflush(stdout);
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
478
third_party/portaudio/test/patest_stop_playout.c
vendored
Normal file
478
third_party/portaudio/test/patest_stop_playout.c
vendored
Normal file
@@ -0,0 +1,478 @@
|
||||
/** @file patest_stop_playout.c
|
||||
@ingroup test_src
|
||||
@brief Test whether all queued samples are played when Pa_StopStream()
|
||||
is used with a callback or read/write stream, or when the callback
|
||||
returns paComplete.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2004 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (1024)
|
||||
|
||||
#define TONE_SECONDS (1) /* long tone */
|
||||
#define TONE_FADE_SECONDS (.04) /* fades at start and end of long tone */
|
||||
#define GAP_SECONDS (.25) /* gap between long tone and blip */
|
||||
#define BLIP_SECONDS (.035) /* short blip */
|
||||
|
||||
#define NUM_REPEATS (3)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (2048)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE+1];
|
||||
|
||||
int repeatCount;
|
||||
|
||||
double phase;
|
||||
double lowIncrement, highIncrement;
|
||||
|
||||
int gap1Length, toneLength, toneFadesLength, gap2Length, blipLength;
|
||||
int gap1Countdown, toneCountdown, gap2Countdown, blipCountdown;
|
||||
}
|
||||
TestData;
|
||||
|
||||
|
||||
static void RetriggerTestSignalGenerator( TestData *data )
|
||||
{
|
||||
data->phase = 0.;
|
||||
data->gap1Countdown = data->gap1Length;
|
||||
data->toneCountdown = data->toneLength;
|
||||
data->gap2Countdown = data->gap2Length;
|
||||
data->blipCountdown = data->blipLength;
|
||||
}
|
||||
|
||||
|
||||
static void ResetTestSignalGenerator( TestData *data )
|
||||
{
|
||||
data->repeatCount = 0;
|
||||
RetriggerTestSignalGenerator( data );
|
||||
}
|
||||
|
||||
|
||||
static void InitTestSignalGenerator( TestData *data )
|
||||
{
|
||||
int signalLengthModBufferLength, i;
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data->sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data->sine[TABLE_SIZE] = data->sine[0]; /* guard point for linear interpolation */
|
||||
|
||||
|
||||
|
||||
data->lowIncrement = (330. / SAMPLE_RATE) * TABLE_SIZE;
|
||||
data->highIncrement = (1760. / SAMPLE_RATE) * TABLE_SIZE;
|
||||
|
||||
data->gap1Length = GAP_SECONDS * SAMPLE_RATE;
|
||||
data->toneLength = TONE_SECONDS * SAMPLE_RATE;
|
||||
data->toneFadesLength = TONE_FADE_SECONDS * SAMPLE_RATE;
|
||||
data->gap2Length = GAP_SECONDS * SAMPLE_RATE;
|
||||
data->blipLength = BLIP_SECONDS * SAMPLE_RATE;
|
||||
|
||||
/* adjust signal length to be a multiple of the buffer length */
|
||||
signalLengthModBufferLength = (data->gap1Length + data->toneLength + data->gap2Length + data->blipLength) % FRAMES_PER_BUFFER;
|
||||
if( signalLengthModBufferLength > 0 )
|
||||
data->toneLength += signalLengthModBufferLength;
|
||||
|
||||
ResetTestSignalGenerator( data );
|
||||
}
|
||||
|
||||
|
||||
#define MIN( a, b ) (((a)<(b))?(a):(b))
|
||||
|
||||
static void GenerateTestSignal( TestData *data, float *stereo, int frameCount )
|
||||
{
|
||||
int framesGenerated = 0;
|
||||
float output;
|
||||
long index;
|
||||
float fraction;
|
||||
int count, i;
|
||||
|
||||
while( framesGenerated < frameCount && data->repeatCount < NUM_REPEATS )
|
||||
{
|
||||
if( framesGenerated < frameCount && data->gap1Countdown > 0 ){
|
||||
count = MIN( frameCount - framesGenerated, data->gap1Countdown );
|
||||
for( i=0; i < count; ++i )
|
||||
{
|
||||
*stereo++ = 0.f;
|
||||
*stereo++ = 0.f;
|
||||
}
|
||||
|
||||
data->gap1Countdown -= count;
|
||||
framesGenerated += count;
|
||||
}
|
||||
|
||||
if( framesGenerated < frameCount && data->toneCountdown > 0 ){
|
||||
count = MIN( frameCount - framesGenerated, data->toneCountdown );
|
||||
for( i=0; i < count; ++i )
|
||||
{
|
||||
/* tone with data->lowIncrement phase increment */
|
||||
index = (long)data->phase;
|
||||
fraction = data->phase - index;
|
||||
output = data->sine[ index ] + (data->sine[ index + 1 ] - data->sine[ index ]) * fraction;
|
||||
|
||||
data->phase += data->lowIncrement;
|
||||
while( data->phase >= TABLE_SIZE )
|
||||
data->phase -= TABLE_SIZE;
|
||||
|
||||
/* apply fade to ends */
|
||||
|
||||
if( data->toneCountdown < data->toneFadesLength )
|
||||
{
|
||||
/* cosine-bell fade out at end */
|
||||
output *= (-cos(((float)data->toneCountdown / (float)data->toneFadesLength) * M_PI) + 1.) * .5;
|
||||
}
|
||||
else if( data->toneCountdown > data->toneLength - data->toneFadesLength )
|
||||
{
|
||||
/* cosine-bell fade in at start */
|
||||
output *= (cos(((float)(data->toneCountdown - (data->toneLength - data->toneFadesLength)) / (float)data->toneFadesLength) * M_PI) + 1.) * .5;
|
||||
}
|
||||
|
||||
output *= .5; /* play tone half as loud as blip */
|
||||
|
||||
*stereo++ = output;
|
||||
*stereo++ = output;
|
||||
|
||||
data->toneCountdown--;
|
||||
}
|
||||
|
||||
framesGenerated += count;
|
||||
}
|
||||
|
||||
if( framesGenerated < frameCount && data->gap2Countdown > 0 ){
|
||||
count = MIN( frameCount - framesGenerated, data->gap2Countdown );
|
||||
for( i=0; i < count; ++i )
|
||||
{
|
||||
*stereo++ = 0.f;
|
||||
*stereo++ = 0.f;
|
||||
}
|
||||
|
||||
data->gap2Countdown -= count;
|
||||
framesGenerated += count;
|
||||
}
|
||||
|
||||
if( framesGenerated < frameCount && data->blipCountdown > 0 ){
|
||||
count = MIN( frameCount - framesGenerated, data->blipCountdown );
|
||||
for( i=0; i < count; ++i )
|
||||
{
|
||||
/* tone with data->highIncrement phase increment */
|
||||
index = (long)data->phase;
|
||||
fraction = data->phase - index;
|
||||
output = data->sine[ index ] + (data->sine[ index + 1 ] - data->sine[ index ]) * fraction;
|
||||
|
||||
data->phase += data->highIncrement;
|
||||
while( data->phase >= TABLE_SIZE )
|
||||
data->phase -= TABLE_SIZE;
|
||||
|
||||
/* cosine-bell envelope over whole blip */
|
||||
output *= (-cos( ((float)data->blipCountdown / (float)data->blipLength) * 2. * M_PI) + 1.) * .5;
|
||||
|
||||
*stereo++ = output;
|
||||
*stereo++ = output;
|
||||
|
||||
data->blipCountdown--;
|
||||
}
|
||||
|
||||
framesGenerated += count;
|
||||
}
|
||||
|
||||
|
||||
if( data->blipCountdown == 0 )
|
||||
{
|
||||
RetriggerTestSignalGenerator( data );
|
||||
data->repeatCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if( framesGenerated < frameCount )
|
||||
{
|
||||
count = frameCount - framesGenerated;
|
||||
for( i=0; i < count; ++i )
|
||||
{
|
||||
*stereo++ = 0.f;
|
||||
*stereo++ = 0.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int IsTestSignalFinished( TestData *data )
|
||||
{
|
||||
if( data->repeatCount >= NUM_REPEATS )
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int TestCallback1( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long frameCount,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
(void) inputBuffer; /* Prevent unused variable warnings. */
|
||||
(void) timeInfo;
|
||||
(void) statusFlags;
|
||||
|
||||
GenerateTestSignal( (TestData*)userData, (float*)outputBuffer, frameCount );
|
||||
|
||||
if( IsTestSignalFinished( (TestData*)userData ) )
|
||||
return paComplete;
|
||||
else
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
|
||||
volatile int testCallback2Finished = 0;
|
||||
|
||||
static int TestCallback2( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long frameCount,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
(void) inputBuffer; /* Prevent unused variable warnings. */
|
||||
(void) timeInfo;
|
||||
(void) statusFlags;
|
||||
|
||||
GenerateTestSignal( (TestData*)userData, (float*)outputBuffer, frameCount );
|
||||
|
||||
if( IsTestSignalFinished( (TestData*)userData ) )
|
||||
testCallback2Finished = 1;
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
TestData data;
|
||||
float writeBuffer[ FRAMES_PER_BUFFER * 2 ];
|
||||
|
||||
printf("PortAudio Test: check that stopping stream plays out all queued samples. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
InitTestSignalGenerator( &data );
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
/* test paComplete ---------------------------------------------------------- */
|
||||
|
||||
ResetTestSignalGenerator( &data );
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
TestCallback1,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("\nPlaying 'tone-blip' %d times using callback, stops by returning paComplete from callback.\n", NUM_REPEATS );
|
||||
printf("If final blip is not intact, callback+paComplete implementation may be faulty.\n\n" );
|
||||
|
||||
while( (err = Pa_IsStreamActive( stream )) == 1 )
|
||||
Pa_Sleep( 2 );
|
||||
|
||||
if( err != 0 ) goto error;
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Sleep( 500 );
|
||||
|
||||
|
||||
/* test paComplete ---------------------------------------------------------- */
|
||||
|
||||
ResetTestSignalGenerator( &data );
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
TestCallback1,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("\nPlaying 'tone-blip' %d times using callback, stops by returning paComplete from callback.\n", NUM_REPEATS );
|
||||
printf("If final blip is not intact or is followed by garbage, callback+paComplete implementation may be faulty.\n\n" );
|
||||
|
||||
while( (err = Pa_IsStreamActive( stream )) == 1 )
|
||||
Pa_Sleep( 5 );
|
||||
|
||||
printf("Waiting 5 seconds after paComplete before stopping the stream. Tests that buffers are flushed correctly.\n");
|
||||
Pa_Sleep( 5000 );
|
||||
|
||||
if( err != 0 ) goto error;
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Sleep( 500 );
|
||||
|
||||
|
||||
/* test Pa_StopStream() with callback --------------------------------------- */
|
||||
|
||||
ResetTestSignalGenerator( &data );
|
||||
|
||||
testCallback2Finished = 0;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
TestCallback2,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
printf("\nPlaying 'tone-blip' %d times using callback, stops by calling Pa_StopStream.\n", NUM_REPEATS );
|
||||
printf("If final blip is not intact, callback+Pa_StopStream implementation may be faulty.\n\n" );
|
||||
|
||||
/* note that polling a volatile flag is not a good way to synchronise with
|
||||
the callback, but it's the best we can do portably. */
|
||||
while( !testCallback2Finished )
|
||||
Pa_Sleep( 2 );
|
||||
|
||||
Pa_Sleep( 500 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Sleep( 500 );
|
||||
|
||||
/* test Pa_StopStream() with Pa_WriteStream --------------------------------- */
|
||||
|
||||
ResetTestSignalGenerator( &data );
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
NULL, /* no callback, use blocking API */
|
||||
NULL ); /* no callback, so no callback userData */
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
printf("\nPlaying 'tone-blip' %d times using Pa_WriteStream, stops by calling Pa_StopStream.\n", NUM_REPEATS );
|
||||
printf("If final blip is not intact, Pa_WriteStream+Pa_StopStream implementation may be faulty.\n\n" );
|
||||
|
||||
do{
|
||||
GenerateTestSignal( &data, writeBuffer, FRAMES_PER_BUFFER );
|
||||
err = Pa_WriteStream( stream, writeBuffer, FRAMES_PER_BUFFER );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
}while( !IsTestSignalFinished( &data ) );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
269
third_party/portaudio/test/patest_suggested_vs_streaminfo_latency.c
vendored
Normal file
269
third_party/portaudio/test/patest_suggested_vs_streaminfo_latency.c
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
/** @file patest_suggested_vs_streaminfo_latency.c
|
||||
@ingroup test_src
|
||||
@brief Print suggested vs. PaStreamInfo reported actual latency
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
|
||||
Opens streams with a sequence of suggested latency values
|
||||
from 0 to 2 seconds in .5ms intervals and gathers the resulting actual
|
||||
latency values. Output a csv file and graph suggested vs. actual. Run
|
||||
with framesPerBuffer unspecified, powers of 2 and multiples of 50 and
|
||||
prime number buffer sizes.
|
||||
*/
|
||||
/*
|
||||
* $Id: patest_sine.c 1368 2008-03-01 00:38:27Z rossb $
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER 2//(128)
|
||||
#define NUM_CHANNELS (2)
|
||||
|
||||
#define SUGGESTED_LATENCY_START_SECONDS (0.0)
|
||||
#define SUGGESTED_LATENCY_END_SECONDS (2.0)
|
||||
#define SUGGESTED_LATENCY_INCREMENT_SECONDS (0.0005) /* half a millisecond increments */
|
||||
|
||||
|
||||
/* dummy callback. does nothing. never gets called */
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
static void usage()
|
||||
{
|
||||
int i;
|
||||
const PaDeviceInfo *deviceInfo;
|
||||
const char *channelString;
|
||||
|
||||
fprintf( stderr, "PortAudio suggested (requested) vs. resulting (reported) stream latency test\n" );
|
||||
fprintf( stderr, "Usage: x.exe input-device-index output-device-index sample-rate frames-per-buffer\n" );
|
||||
fprintf( stderr, "Use -1 for default device index, or use one of these:\n" );
|
||||
for( i=0; i < Pa_GetDeviceCount(); ++i ){
|
||||
deviceInfo = Pa_GetDeviceInfo(i);
|
||||
if( deviceInfo->maxInputChannels > 0 && deviceInfo->maxOutputChannels > 0 )
|
||||
channelString = "full-duplex";
|
||||
else if( deviceInfo->maxInputChannels > 0 )
|
||||
channelString = "input only";
|
||||
else
|
||||
channelString = "output only";
|
||||
|
||||
fprintf( stderr, "%d (%s, %s, %s)\n", i, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name, channelString );
|
||||
}
|
||||
Pa_Terminate();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main( int argc, const char* argv[] );
|
||||
int main( int argc, const char* argv[] )
|
||||
{
|
||||
PaStreamParameters inputParameters, outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
PaTime suggestedLatency;
|
||||
const PaStreamInfo *streamInfo;
|
||||
const PaDeviceInfo *deviceInfo;
|
||||
float sampleRate = SAMPLE_RATE;
|
||||
int framesPerBuffer = FRAMES_PER_BUFFER;
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
if( argc > 1 && strcmp(argv[1],"-h") == 0 )
|
||||
usage();
|
||||
|
||||
if( argc > 3 ){
|
||||
sampleRate = atoi(argv[3]);
|
||||
}
|
||||
|
||||
if( argc > 4 ){
|
||||
framesPerBuffer = atoi(argv[4]);
|
||||
}
|
||||
|
||||
printf("# sample rate=%f, frames per buffer=%d\n", (float)sampleRate, framesPerBuffer );
|
||||
|
||||
inputParameters.device = -1;
|
||||
if( argc > 1 )
|
||||
inputParameters.device = atoi(argv[1]);
|
||||
if( inputParameters.device == -1 ){
|
||||
inputParameters.device = Pa_GetDefaultInputDevice();
|
||||
if (inputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default input device available.\n");
|
||||
goto error;
|
||||
}
|
||||
}else{
|
||||
deviceInfo = Pa_GetDeviceInfo(inputParameters.device);
|
||||
if( !deviceInfo ){
|
||||
fprintf(stderr,"Error: Invalid input device index.\n");
|
||||
usage();
|
||||
}
|
||||
if( deviceInfo->maxInputChannels == 0 ){
|
||||
fprintf(stderr,"Error: Specified input device has no input channels (an output only device?).\n");
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
inputParameters.channelCount = NUM_CHANNELS;
|
||||
inputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
deviceInfo = Pa_GetDeviceInfo(inputParameters.device);
|
||||
printf( "# using input device id %d (%s, %s)\n", inputParameters.device, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name );
|
||||
|
||||
|
||||
outputParameters.device = -1;
|
||||
if( argc > 2 )
|
||||
outputParameters.device = atoi(argv[2]);
|
||||
if( outputParameters.device == -1 ){
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice();
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device available.\n");
|
||||
goto error;
|
||||
}
|
||||
}else{
|
||||
deviceInfo = Pa_GetDeviceInfo(outputParameters.device);
|
||||
if( !deviceInfo ){
|
||||
fprintf(stderr,"Error: Invalid output device index.\n");
|
||||
usage();
|
||||
}
|
||||
if( deviceInfo->maxOutputChannels == 0 ){
|
||||
fprintf(stderr,"Error: Specified output device has no output channels (an input only device?).\n");
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
outputParameters.channelCount = NUM_CHANNELS;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
deviceInfo = Pa_GetDeviceInfo(outputParameters.device);
|
||||
printf( "# using output device id %d (%s, %s)\n", outputParameters.device, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name );
|
||||
|
||||
|
||||
printf( "# suggested latency, half duplex PaStreamInfo::outputLatency, half duplex PaStreamInfo::inputLatency, full duplex PaStreamInfo::outputLatency, full duplex PaStreamInfo::inputLatency\n" );
|
||||
suggestedLatency = SUGGESTED_LATENCY_START_SECONDS;
|
||||
while( suggestedLatency <= SUGGESTED_LATENCY_END_SECONDS ){
|
||||
|
||||
outputParameters.suggestedLatency = suggestedLatency;
|
||||
inputParameters.suggestedLatency = suggestedLatency;
|
||||
|
||||
printf( "%f, ", suggestedLatency );
|
||||
|
||||
/* ------------------------------ output ------------------------------ */
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
sampleRate,
|
||||
framesPerBuffer,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
0 );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
streamInfo = Pa_GetStreamInfo( stream );
|
||||
|
||||
printf( "%f,", streamInfo->outputLatency );
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* ------------------------------ input ------------------------------ */
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
NULL, /* no output */
|
||||
sampleRate,
|
||||
framesPerBuffer,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
0 );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
streamInfo = Pa_GetStreamInfo( stream );
|
||||
|
||||
printf( "%f,", streamInfo->inputLatency );
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* ------------------------------ full duplex ------------------------------ */
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
&outputParameters,
|
||||
sampleRate,
|
||||
framesPerBuffer,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
0 );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
streamInfo = Pa_GetStreamInfo( stream );
|
||||
|
||||
printf( "%f,%f", streamInfo->outputLatency, streamInfo->inputLatency );
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
printf( "\n" );
|
||||
suggestedLatency += SUGGESTED_LATENCY_INCREMENT_SECONDS;
|
||||
}
|
||||
|
||||
Pa_Terminate();
|
||||
printf("# Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
150
third_party/portaudio/test/patest_suggested_vs_streaminfo_latency.py
vendored
Normal file
150
third_party/portaudio/test/patest_suggested_vs_streaminfo_latency.py
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
|
||||
Run and graph the results of patest_suggested_vs_streaminfo_latency.c
|
||||
|
||||
Requires matplotlib for plotting: http://matplotlib.sourceforge.net/
|
||||
|
||||
"""
|
||||
import os
|
||||
from pylab import *
|
||||
import numpy
|
||||
from matplotlib.backends.backend_pdf import PdfPages
|
||||
|
||||
testExeName = "PATest.exe" # rename to whatever the compiled patest_suggested_vs_streaminfo_latency.c binary is
|
||||
dataFileName = "patest_suggested_vs_streaminfo_latency.csv" # code below calls the exe to generate this file
|
||||
|
||||
inputDeviceIndex = -1 # -1 means default
|
||||
outputDeviceIndex = -1 # -1 means default
|
||||
sampleRate = 44100
|
||||
pdfFilenameSuffix = "_wmme"
|
||||
|
||||
pdfFile = PdfPages("patest_suggested_vs_streaminfo_latency_" + str(sampleRate) + pdfFilenameSuffix +".pdf") #output this pdf file
|
||||
|
||||
|
||||
def loadCsvData( dataFileName ):
|
||||
params= ""
|
||||
inputDevice = ""
|
||||
outputDevice = ""
|
||||
|
||||
startLines = file(dataFileName).readlines(1024)
|
||||
for line in startLines:
|
||||
if "output device" in line:
|
||||
outputDevice = line.strip(" \t\n\r#")
|
||||
if "input device" in line:
|
||||
inputDevice = line.strip(" \t\n\r#")
|
||||
params = startLines[0].strip(" \t\n\r#")
|
||||
|
||||
data = numpy.loadtxt(dataFileName, delimiter=",", skiprows=4).transpose()
|
||||
|
||||
class R(object): pass
|
||||
result = R()
|
||||
result.params = params
|
||||
for s in params.split(','):
|
||||
if "sample rate" in s:
|
||||
result.sampleRate = s
|
||||
|
||||
result.inputDevice = inputDevice
|
||||
result.outputDevice = outputDevice
|
||||
result.suggestedLatency = data[0]
|
||||
result.halfDuplexOutputLatency = data[1]
|
||||
result.halfDuplexInputLatency = data[2]
|
||||
result.fullDuplexOutputLatency = data[3]
|
||||
result.fullDuplexInputLatency = data[4]
|
||||
return result;
|
||||
|
||||
|
||||
def setFigureTitleAndAxisLabels( framesPerBufferString ):
|
||||
title("PortAudio suggested (requested) vs. resulting (reported) stream latency\n" + framesPerBufferString)
|
||||
ylabel("PaStreamInfo::{input,output}Latency (s)")
|
||||
xlabel("Pa_OpenStream suggestedLatency (s)")
|
||||
grid(True)
|
||||
legend(loc="upper left")
|
||||
|
||||
def setDisplayRangeSeconds( maxSeconds ):
|
||||
xlim(0, maxSeconds)
|
||||
ylim(0, maxSeconds)
|
||||
|
||||
|
||||
# run the test with different frames per buffer values:
|
||||
|
||||
compositeTestFramesPerBufferValues = [0]
|
||||
# powers of two
|
||||
for i in range (1,11):
|
||||
compositeTestFramesPerBufferValues.append( pow(2,i) )
|
||||
|
||||
# multiples of 50
|
||||
for i in range (1,20):
|
||||
compositeTestFramesPerBufferValues.append( i * 50 )
|
||||
|
||||
# 10ms buffer sizes
|
||||
compositeTestFramesPerBufferValues.append( 441 )
|
||||
compositeTestFramesPerBufferValues.append( 882 )
|
||||
|
||||
# large primes
|
||||
#compositeTestFramesPerBufferValues.append( 39209 )
|
||||
#compositeTestFramesPerBufferValues.append( 37537 )
|
||||
#compositeTestFramesPerBufferValues.append( 26437 )
|
||||
|
||||
individualPlotFramesPerBufferValues = [0,64,128,256,512] #output separate plots for these
|
||||
|
||||
isFirst = True
|
||||
|
||||
for framesPerBuffer in compositeTestFramesPerBufferValues:
|
||||
commandString = testExeName + " " + str(inputDeviceIndex) + " " + str(outputDeviceIndex) + " " + str(sampleRate) + " " + str(framesPerBuffer) + ' > ' + dataFileName
|
||||
print commandString
|
||||
os.system(commandString)
|
||||
|
||||
d = loadCsvData(dataFileName)
|
||||
|
||||
if isFirst:
|
||||
figure(1) # title sheet
|
||||
gcf().text(0.1, 0.0,
|
||||
"patest_suggested_vs_streaminfo_latency\n%s\n%s\n%s\n"%(d.inputDevice,d.outputDevice,d.sampleRate))
|
||||
pdfFile.savefig()
|
||||
|
||||
|
||||
figure(2) # composite plot, includes all compositeTestFramesPerBufferValues
|
||||
|
||||
if isFirst:
|
||||
plot( d.suggestedLatency, d.suggestedLatency, label="Suggested latency" )
|
||||
|
||||
plot( d.suggestedLatency, d.halfDuplexOutputLatency )
|
||||
plot( d.suggestedLatency, d.halfDuplexInputLatency )
|
||||
plot( d.suggestedLatency, d.fullDuplexOutputLatency )
|
||||
plot( d.suggestedLatency, d.fullDuplexInputLatency )
|
||||
|
||||
if framesPerBuffer in individualPlotFramesPerBufferValues: # individual plots
|
||||
figure( 3 + individualPlotFramesPerBufferValues.index(framesPerBuffer) )
|
||||
|
||||
plot( d.suggestedLatency, d.suggestedLatency, label="Suggested latency" )
|
||||
plot( d.suggestedLatency, d.halfDuplexOutputLatency, label="Half-duplex output latency" )
|
||||
plot( d.suggestedLatency, d.halfDuplexInputLatency, label="Half-duplex input latency" )
|
||||
plot( d.suggestedLatency, d.fullDuplexOutputLatency, label="Full-duplex output latency" )
|
||||
plot( d.suggestedLatency, d.fullDuplexInputLatency, label="Full-duplex input latency" )
|
||||
|
||||
if framesPerBuffer == 0:
|
||||
framesPerBufferText = "paFramesPerBufferUnspecified"
|
||||
else:
|
||||
framesPerBufferText = str(framesPerBuffer)
|
||||
setFigureTitleAndAxisLabels( "user frames per buffer: "+str(framesPerBufferText) )
|
||||
setDisplayRangeSeconds(2.2)
|
||||
pdfFile.savefig()
|
||||
setDisplayRangeSeconds(0.1)
|
||||
setFigureTitleAndAxisLabels( "user frames per buffer: "+str(framesPerBufferText)+" (detail)" )
|
||||
pdfFile.savefig()
|
||||
|
||||
isFirst = False
|
||||
|
||||
figure(2)
|
||||
setFigureTitleAndAxisLabels( "composite of frames per buffer values:\n"+str(compositeTestFramesPerBufferValues) )
|
||||
setDisplayRangeSeconds(2.2)
|
||||
pdfFile.savefig()
|
||||
setDisplayRangeSeconds(0.1)
|
||||
setFigureTitleAndAxisLabels( "composite of frames per buffer values:\n"+str(compositeTestFramesPerBufferValues)+" (detail)" )
|
||||
pdfFile.savefig()
|
||||
|
||||
pdfFile.close()
|
||||
|
||||
#uncomment this to display interactively, otherwise we just output a pdf
|
||||
#show()
|
||||
271
third_party/portaudio/test/patest_sync.c
vendored
Normal file
271
third_party/portaudio/test/patest_sync.c
vendored
Normal file
@@ -0,0 +1,271 @@
|
||||
/** @file patest_sync.c
|
||||
@ingroup test_src
|
||||
@brief Test time stamping and synchronization of audio and video.
|
||||
|
||||
A high latency is used so we can hear the difference in time.
|
||||
Random durations are used so we know we are hearing the right beep
|
||||
and not the one before or after.
|
||||
|
||||
Sequence of events:
|
||||
-# Foreground requests a beep.
|
||||
-# Background randomly schedules a beep.
|
||||
-# Foreground waits for the beep to be heard based on PaUtil_GetTime().
|
||||
-# Foreground outputs video (printf) in sync with audio.
|
||||
-# Repeat.
|
||||
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
#define NUM_BEEPS (6)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define SAMPLE_PERIOD (1.0/44100.0)
|
||||
#define FRAMES_PER_BUFFER (256)
|
||||
#define BEEP_DURATION (400)
|
||||
#define LATENCY_MSEC (2000)
|
||||
#define SLEEP_MSEC (10)
|
||||
#define TIMEOUT_MSEC (15000)
|
||||
|
||||
#define STATE_BKG_IDLE (0)
|
||||
#define STATE_BKG_PENDING (1)
|
||||
#define STATE_BKG_BEEPING (2)
|
||||
typedef struct
|
||||
{
|
||||
float left_phase;
|
||||
float right_phase;
|
||||
int state;
|
||||
volatile int requestBeep; /* Set by foreground, cleared by background. */
|
||||
PaTime beepTime;
|
||||
int beepCount;
|
||||
double latency; /* For debugging. */
|
||||
}
|
||||
paTestData;
|
||||
|
||||
static unsigned long GenerateRandomNumber( void );
|
||||
/************************************************************/
|
||||
/* Calculate pseudo-random 32 bit number based on linear congruential method. */
|
||||
static unsigned long GenerateRandomNumber( void )
|
||||
{
|
||||
static unsigned long randSeed = 99887766; /* Change this for different random sequences. */
|
||||
randSeed = (randSeed * 196314165) + 907633515;
|
||||
return randSeed;
|
||||
}
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo *timeInfo,
|
||||
PaStreamCallbackFlags statusFlags, void *userData )
|
||||
{
|
||||
/* Cast data passed through stream to our structure. */
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned int i;
|
||||
(void) inputBuffer;
|
||||
|
||||
data->latency = timeInfo->outputBufferDacTime - timeInfo->currentTime;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
switch( data->state )
|
||||
{
|
||||
case STATE_BKG_IDLE:
|
||||
/* Schedule beep at some random time in the future. */
|
||||
if( data->requestBeep )
|
||||
{
|
||||
int random = GenerateRandomNumber() >> 14;
|
||||
data->beepTime = timeInfo->outputBufferDacTime + (( (double)(random + SAMPLE_RATE)) * SAMPLE_PERIOD );
|
||||
data->state = STATE_BKG_PENDING;
|
||||
}
|
||||
*out++ = 0.0; /* left */
|
||||
*out++ = 0.0; /* right */
|
||||
break;
|
||||
|
||||
case STATE_BKG_PENDING:
|
||||
if( (timeInfo->outputBufferDacTime + (i*SAMPLE_PERIOD)) >= data->beepTime )
|
||||
{
|
||||
data->state = STATE_BKG_BEEPING;
|
||||
data->beepCount = BEEP_DURATION;
|
||||
data->left_phase = data->right_phase = 0.0;
|
||||
}
|
||||
*out++ = 0.0; /* left */
|
||||
*out++ = 0.0; /* right */
|
||||
break;
|
||||
|
||||
case STATE_BKG_BEEPING:
|
||||
if( data->beepCount <= 0 )
|
||||
{
|
||||
data->state = STATE_BKG_IDLE;
|
||||
data->requestBeep = 0;
|
||||
*out++ = 0.0; /* left */
|
||||
*out++ = 0.0; /* right */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Play sawtooth wave. */
|
||||
*out++ = data->left_phase; /* left */
|
||||
*out++ = data->right_phase; /* right */
|
||||
/* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
|
||||
data->left_phase += 0.01f;
|
||||
/* When signal reaches top, drop back down. */
|
||||
if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
|
||||
/* higher pitch so we can distinguish left and right. */
|
||||
data->right_phase += 0.03f;
|
||||
if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
|
||||
}
|
||||
data->beepCount -= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
data->state = STATE_BKG_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData DATA;
|
||||
int i, timeout;
|
||||
PaTime previousTime;
|
||||
PaStreamParameters outputParameters;
|
||||
printf("PortAudio Test: you should see BEEP at the same time you hear it.\n");
|
||||
printf("Wait for a few seconds random delay between BEEPs.\n");
|
||||
printf("BEEP %d times.\n", NUM_BEEPS );
|
||||
/* Initialize our DATA for use by callback. */
|
||||
DATA.left_phase = DATA.right_phase = 0.0;
|
||||
DATA.state = STATE_BKG_IDLE;
|
||||
DATA.requestBeep = 0;
|
||||
/* Initialize library before making any other calls. */
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice();
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
outputParameters.sampleFormat = paFloat32;
|
||||
outputParameters.suggestedLatency = (double)LATENCY_MSEC / 1000;
|
||||
|
||||
/* Open an audio I/O stream. */
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER, /* frames per buffer */
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&DATA );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("started\n");
|
||||
fflush(stdout);
|
||||
|
||||
previousTime = Pa_GetStreamTime( stream );
|
||||
for( i=0; i<NUM_BEEPS; i++ )
|
||||
{
|
||||
/* Request a beep from background. */
|
||||
DATA.requestBeep = 1;
|
||||
|
||||
/* Wait for background to acknowledge request. */
|
||||
timeout = TIMEOUT_MSEC;
|
||||
while( (DATA.requestBeep == 1) && (timeout-- > 0 ) ) Pa_Sleep(SLEEP_MSEC);
|
||||
if( timeout <= 0 )
|
||||
{
|
||||
fprintf( stderr, "Timed out waiting for background to acknowledge request.\n" );
|
||||
goto error;
|
||||
}
|
||||
printf("calc beep for %9.3f, latency = %6.3f\n", DATA.beepTime, DATA.latency );
|
||||
fflush(stdout);
|
||||
|
||||
/* Wait for scheduled beep time. */
|
||||
timeout = TIMEOUT_MSEC + (10000/SLEEP_MSEC);
|
||||
while( (Pa_GetStreamTime( stream ) < DATA.beepTime) && (timeout-- > 0 ) )
|
||||
{
|
||||
Pa_Sleep(SLEEP_MSEC);
|
||||
}
|
||||
if( timeout <= 0 )
|
||||
{
|
||||
fprintf( stderr, "Timed out waiting for time. Now = %9.3f, Beep for %9.3f.\n",
|
||||
PaUtil_GetTime(), DATA.beepTime );
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Beep should be sounding now so print synchronized BEEP. */
|
||||
printf("hear \"BEEP\" at %9.3f, delta = %9.3f\n",
|
||||
Pa_GetStreamTime( stream ), (DATA.beepTime - previousTime) );
|
||||
fflush(stdout);
|
||||
|
||||
previousTime = DATA.beepTime;
|
||||
}
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
173
third_party/portaudio/test/patest_timing.c
vendored
Normal file
173
third_party/portaudio/test/patest_timing.c
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
/** @file patest_timing.c
|
||||
@ingroup test_src
|
||||
@brief Play a sine wave for several seconds, and spits out a ton of timing info while it's at it. Based on patest_sine.c
|
||||
@author Bjorn Roche
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id: patest_timing.c 578 2003-09-02 04:17:38Z rossbencina $
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (5)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
PaStream *stream;
|
||||
PaTime start;
|
||||
float sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
printf( "Timing info given to callback: Adc: %g, Current: %g, Dac: %g\n",
|
||||
timeInfo->inputBufferAdcTime,
|
||||
timeInfo->currentTime,
|
||||
timeInfo->outputBufferDacTime );
|
||||
|
||||
printf( "getStreamTime() returns: %g\n", Pa_GetStreamTime(data->stream) - data->start );
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
|
||||
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.left_phase = data.right_phase = 0;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
data.stream = stream;
|
||||
data.start = Pa_GetStreamTime(stream);
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
data.start = Pa_GetStreamTime(stream);
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
printf("The tone should have been heard for about 5 seconds and all the timing info above should report that about 5 seconds elapsed (except Adc, which is undefined since there was no input device opened).\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
200
third_party/portaudio/test/patest_toomanysines.c
vendored
Normal file
200
third_party/portaudio/test/patest_toomanysines.c
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/** @file patest_toomanysines.c
|
||||
@ingroup test_src
|
||||
@brief Play more sine waves than we can handle in real time as a stress test.
|
||||
@todo This may not be needed now that we have "patest_out_overflow.c".
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define MAX_SINES (1000)
|
||||
#define MAX_LOAD (1.2)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (512)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TWOPI (M_PI * 2.0)
|
||||
|
||||
typedef struct paTestData
|
||||
{
|
||||
int numSines;
|
||||
double phases[MAX_SINES];
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
int j;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent unused variable warning. */
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float output = 0.0;
|
||||
double phaseInc = 0.02;
|
||||
double phase;
|
||||
for( j=0; j<data->numSines; j++ )
|
||||
{
|
||||
/* Advance phase of next oscillator. */
|
||||
phase = data->phases[j];
|
||||
phase += phaseInc;
|
||||
if( phase > TWOPI ) phase -= TWOPI;
|
||||
|
||||
phaseInc *= 1.02;
|
||||
if( phaseInc > 0.5 ) phaseInc *= 0.5;
|
||||
|
||||
/* This is not a very efficient way to calc sines. */
|
||||
output += (float) sin( phase );
|
||||
data->phases[j] = phase;
|
||||
}
|
||||
*out++ = (float) (output / data->numSines);
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
int numStress;
|
||||
paTestData data = {0};
|
||||
double load;
|
||||
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD );
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 1; /* mono output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* Determine number of sines required to get to 50% */
|
||||
do
|
||||
{ Pa_Sleep( 100 );
|
||||
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("numSines = %d, CPU load = %f\n", data.numSines, load );
|
||||
|
||||
if( load < 0.3 )
|
||||
{
|
||||
data.numSines += 10;
|
||||
}
|
||||
else if( load < 0.4 )
|
||||
{
|
||||
data.numSines += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.numSines += 1;
|
||||
}
|
||||
|
||||
}
|
||||
while( load < 0.5 );
|
||||
|
||||
/* Calculate target stress value then ramp up to that level*/
|
||||
numStress = (int) (2.0 * data.numSines * MAX_LOAD );
|
||||
if( numStress > MAX_SINES )
|
||||
numStress = MAX_SINES;
|
||||
for( ; data.numSines < numStress; data.numSines+=2 )
|
||||
{
|
||||
Pa_Sleep( 200 );
|
||||
load = Pa_GetStreamCpuLoad( stream );
|
||||
printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load );
|
||||
}
|
||||
|
||||
printf("Suffer for 5 seconds.\n");
|
||||
Pa_Sleep( 5000 );
|
||||
|
||||
printf("Stop stream.\n");
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
178
third_party/portaudio/test/patest_two_rates.c
vendored
Normal file
178
third_party/portaudio/test/patest_two_rates.c
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/** @file patest_two_rates.c
|
||||
@ingroup test_src
|
||||
@brief Play two streams at different rates to make sure they don't interfere.
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Author: Phil Burk http://www.softsynth.com
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define OUTPUT_DEVICE (Pa_GetDefaultOutputDeviceID())
|
||||
#define SAMPLE_RATE_1 (44100)
|
||||
#define SAMPLE_RATE_2 (48000)
|
||||
#define FRAMES_PER_BUFFER (256)
|
||||
#define FREQ_INCR (0.1)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double phase;
|
||||
int 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( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
int frameIndex;
|
||||
(void) timeInfo; /* 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);
|
||||
}
|
||||
data->numFrames += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaError err;
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream1;
|
||||
PaStream *stream2;
|
||||
paTestData data1 = {0};
|
||||
paTestData data2 = {0};
|
||||
printf("PortAudio Test: two rates.\n" );
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
/* Start first stream. **********************/
|
||||
err = Pa_OpenStream(
|
||||
&stream1,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE_1,
|
||||
FRAMES_PER_BUFFER,
|
||||
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,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE_2,
|
||||
FRAMES_PER_BUFFER,
|
||||
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("NumFrames = %d on stream1, %d on stream2.\n", data1.numFrames, data2.numFrames );
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
162
third_party/portaudio/test/patest_underflow.c
vendored
Normal file
162
third_party/portaudio/test/patest_underflow.c
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/** @file patest_underflow.c
|
||||
@ingroup test_src
|
||||
@brief Simulate an output buffer underflow condition.
|
||||
Tests whether the stream can be stopped when underflowing buffers.
|
||||
@author Ross Bencina <rossb@audiomulch.com>
|
||||
@author Phil Burk <philburk@softsynth.com>
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (20)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (2048)
|
||||
#define MSEC_PER_BUFFER ( (FRAMES_PER_BUFFER * 1000) / SAMPLE_RATE )
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
int sleepTime;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent unused variable warnings. */
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out++ = data->sine[data->left_phase]; /* left */
|
||||
*out++ = data->sine[data->right_phase]; /* right */
|
||||
data->left_phase += 1;
|
||||
if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
|
||||
data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
|
||||
if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
/* Cause underflow to occur. */
|
||||
if( data->sleepTime > 0 ) Pa_Sleep( data->sleepTime );
|
||||
data->sleepTime += 1;
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
data.left_phase = data.right_phase = data.sleepTime = 0;
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
while( data.sleepTime < (2 * MSEC_PER_BUFFER) )
|
||||
{
|
||||
printf("SleepTime = %d\n", data.sleepTime );
|
||||
Pa_Sleep( data.sleepTime );
|
||||
}
|
||||
|
||||
printf("Try to stop stream.\n");
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
243
third_party/portaudio/test/patest_unplug.c
vendored
Normal file
243
third_party/portaudio/test/patest_unplug.c
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/** @file patest_unplug.c
|
||||
@ingroup test_src
|
||||
@brief Debug a crash involving unplugging a USB device.
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (8)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
#define TABLE_SIZE (200)
|
||||
#define FRAMES_PER_BUFFER (64)
|
||||
#define MAX_CHANNELS (8)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short sine[TABLE_SIZE];
|
||||
int32_t phases[MAX_CHANNELS];
|
||||
int32_t numChannels;
|
||||
int32_t sampsToGo;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
|
||||
static int inputCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent "unused variable" warnings. */
|
||||
(void) outputBuffer; /* Prevent "unused variable" warnings. */
|
||||
|
||||
data->sampsToGo -= framesPerBuffer;
|
||||
if (data->sampsToGo <= 0)
|
||||
{
|
||||
data->sampsToGo = 0;
|
||||
finished = 1;
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
static int outputCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
short *out = (short*)outputBuffer;
|
||||
unsigned int i;
|
||||
int finished = 0;
|
||||
(void) inputBuffer; /* Prevent "unused variable" warnings. */
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
for (int channelIndex = 0; channelIndex < data->numChannels; channelIndex++)
|
||||
{
|
||||
int phase = data->phases[channelIndex];
|
||||
*out++ = data->sine[phase];
|
||||
phase += channelIndex + 2;
|
||||
if( phase >= TABLE_SIZE ) phase -= TABLE_SIZE;
|
||||
data->phases[channelIndex] = phase;
|
||||
}
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(int argc, char **args);
|
||||
int main(int argc, char **args)
|
||||
{
|
||||
PaStreamParameters inputParameters;
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *inputStream;
|
||||
PaStream *outputStream;
|
||||
const PaDeviceInfo *deviceInfo;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int totalSamps;
|
||||
int inputDevice = -1;
|
||||
int outputDevice = -1;
|
||||
|
||||
printf("Test unplugging a USB device.\n");
|
||||
|
||||
if( argc > 1 ) {
|
||||
inputDevice = outputDevice = atoi( args[1] );
|
||||
printf("Using device number %d.\n\n", inputDevice );
|
||||
} else {
|
||||
printf("Using default device.\n\n" );
|
||||
}
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
|
||||
}
|
||||
data.numChannels = 2;
|
||||
data.sampsToGo = totalSamps = NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
|
||||
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
if( inputDevice == -1 )
|
||||
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
|
||||
else
|
||||
inputParameters.device = inputDevice ;
|
||||
|
||||
if (inputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default input device.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if( outputDevice == -1 )
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
else
|
||||
outputParameters.device = outputDevice ;
|
||||
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
inputParameters.channelCount = 2;
|
||||
inputParameters.sampleFormat = paInt16;
|
||||
deviceInfo = Pa_GetDeviceInfo( inputParameters.device );
|
||||
if( deviceInfo == NULL )
|
||||
{
|
||||
fprintf( stderr, "No matching input device.\n" );
|
||||
goto error;
|
||||
}
|
||||
inputParameters.suggestedLatency = deviceInfo->defaultLowInputLatency;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
err = Pa_OpenStream(
|
||||
&inputStream,
|
||||
&inputParameters,
|
||||
NULL,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
0,
|
||||
inputCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.channelCount = 2;
|
||||
outputParameters.sampleFormat = paInt16;
|
||||
deviceInfo = Pa_GetDeviceInfo( outputParameters.device );
|
||||
if( deviceInfo == NULL )
|
||||
{
|
||||
fprintf( stderr, "No matching output device.\n" );
|
||||
goto error;
|
||||
}
|
||||
outputParameters.suggestedLatency = deviceInfo->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
err = Pa_OpenStream(
|
||||
&outputStream,
|
||||
NULL,
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
(paClipOff | paDitherOff),
|
||||
outputCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( inputStream );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_StartStream( outputStream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("When you hear sound, unplug the USB device.\n");
|
||||
do
|
||||
{
|
||||
Pa_Sleep(500);
|
||||
printf("Frames remaining = %d\n", data.sampsToGo);
|
||||
printf("Pa_IsStreamActive(inputStream) = %d\n", Pa_IsStreamActive(inputStream));
|
||||
printf("Pa_IsStreamActive(outputStream) = %d\n", Pa_IsStreamActive(outputStream));
|
||||
} while( Pa_IsStreamActive(inputStream) && Pa_IsStreamActive(outputStream) );
|
||||
|
||||
err = Pa_CloseStream( inputStream );
|
||||
if( err != paNoError ) goto error;
|
||||
err = Pa_CloseStream( outputStream );
|
||||
if( err != paNoError ) goto error;
|
||||
Pa_Terminate();
|
||||
return paNoError;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
fprintf( stderr, "Host Error message: %s\n", Pa_GetLastHostErrorInfo()->errorText );
|
||||
return err;
|
||||
}
|
||||
331
third_party/portaudio/test/patest_wire.c
vendored
Normal file
331
third_party/portaudio/test/patest_wire.c
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
/** @file patest_wire.c
|
||||
@ingroup test_src
|
||||
@brief Pass input directly to output.
|
||||
|
||||
Note that some HW devices, for example many ISA audio cards
|
||||
on PCs, do NOT support full duplex! For a PC, you normally need
|
||||
a PCI based audio card such as the SBLive.
|
||||
|
||||
@author Phil Burk http://www.softsynth.com
|
||||
|
||||
While adapting to V19-API, I excluded configs with framesPerCallback=0
|
||||
because of an assert in file pa_common/pa_process.c. Pieter, Oct 9, 2003.
|
||||
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
|
||||
typedef struct WireConfig_s
|
||||
{
|
||||
int isInputInterleaved;
|
||||
int isOutputInterleaved;
|
||||
int numInputChannels;
|
||||
int numOutputChannels;
|
||||
int framesPerCallback;
|
||||
/* count status flags */
|
||||
int numInputUnderflows;
|
||||
int numInputOverflows;
|
||||
int numOutputUnderflows;
|
||||
int numOutputOverflows;
|
||||
int numPrimingOutputs;
|
||||
int numCallbacks;
|
||||
} WireConfig_t;
|
||||
|
||||
#define USE_FLOAT_INPUT (1)
|
||||
#define USE_FLOAT_OUTPUT (1)
|
||||
|
||||
/* Latencies set to defaults. */
|
||||
|
||||
#if USE_FLOAT_INPUT
|
||||
#define INPUT_FORMAT paFloat32
|
||||
typedef float INPUT_SAMPLE;
|
||||
#else
|
||||
#define INPUT_FORMAT paInt16
|
||||
typedef short INPUT_SAMPLE;
|
||||
#endif
|
||||
|
||||
#if USE_FLOAT_OUTPUT
|
||||
#define OUTPUT_FORMAT paFloat32
|
||||
typedef float OUTPUT_SAMPLE;
|
||||
#else
|
||||
#define OUTPUT_FORMAT paInt16
|
||||
typedef short OUTPUT_SAMPLE;
|
||||
#endif
|
||||
|
||||
double gInOutScaler = 1.0;
|
||||
#define CONVERT_IN_TO_OUT(in) ((OUTPUT_SAMPLE) ((in) * gInOutScaler))
|
||||
|
||||
#define INPUT_DEVICE (Pa_GetDefaultInputDevice())
|
||||
#define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice())
|
||||
|
||||
static PaError TestConfiguration( WireConfig_t *config );
|
||||
|
||||
static int wireCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData );
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may be called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
|
||||
static int wireCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
INPUT_SAMPLE *in;
|
||||
OUTPUT_SAMPLE *out;
|
||||
int inStride;
|
||||
int outStride;
|
||||
int inDone = 0;
|
||||
int outDone = 0;
|
||||
WireConfig_t *config = (WireConfig_t *) userData;
|
||||
unsigned int i;
|
||||
int inChannel, outChannel;
|
||||
|
||||
/* This may get called with NULL inputBuffer during initial setup. */
|
||||
if( inputBuffer == NULL) return 0;
|
||||
|
||||
/* Count flags */
|
||||
if( (statusFlags & paInputUnderflow) != 0 ) config->numInputUnderflows += 1;
|
||||
if( (statusFlags & paInputOverflow) != 0 ) config->numInputOverflows += 1;
|
||||
if( (statusFlags & paOutputUnderflow) != 0 ) config->numOutputUnderflows += 1;
|
||||
if( (statusFlags & paOutputOverflow) != 0 ) config->numOutputOverflows += 1;
|
||||
if( (statusFlags & paPrimingOutput) != 0 ) config->numPrimingOutputs += 1;
|
||||
config->numCallbacks += 1;
|
||||
|
||||
inChannel=0, outChannel=0;
|
||||
while( !(inDone && outDone) )
|
||||
{
|
||||
if( config->isInputInterleaved )
|
||||
{
|
||||
in = ((INPUT_SAMPLE*)inputBuffer) + inChannel;
|
||||
inStride = config->numInputChannels;
|
||||
}
|
||||
else
|
||||
{
|
||||
in = ((INPUT_SAMPLE**)inputBuffer)[inChannel];
|
||||
inStride = 1;
|
||||
}
|
||||
|
||||
if( config->isOutputInterleaved )
|
||||
{
|
||||
out = ((OUTPUT_SAMPLE*)outputBuffer) + outChannel;
|
||||
outStride = config->numOutputChannels;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = ((OUTPUT_SAMPLE**)outputBuffer)[outChannel];
|
||||
outStride = 1;
|
||||
}
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
*out = CONVERT_IN_TO_OUT( *in );
|
||||
out += outStride;
|
||||
in += inStride;
|
||||
}
|
||||
|
||||
if(inChannel < (config->numInputChannels - 1)) inChannel++;
|
||||
else inDone = 1;
|
||||
if(outChannel < (config->numOutputChannels - 1)) outChannel++;
|
||||
else outDone = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaError err = paNoError;
|
||||
WireConfig_t CONFIG;
|
||||
WireConfig_t *config = &CONFIG;
|
||||
int configIndex = 0;;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Please connect audio signal to input and listen for it on output!\n");
|
||||
printf("input format = %lu\n", INPUT_FORMAT );
|
||||
printf("output format = %lu\n", OUTPUT_FORMAT );
|
||||
printf("input device ID = %d\n", INPUT_DEVICE );
|
||||
printf("output device ID = %d\n", OUTPUT_DEVICE );
|
||||
|
||||
if( INPUT_FORMAT == OUTPUT_FORMAT )
|
||||
{
|
||||
gInOutScaler = 1.0;
|
||||
}
|
||||
else if( (INPUT_FORMAT == paInt16) && (OUTPUT_FORMAT == paFloat32) )
|
||||
{
|
||||
gInOutScaler = 1.0/32768.0;
|
||||
}
|
||||
else if( (INPUT_FORMAT == paFloat32) && (OUTPUT_FORMAT == paInt16) )
|
||||
{
|
||||
gInOutScaler = 32768.0;
|
||||
}
|
||||
|
||||
for( config->isInputInterleaved = 0; config->isInputInterleaved < 2; config->isInputInterleaved++ )
|
||||
{
|
||||
for( config->isOutputInterleaved = 0; config->isOutputInterleaved < 2; config->isOutputInterleaved++ )
|
||||
{
|
||||
for( config->numInputChannels = 1; config->numInputChannels < 3; config->numInputChannels++ )
|
||||
{
|
||||
for( config->numOutputChannels = 1; config->numOutputChannels < 3; config->numOutputChannels++ )
|
||||
{
|
||||
/* If framesPerCallback = 0, assertion fails in file pa_common/pa_process.c, line 1413: EX. */
|
||||
for( config->framesPerCallback = 64; config->framesPerCallback < 129; config->framesPerCallback += 64 )
|
||||
{
|
||||
printf("-----------------------------------------------\n" );
|
||||
printf("Configuration #%d\n", configIndex++ );
|
||||
err = TestConfiguration( config );
|
||||
/* Give user a chance to bail out. */
|
||||
if( err == 1 )
|
||||
{
|
||||
err = paNoError;
|
||||
goto done;
|
||||
}
|
||||
else if( err != paNoError ) goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
Pa_Terminate();
|
||||
printf("Full duplex sound test complete.\n"); fflush(stdout);
|
||||
printf("Hit ENTER to quit.\n"); fflush(stdout);
|
||||
getchar();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
printf("Hit ENTER to quit.\n"); fflush(stdout);
|
||||
getchar();
|
||||
return -1;
|
||||
}
|
||||
|
||||
static PaError TestConfiguration( WireConfig_t *config )
|
||||
{
|
||||
int c;
|
||||
PaError err = paNoError;
|
||||
PaStream *stream;
|
||||
PaStreamParameters inputParameters, outputParameters;
|
||||
|
||||
printf("input %sinterleaved!\n", (config->isInputInterleaved ? " " : "NOT ") );
|
||||
printf("output %sinterleaved!\n", (config->isOutputInterleaved ? " " : "NOT ") );
|
||||
printf("input channels = %d\n", config->numInputChannels );
|
||||
printf("output channels = %d\n", config->numOutputChannels );
|
||||
printf("framesPerCallback = %d\n", config->framesPerCallback );
|
||||
|
||||
inputParameters.device = INPUT_DEVICE; /* default input device */
|
||||
if (inputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default input device.\n");
|
||||
goto error;
|
||||
}
|
||||
inputParameters.channelCount = config->numInputChannels;
|
||||
inputParameters.sampleFormat = INPUT_FORMAT | (config->isInputInterleaved ? 0 : paNonInterleaved);
|
||||
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
|
||||
inputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
outputParameters.device = OUTPUT_DEVICE; /* default output device */
|
||||
if (outputParameters.device == paNoDevice) {
|
||||
fprintf(stderr,"Error: No default output device.\n");
|
||||
goto error;
|
||||
}
|
||||
outputParameters.channelCount = config->numOutputChannels;
|
||||
outputParameters.sampleFormat = OUTPUT_FORMAT | (config->isOutputInterleaved ? 0 : paNonInterleaved);
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
config->numInputUnderflows = 0;
|
||||
config->numInputOverflows = 0;
|
||||
config->numOutputUnderflows = 0;
|
||||
config->numOutputOverflows = 0;
|
||||
config->numPrimingOutputs = 0;
|
||||
config->numCallbacks = 0;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
&inputParameters,
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
config->framesPerCallback, /* frames per buffer */
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
wireCallback,
|
||||
config );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Now recording and playing. - Hit ENTER for next configuration, or 'q' to quit.\n"); fflush(stdout);
|
||||
c = getchar();
|
||||
|
||||
printf("Closing stream.\n");
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
#define CHECK_FLAG_COUNT(member) \
|
||||
if( config->member > 0 ) printf("FLAGS SET: " #member " = %d\n", config->member );
|
||||
CHECK_FLAG_COUNT( numInputUnderflows );
|
||||
CHECK_FLAG_COUNT( numInputOverflows );
|
||||
CHECK_FLAG_COUNT( numOutputUnderflows );
|
||||
CHECK_FLAG_COUNT( numOutputOverflows );
|
||||
CHECK_FLAG_COUNT( numPrimingOutputs );
|
||||
printf("number of callbacks = %d\n", config->numCallbacks );
|
||||
|
||||
if( c == 'q' ) return 1;
|
||||
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
517
third_party/portaudio/test/patest_wmme_find_best_latency_params.c
vendored
Normal file
517
third_party/portaudio/test/patest_wmme_find_best_latency_params.c
vendored
Normal file
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* $Id: $
|
||||
* Portable Audio I/O Library
|
||||
* Windows MME low level buffer user guided parameters search
|
||||
*
|
||||
* Copyright (c) 2010 Ross Bencina
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#define _WIN32_WINNT 0x0501 /* for GetNativeSystemInfo */
|
||||
#include <windows.h> /* required when using pa_win_wmme.h */
|
||||
#include <mmsystem.h> /* required when using pa_win_wmme.h */
|
||||
|
||||
#include <conio.h> /* for _getch */
|
||||
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_wmme.h"
|
||||
|
||||
|
||||
#define DEFAULT_SAMPLE_RATE (44100.)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (2048)
|
||||
|
||||
#define CHANNEL_COUNT (2)
|
||||
|
||||
|
||||
/* search parameters. we test all buffer counts in this range */
|
||||
#define MIN_WMME_BUFFER_COUNT (2)
|
||||
#define MAX_WMME_BUFFER_COUNT (12)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/* functions to query and print Windows version information */
|
||||
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process;
|
||||
|
||||
static BOOL IsWow64()
|
||||
{
|
||||
BOOL bIsWow64 = FALSE;
|
||||
|
||||
//IsWow64Process is not available on all supported versions of Windows.
|
||||
//Use GetModuleHandle to get a handle to the DLL that contains the function
|
||||
//and GetProcAddress to get a pointer to the function if available.
|
||||
|
||||
fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
|
||||
GetModuleHandle(TEXT("kernel32")),"IsWow64Process" );
|
||||
|
||||
if(NULL != fnIsWow64Process)
|
||||
{
|
||||
if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
|
||||
{
|
||||
//handle error
|
||||
}
|
||||
}
|
||||
return bIsWow64;
|
||||
}
|
||||
|
||||
static void printWindowsVersionInfo( FILE *fp )
|
||||
{
|
||||
OSVERSIONINFOEX osVersionInfoEx;
|
||||
SYSTEM_INFO systemInfo;
|
||||
const char *osName = "Unknown";
|
||||
const char *osProductType = "";
|
||||
const char *processorArchitecture = "Unknown";
|
||||
|
||||
memset( &osVersionInfoEx, 0, sizeof(OSVERSIONINFOEX) );
|
||||
osVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
GetVersionEx( &osVersionInfoEx );
|
||||
|
||||
|
||||
if( osVersionInfoEx.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ){
|
||||
switch( osVersionInfoEx.dwMinorVersion ){
|
||||
case 0: osName = "Windows 95"; break;
|
||||
case 10: osName = "Windows 98"; break; // could also be 98SE (I've seen code discriminate based
|
||||
// on osInfo.Version.Revision.ToString() == "2222A")
|
||||
case 90: osName = "Windows Me"; break;
|
||||
}
|
||||
}else if( osVersionInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT ){
|
||||
switch( osVersionInfoEx.dwMajorVersion ){
|
||||
case 3: osName = "Windows NT 3.51"; break;
|
||||
case 4: osName = "Windows NT 4.0"; break;
|
||||
case 5: switch( osVersionInfoEx.dwMinorVersion ){
|
||||
case 0: osName = "Windows 2000"; break;
|
||||
case 1: osName = "Windows XP"; break;
|
||||
case 2:
|
||||
if( osVersionInfoEx.wSuiteMask & 0x00008000 /*VER_SUITE_WH_SERVER*/ ){
|
||||
osName = "Windows Home Server";
|
||||
}else{
|
||||
if( osVersionInfoEx.wProductType == VER_NT_WORKSTATION ){
|
||||
osName = "Windows XP Professional x64 Edition (?)";
|
||||
}else{
|
||||
if( GetSystemMetrics(/*SM_SERVERR2*/89) == 0 )
|
||||
osName = "Windows Server 2003";
|
||||
else
|
||||
osName = "Windows Server 2003 R2";
|
||||
}
|
||||
}break;
|
||||
}break;
|
||||
case 6:switch( osVersionInfoEx.dwMinorVersion ){
|
||||
case 0:
|
||||
if( osVersionInfoEx.wProductType == VER_NT_WORKSTATION )
|
||||
osName = "Windows Vista";
|
||||
else
|
||||
osName = "Windows Server 2008";
|
||||
break;
|
||||
case 1:
|
||||
if( osVersionInfoEx.wProductType == VER_NT_WORKSTATION )
|
||||
osName = "Windows 7";
|
||||
else
|
||||
osName = "Windows Server 2008 R2";
|
||||
break;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
if(osVersionInfoEx.dwMajorVersion == 4)
|
||||
{
|
||||
if(osVersionInfoEx.wProductType == VER_NT_WORKSTATION)
|
||||
osProductType = "Workstation";
|
||||
else if(osVersionInfoEx.wProductType == VER_NT_SERVER)
|
||||
osProductType = "Server";
|
||||
}
|
||||
else if(osVersionInfoEx.dwMajorVersion == 5)
|
||||
{
|
||||
if(osVersionInfoEx.wProductType == VER_NT_WORKSTATION)
|
||||
{
|
||||
if((osVersionInfoEx.wSuiteMask & VER_SUITE_PERSONAL) == VER_SUITE_PERSONAL)
|
||||
osProductType = "Home Edition"; // Windows XP Home Edition
|
||||
else
|
||||
osProductType = "Professional"; // Windows XP / Windows 2000 Professional
|
||||
}
|
||||
else if(osVersionInfoEx.wProductType == VER_NT_SERVER)
|
||||
{
|
||||
if(osVersionInfoEx.dwMinorVersion == 0)
|
||||
{
|
||||
if((osVersionInfoEx.wSuiteMask & VER_SUITE_DATACENTER) == VER_SUITE_DATACENTER)
|
||||
osProductType = "Datacenter Server"; // Windows 2000 Datacenter Server
|
||||
else if((osVersionInfoEx.wSuiteMask & VER_SUITE_ENTERPRISE) == VER_SUITE_ENTERPRISE)
|
||||
osProductType = "Advanced Server"; // Windows 2000 Advanced Server
|
||||
else
|
||||
osProductType = "Server"; // Windows 2000 Server
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if((osVersionInfoEx.wSuiteMask & VER_SUITE_DATACENTER) == VER_SUITE_DATACENTER)
|
||||
osProductType = "Datacenter Edition"; // Windows Server 2003 Datacenter Edition
|
||||
else if((osVersionInfoEx.wSuiteMask & VER_SUITE_ENTERPRISE) == VER_SUITE_ENTERPRISE)
|
||||
osProductType = "Enterprise Edition"; // Windows Server 2003 Enterprise Edition
|
||||
else if((osVersionInfoEx.wSuiteMask & VER_SUITE_BLADE) == VER_SUITE_BLADE)
|
||||
osProductType = "Web Edition"; // Windows Server 2003 Web Edition
|
||||
else
|
||||
osProductType = "Standard Edition"; // Windows Server 2003 Standard Edition
|
||||
}
|
||||
}
|
||||
|
||||
memset( &systemInfo, 0, sizeof(SYSTEM_INFO) );
|
||||
GetNativeSystemInfo( &systemInfo );
|
||||
|
||||
if( systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
|
||||
processorArchitecture = "x86";
|
||||
else if( systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
|
||||
processorArchitecture = "x64";
|
||||
else if( systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
|
||||
processorArchitecture = "Itanium";
|
||||
|
||||
|
||||
fprintf( fp, "OS name and edition: %s %s\n", osName, osProductType );
|
||||
fprintf( fp, "OS version: %d.%d.%d %S\n",
|
||||
osVersionInfoEx.dwMajorVersion, osVersionInfoEx.dwMinorVersion,
|
||||
osVersionInfoEx.dwBuildNumber, osVersionInfoEx.szCSDVersion );
|
||||
fprintf( fp, "Processor architecture: %s\n", processorArchitecture );
|
||||
fprintf( fp, "WoW64 process: %s\n", IsWow64() ? "Yes" : "No" );
|
||||
}
|
||||
|
||||
static void printTimeAndDate( FILE *fp )
|
||||
{
|
||||
struct tm *local;
|
||||
time_t t;
|
||||
|
||||
t = time(NULL);
|
||||
local = localtime(&t);
|
||||
fprintf(fp, "Local time and date: %s", asctime(local));
|
||||
local = gmtime(&t);
|
||||
fprintf(fp, "UTC time and date: %s", asctime(local));
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
double phase;
|
||||
double phaseIncrement;
|
||||
volatile int fadeIn;
|
||||
volatile int fadeOut;
|
||||
double amp;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
static paTestData data;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i,j;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float x = data->sine[(int)data->phase];
|
||||
data->phase += data->phaseIncrement;
|
||||
if( data->phase >= TABLE_SIZE ){
|
||||
data->phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
x *= data->amp;
|
||||
if( data->fadeIn ){
|
||||
data->amp += .001;
|
||||
if( data->amp >= 1. )
|
||||
data->fadeIn = 0;
|
||||
}else if( data->fadeOut ){
|
||||
if( data->amp > 0 )
|
||||
data->amp -= .001;
|
||||
}
|
||||
|
||||
for( j = 0; j < CHANNEL_COUNT; ++j ){
|
||||
*out++ = x;
|
||||
}
|
||||
}
|
||||
|
||||
if( data->amp > 0 )
|
||||
return paContinue;
|
||||
else
|
||||
return paComplete;
|
||||
}
|
||||
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
|
||||
static int playUntilKeyPress( int deviceIndex, float sampleRate,
|
||||
int framesPerUserBuffer, int framesPerWmmeBuffer, int wmmeBufferCount )
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaWinMmeStreamInfo wmmeStreamInfo;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
int c;
|
||||
|
||||
outputParameters.device = deviceIndex;
|
||||
outputParameters.channelCount = CHANNEL_COUNT;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
|
||||
outputParameters.suggestedLatency = 0; /*Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;*/
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo);
|
||||
wmmeStreamInfo.hostApiType = paMME;
|
||||
wmmeStreamInfo.version = 1;
|
||||
wmmeStreamInfo.flags = paWinMmeUseLowLevelLatencyParameters | paWinMmeDontThrottleOverloadedProcessingThread;
|
||||
wmmeStreamInfo.framesPerBuffer = framesPerWmmeBuffer;
|
||||
wmmeStreamInfo.bufferCount = wmmeBufferCount;
|
||||
outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo;
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
sampleRate,
|
||||
framesPerUserBuffer,
|
||||
paClipOff | paPrimeOutputBuffersUsingStreamCallback, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
data.amp = 0;
|
||||
data.fadeIn = 1;
|
||||
data.fadeOut = 0;
|
||||
data.phase = 0;
|
||||
data.phaseIncrement = 15 + ((rand()%100) / 10); // randomise pitch
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
|
||||
do{
|
||||
printf( "Trying buffer size %d.\nIf it sounds smooth (without clicks or glitches) press 'y', if it sounds bad press 'n' ('q' to quit)\n", framesPerWmmeBuffer );
|
||||
c = tolower(_getch());
|
||||
if( c == 'q' ){
|
||||
Pa_Terminate();
|
||||
exit(0);
|
||||
}
|
||||
}while( c != 'y' && c != 'n' );
|
||||
|
||||
data.fadeOut = 1;
|
||||
while( Pa_IsStreamActive(stream) == 1 )
|
||||
Pa_Sleep( 100 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
return (c == 'y') ? YES : NO;
|
||||
|
||||
error:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
static void usage( int wmmeHostApiIndex )
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf( stderr, "PortAudio WMME output latency user guided test\n" );
|
||||
fprintf( stderr, "Usage: x.exe mme-device-index [sampleRate [min-buffer-count max-buffer-count]]\n" );
|
||||
fprintf( stderr, "Invalid device index. Use one of these:\n" );
|
||||
for( i=0; i < Pa_GetDeviceCount(); ++i ){
|
||||
|
||||
if( Pa_GetDeviceInfo(i)->hostApi == wmmeHostApiIndex && Pa_GetDeviceInfo(i)->maxOutputChannels > 0 )
|
||||
fprintf( stderr, "%d (%s)\n", i, Pa_GetDeviceInfo(i)->name );
|
||||
}
|
||||
Pa_Terminate();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
ideas:
|
||||
o- could be testing with 80% CPU load
|
||||
o- could test with different channel counts
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
PaError err;
|
||||
int i;
|
||||
int deviceIndex;
|
||||
int wmmeBufferCount, wmmeBufferSize, smallestWorkingBufferSize;
|
||||
int smallestWorkingBufferingLatencyFrames;
|
||||
int min, max, mid;
|
||||
int testResult;
|
||||
FILE *resultsFp;
|
||||
int wmmeHostApiIndex;
|
||||
const PaHostApiInfo *wmmeHostApiInfo;
|
||||
double sampleRate = DEFAULT_SAMPLE_RATE;
|
||||
int wmmeMinBufferCount = MIN_WMME_BUFFER_COUNT;
|
||||
int wmmeMaxBufferCount = MAX_WMME_BUFFER_COUNT;
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
wmmeHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( paMME );
|
||||
wmmeHostApiInfo = Pa_GetHostApiInfo( wmmeHostApiIndex );
|
||||
|
||||
if( argc > 5 )
|
||||
usage(wmmeHostApiIndex);
|
||||
|
||||
deviceIndex = wmmeHostApiInfo->defaultOutputDevice;
|
||||
if( argc >= 2 ){
|
||||
deviceIndex = -1;
|
||||
if( sscanf( argv[1], "%d", &deviceIndex ) != 1 )
|
||||
usage(wmmeHostApiIndex);
|
||||
if( deviceIndex < 0 || deviceIndex >= Pa_GetDeviceCount() || Pa_GetDeviceInfo(deviceIndex)->hostApi != wmmeHostApiIndex ){
|
||||
usage(wmmeHostApiIndex);
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
|
||||
|
||||
if( argc >= 3 ){
|
||||
if( sscanf( argv[2], "%lf", &sampleRate ) != 1 )
|
||||
usage(wmmeHostApiIndex);
|
||||
}
|
||||
|
||||
printf( "Testing with sample rate %f.\n", (float)sampleRate );
|
||||
|
||||
if( argc == 4 ){
|
||||
if( sscanf( argv[3], "%d", &wmmeMinBufferCount ) != 1 )
|
||||
usage(wmmeHostApiIndex);
|
||||
wmmeMaxBufferCount = wmmeMinBufferCount;
|
||||
}
|
||||
|
||||
if( argc == 5 ){
|
||||
if( sscanf( argv[3], "%d", &wmmeMinBufferCount ) != 1 )
|
||||
usage(wmmeHostApiIndex);
|
||||
if( sscanf( argv[4], "%d", &wmmeMaxBufferCount ) != 1 )
|
||||
usage(wmmeHostApiIndex);
|
||||
}
|
||||
|
||||
printf( "Testing buffer counts from %d to %d\n", wmmeMinBufferCount, wmmeMaxBufferCount );
|
||||
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
data.phase = 0;
|
||||
|
||||
resultsFp = fopen( "results.txt", "at" );
|
||||
fprintf( resultsFp, "*** WMME smallest working output buffer sizes\n" );
|
||||
|
||||
printTimeAndDate( resultsFp );
|
||||
printWindowsVersionInfo( resultsFp );
|
||||
|
||||
fprintf( resultsFp, "audio device: %s\n", Pa_GetDeviceInfo( deviceIndex )->name );
|
||||
fflush( resultsFp );
|
||||
|
||||
fprintf( resultsFp, "Sample rate: %f\n", (float)sampleRate );
|
||||
fprintf( resultsFp, "Buffer count, Smallest working buffer size (frames), Smallest working buffering latency (frames), Smallest working buffering latency (Seconds)\n" );
|
||||
|
||||
for( wmmeBufferCount = wmmeMinBufferCount; wmmeBufferCount <= wmmeMaxBufferCount; ++wmmeBufferCount ){
|
||||
|
||||
printf( "Test %d of %d\n", (wmmeBufferCount - wmmeMinBufferCount) + 1, (wmmeMaxBufferCount-wmmeMinBufferCount) + 1 );
|
||||
printf( "Testing with %d buffers...\n", wmmeBufferCount );
|
||||
|
||||
/*
|
||||
Binary search after Niklaus Wirth
|
||||
from http://en.wikipedia.org/wiki/Binary_search_algorithm#The_algorithm
|
||||
*/
|
||||
min = 1;
|
||||
max = (int)((sampleRate * .3) / (wmmeBufferCount-1)); //8192; /* we assume that this size works 300ms */
|
||||
smallestWorkingBufferSize = 0;
|
||||
|
||||
do{
|
||||
mid = min + ((max - min) / 2);
|
||||
|
||||
wmmeBufferSize = mid;
|
||||
testResult = playUntilKeyPress( deviceIndex, sampleRate, wmmeBufferSize, wmmeBufferSize, wmmeBufferCount );
|
||||
|
||||
if( testResult == YES ){
|
||||
max = mid - 1;
|
||||
smallestWorkingBufferSize = wmmeBufferSize;
|
||||
}else{
|
||||
min = mid + 1;
|
||||
}
|
||||
|
||||
}while( (min <= max) && (testResult == YES || testResult == NO) );
|
||||
|
||||
smallestWorkingBufferingLatencyFrames = smallestWorkingBufferSize * (wmmeBufferCount - 1);
|
||||
|
||||
printf( "Smallest working buffer size for %d buffers is: %d\n", wmmeBufferCount, smallestWorkingBufferSize );
|
||||
printf( "Corresponding to buffering latency of %d frames, or %f seconds.\n", smallestWorkingBufferingLatencyFrames, smallestWorkingBufferingLatencyFrames / sampleRate );
|
||||
|
||||
fprintf( resultsFp, "%d, %d, %d, %f\n", wmmeBufferCount, smallestWorkingBufferSize, smallestWorkingBufferingLatencyFrames, smallestWorkingBufferingLatencyFrames / sampleRate );
|
||||
fflush( resultsFp );
|
||||
}
|
||||
|
||||
fprintf( resultsFp, "###\n" );
|
||||
fclose( resultsFp );
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
191
third_party/portaudio/test/patest_wmme_low_level_latency_params.c
vendored
Normal file
191
third_party/portaudio/test/patest_wmme_low_level_latency_params.c
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* $Id: $
|
||||
* Portable Audio I/O Library
|
||||
* Windows MME low level buffer parameters test
|
||||
*
|
||||
* Copyright (c) 2007 Ross Bencina
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <windows.h> /* required when using pa_win_wmme.h */
|
||||
#include <mmsystem.h> /* required when using pa_win_wmme.h */
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_wmme.h"
|
||||
|
||||
#define NUM_SECONDS (6)
|
||||
#define SAMPLE_RATE (44100)
|
||||
|
||||
#define WMME_FRAMES_PER_BUFFER (440)
|
||||
#define WMME_BUFFER_COUNT (6)
|
||||
|
||||
#define FRAMES_PER_BUFFER WMME_FRAMES_PER_BUFFER /* hardwire portaudio callback buffer size to WMME buffer size for this test */
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (2048)
|
||||
|
||||
#define CHANNEL_COUNT (2)
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float sine[TABLE_SIZE];
|
||||
double phase;
|
||||
}
|
||||
paTestData;
|
||||
|
||||
/* This routine will be called by the PortAudio engine when audio is needed.
|
||||
** It may called at interrupt level on some machines so don't do anything
|
||||
** that could mess up the system like calling malloc() or free().
|
||||
*/
|
||||
static int patestCallback( const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* timeInfo,
|
||||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData )
|
||||
{
|
||||
paTestData *data = (paTestData*)userData;
|
||||
float *out = (float*)outputBuffer;
|
||||
unsigned long i,j;
|
||||
|
||||
(void) timeInfo; /* Prevent unused variable warnings. */
|
||||
(void) statusFlags;
|
||||
(void) inputBuffer;
|
||||
|
||||
for( i=0; i<framesPerBuffer; i++ )
|
||||
{
|
||||
float x = data->sine[(int)data->phase];
|
||||
data->phase += 20;
|
||||
if( data->phase >= TABLE_SIZE ){
|
||||
data->phase -= TABLE_SIZE;
|
||||
}
|
||||
|
||||
for( j = 0; j < CHANNEL_COUNT; ++j ){
|
||||
*out++ = x;
|
||||
}
|
||||
}
|
||||
|
||||
return paContinue;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaWinMmeStreamInfo wmmeStreamInfo;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
paTestData data;
|
||||
int i;
|
||||
int deviceIndex;
|
||||
|
||||
printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paMME ) )->defaultOutputDevice;
|
||||
if( argc == 2 ){
|
||||
sscanf( argv[1], "%d", &deviceIndex );
|
||||
}
|
||||
|
||||
printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
data.phase = 0;
|
||||
|
||||
outputParameters.device = deviceIndex;
|
||||
outputParameters.channelCount = CHANNEL_COUNT;
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
|
||||
outputParameters.suggestedLatency = 0; /*Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;*/
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo);
|
||||
wmmeStreamInfo.hostApiType = paMME;
|
||||
wmmeStreamInfo.version = 1;
|
||||
wmmeStreamInfo.flags = paWinMmeUseLowLevelLatencyParameters | paWinMmeDontThrottleOverloadedProcessingThread;
|
||||
wmmeStreamInfo.framesPerBuffer = WMME_FRAMES_PER_BUFFER;
|
||||
wmmeStreamInfo.bufferCount = WMME_BUFFER_COUNT;
|
||||
outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo;
|
||||
|
||||
|
||||
if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){
|
||||
printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
|
||||
}else{
|
||||
printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
|
||||
}
|
||||
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
patestCallback,
|
||||
&data );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Play for %d seconds.\n", NUM_SECONDS );
|
||||
Pa_Sleep( NUM_SECONDS * 1000 );
|
||||
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
165
third_party/portaudio/test/patest_write_stop.c
vendored
Normal file
165
third_party/portaudio/test/patest_write_stop.c
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
/** @file patest_write_stop.c
|
||||
@brief Play a few seconds of silence followed by a few cycles of a sine wave. Tests to make sure that pa_StopStream() completes playback in blocking I/O
|
||||
@author Bjorn Roche of XO Audio (www.xoaudio.com)
|
||||
@author Ross Bencina
|
||||
@author Phil Burk
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define NUM_SECONDS (5)
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (1024)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (3.14159265)
|
||||
#endif
|
||||
|
||||
#define TABLE_SIZE (200)
|
||||
|
||||
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
|
||||
float sine[TABLE_SIZE]; /* sine wavetable */
|
||||
int left_phase = 0;
|
||||
int right_phase = 0;
|
||||
int left_inc = 1;
|
||||
int right_inc = 3; /* higher pitch so we can distinguish left and right. */
|
||||
int i, j;
|
||||
int bufferCount;
|
||||
const int framesBy2 = FRAMES_PER_BUFFER >> 1;
|
||||
const float framesBy2f = (float) framesBy2 ;
|
||||
|
||||
|
||||
printf( "PortAudio Test: output silence, followed by one buffer of a ramped sine wave. SR = %d, BufSize = %d\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
for( i=0; i<TABLE_SIZE; i++ )
|
||||
{
|
||||
sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
|
||||
}
|
||||
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency * 5;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
/* open the stream */
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
NULL, /* no callback, use blocking API */
|
||||
NULL ); /* no callback, so no callback userData */
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* start the stream */
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
printf("Playing %d seconds of silence followed by one buffer of a ramped sinusoid.\n", NUM_SECONDS );
|
||||
|
||||
bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER);
|
||||
|
||||
/* clear buffer */
|
||||
for( j=0; j < FRAMES_PER_BUFFER; j++ )
|
||||
{
|
||||
buffer[j][0] = 0; /* left */
|
||||
buffer[j][1] = 0; /* right */
|
||||
}
|
||||
/* play the silent buffer a bunch o' times */
|
||||
for( i=0; i < bufferCount; i++ )
|
||||
{
|
||||
err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
|
||||
if( err != paNoError ) goto error;
|
||||
}
|
||||
/* play a non-silent buffer once */
|
||||
for( j=0; j < FRAMES_PER_BUFFER; j++ )
|
||||
{
|
||||
float ramp = 1;
|
||||
if( j < framesBy2 )
|
||||
ramp = j / framesBy2f;
|
||||
else
|
||||
ramp = (FRAMES_PER_BUFFER - j) / framesBy2f ;
|
||||
|
||||
buffer[j][0] = sine[left_phase] * ramp; /* left */
|
||||
buffer[j][1] = sine[right_phase] * ramp; /* right */
|
||||
left_phase += left_inc;
|
||||
if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
|
||||
right_phase += right_inc;
|
||||
if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
|
||||
}
|
||||
err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* stop stream, close, and terminate */
|
||||
err = Pa_StopStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
168
third_party/portaudio/test/patest_write_stop_hang_illegal.c
vendored
Normal file
168
third_party/portaudio/test/patest_write_stop_hang_illegal.c
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
/** @file patest_write_stop_threads.c
|
||||
@brief Call Pa_StopStream() from another thread to see if PortAudio hangs.
|
||||
@author Bjorn Roche of XO Audio (www.xoaudio.com)
|
||||
@author Ross Bencina
|
||||
@author Phil Burk
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This program uses the PortAudio Portable Audio Library.
|
||||
* For more information see: http://www.portaudio.com/
|
||||
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* the PortAudio community also makes the following non-binding requests:
|
||||
*
|
||||
* Any person wishing to distribute modifications to the Software is
|
||||
* requested to send the modifications to the original developer so that
|
||||
* they can be incorporated into the canonical version. It is also
|
||||
* requested that these non-binding requests be included along with the
|
||||
* license above.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
/* pthread may only be available on Mac and Linux. */
|
||||
#include <pthread.h>
|
||||
#include "portaudio.h"
|
||||
|
||||
#define SAMPLE_RATE (44100)
|
||||
#define FRAMES_PER_BUFFER (2048)
|
||||
|
||||
static float s_buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
|
||||
|
||||
/**
|
||||
* WARNING: PortAudio is NOT thread safe. DO NOT call PortAudio
|
||||
* from multiple threads without synchronization. This test uses
|
||||
* PA in an ILLEGAL WAY in order to try to flush out potential hang bugs.
|
||||
* The test calls Pa_WriteStream() and Pa_StopStream() simultaneously
|
||||
* from separate threads in order to try to cause Pa_StopStream() to hang.
|
||||
* In the main thread we write to the stream in a loop.
|
||||
* Then try stopping PA from another thread to see if it hangs.
|
||||
*
|
||||
* @note: Do not expect this test to pass. The test is only here
|
||||
* as a debugging aid for hang bugs. Since this test uses PA in an
|
||||
* illegal way, it may fail for reasons that are not PA bugs.
|
||||
*/
|
||||
|
||||
/* Wait awhile then abort the stream. */
|
||||
void *stop_thread_proc(void *arg)
|
||||
{
|
||||
PaStream *stream = (PaStream *)arg;
|
||||
PaTime time;
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
/* ILLEGAL unsynchronised call to PA, see comment above */
|
||||
time = Pa_GetStreamTime( stream );
|
||||
printf("Stream time = %f\n", time);
|
||||
fflush(stdout);
|
||||
usleep(100 * 1000);
|
||||
}
|
||||
printf("Call Pa_StopStream()\n");
|
||||
fflush(stdout);
|
||||
/* ILLEGAL unsynchronised call to PA, see comment above */
|
||||
PaError err = Pa_StopStream( stream );
|
||||
printf("Pa_StopStream() returned %d\n", err);
|
||||
fflush(stdout);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
PaStreamParameters outputParameters;
|
||||
PaStream *stream;
|
||||
PaError err;
|
||||
int result;
|
||||
pthread_t thread;
|
||||
|
||||
printf( "PortAudio Test: output silence and stop from another thread. SR = %d, BufSize = %d\n",
|
||||
SAMPLE_RATE, FRAMES_PER_BUFFER);
|
||||
|
||||
err = Pa_Initialize();
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
|
||||
outputParameters.channelCount = 2; /* stereo output */
|
||||
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
|
||||
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency * 5;
|
||||
outputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
/* open the stream */
|
||||
err = Pa_OpenStream(
|
||||
&stream,
|
||||
NULL, /* no input */
|
||||
&outputParameters,
|
||||
SAMPLE_RATE,
|
||||
FRAMES_PER_BUFFER,
|
||||
paClipOff, /* we won't output out of range samples so don't bother clipping them */
|
||||
NULL, /* no callback, use blocking API */
|
||||
NULL ); /* no callback, so no callback userData */
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
result = pthread_create(&thread, NULL /* attributes */, stop_thread_proc, stream);
|
||||
|
||||
/* start the stream */
|
||||
err = Pa_StartStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
/* clear buffer */
|
||||
memset( s_buffer, 0, sizeof(s_buffer) );
|
||||
|
||||
/* play the silent buffer many times */
|
||||
while( Pa_IsStreamActive(stream) > 0 )
|
||||
{
|
||||
err = Pa_WriteStream( stream, s_buffer, FRAMES_PER_BUFFER );
|
||||
printf("Pa_WriteStream returns %d = %s\n", err, Pa_GetErrorText( err ));
|
||||
if( err != paNoError )
|
||||
{
|
||||
err = paNoError;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
printf("Try to join the thread that called Pa_StopStream().\n");
|
||||
result = pthread_join( thread, NULL );
|
||||
printf("pthread_join returned %d\n", result);
|
||||
|
||||
/* close, and terminate */
|
||||
printf("Call Pa_CloseStream\n");
|
||||
err = Pa_CloseStream( stream );
|
||||
if( err != paNoError ) goto error;
|
||||
|
||||
Pa_Terminate();
|
||||
printf("Test finished.\n");
|
||||
|
||||
return err;
|
||||
error:
|
||||
Pa_Terminate();
|
||||
fprintf( stderr, "An error occurred while using the portaudio stream\n" );
|
||||
fprintf( stderr, "Error number: %d\n", err );
|
||||
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return err;
|
||||
}
|
||||
Reference in New Issue
Block a user