2007-09-21 14:49:14 -04:00
/** @file patest_timing.c
@ ingroup test_src
@ brief Play a sine wave for several seconds , and spits out a ton of timing info while it ' s at it . Based on patet_sine . c
@ author Bjorn Roche
@ author Ross Bencina < rossb @ audiomulch . com >
@ author Phil Burk < philburk @ softsynth . com >
*/
/*
* $ Id : patest_sine . c 578 2003 - 09 - 02 04 : 17 : 38 Z rossbencina $
*
* This program uses the PortAudio Portable Audio Library .
* For more information see : http : //www.portaudio.com/
* Copyright ( c ) 1999 - 2000 Ross Bencina and Phil Burk
*
* Permission is hereby granted , free of charge , to any person obtaining
* a copy of this software and associated documentation files
* ( the " Software " ) , to deal in the Software without restriction ,
* including without limitation the rights to use , copy , modify , merge ,
* publish , distribute , sublicense , and / or sell copies of the Software ,
* and to permit persons to whom the Software is furnished to do so ,
* subject to the following conditions :
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND ,
* EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT .
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF
* CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
*/
/*
* The text above constitutes the entire PortAudio license ; however ,
* the PortAudio community also makes the following non - binding requests :
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version . It is also
* requested that these non - binding requests be included along with the
* license above .
*/
# include <stdio.h>
# include <math.h>
# include "portaudio.h"
# define NUM_SECONDS (5)
# define SAMPLE_RATE (44100)
# define FRAMES_PER_BUFFER (64)
# ifndef M_PI
# define M_PI (3.14159265)
# endif
# define TABLE_SIZE (200)
typedef struct
{
PaStream * stream ;
PaTime start ;
float sine [ TABLE_SIZE ] ;
int left_phase ;
int right_phase ;
}
paTestData ;
/* This routine will be called by the PortAudio engine when audio is needed.
* * It may called at interrupt level on some machines so don ' t do anything
* * that could mess up the system like calling malloc ( ) or free ( ) .
*/
static int patestCallback ( const void * inputBuffer , void * outputBuffer ,
unsigned long framesPerBuffer ,
const PaStreamCallbackTimeInfo * timeInfo ,
PaStreamCallbackFlags statusFlags ,
void * userData )
{
paTestData * data = ( paTestData * ) userData ;
float * out = ( float * ) outputBuffer ;
unsigned long i ;
( void ) timeInfo ; /* Prevent unused variable warnings. */
( void ) statusFlags ;
( void ) inputBuffer ;
printf ( " Timing info given to callback: Adc: %g, Current: %g, Dac: %g \n " ,
timeInfo - > inputBufferAdcTime ,
timeInfo - > currentTime ,
timeInfo - > outputBufferDacTime ) ;
printf ( " getStreamTime() returns: %g \n " , Pa_GetStreamTime ( data - > stream ) - data - > start ) ;
for ( i = 0 ; i < framesPerBuffer ; i + + )
{
* out + + = data - > sine [ data - > left_phase ] ; /* left */
* out + + = data - > sine [ data - > right_phase ] ; /* right */
data - > left_phase + = 1 ;
if ( data - > left_phase > = TABLE_SIZE ) data - > left_phase - = TABLE_SIZE ;
data - > right_phase + = 3 ; /* higher pitch so we can distinguish left and right. */
if ( data - > right_phase > = TABLE_SIZE ) data - > right_phase - = TABLE_SIZE ;
}
return paContinue ;
}
/*******************************************************************/
int main ( void ) ;
int main ( void )
{
PaStreamParameters outputParameters ;
PaStream * stream ;
PaError err ;
paTestData data ;
int i ;
printf ( " PortAudio Test: output sine wave. SR = %d, BufSize = %d \n " , SAMPLE_RATE , FRAMES_PER_BUFFER ) ;
/* initialise sinusoidal wavetable */
for ( i = 0 ; i < TABLE_SIZE ; i + + )
{
data . sine [ i ] = ( float ) sin ( ( ( double ) i / ( double ) TABLE_SIZE ) * M_PI * 2. ) ;
}
data . left_phase = data . right_phase = 0 ;
err = Pa_Initialize ( ) ;
if ( err ! = paNoError ) goto error ;
outputParameters . device = Pa_GetDefaultOutputDevice ( ) ; /* default output device */
outputParameters . channelCount = 2 ; /* stereo output */
outputParameters . sampleFormat = paFloat32 ; /* 32 bit floating point output */
outputParameters . suggestedLatency = Pa_GetDeviceInfo ( outputParameters . device ) - > defaultLowOutputLatency ;
outputParameters . hostApiSpecificStreamInfo = NULL ;
err = Pa_OpenStream (
& stream ,
NULL , /* no input */
& outputParameters ,
SAMPLE_RATE ,
FRAMES_PER_BUFFER ,
paClipOff , /* we won't output out of range samples so don't bother clipping them */
patestCallback ,
& data ) ;
data . stream = stream ;
data . start = Pa_GetStreamTime ( stream ) ;
if ( err ! = paNoError ) goto error ;
err = Pa_StartStream ( stream ) ;
data . start = Pa_GetStreamTime ( stream ) ;
if ( err ! = paNoError ) goto error ;
printf ( " Play for %d seconds. \n " , NUM_SECONDS ) ;
Pa_Sleep ( NUM_SECONDS * 1000 ) ;
err = Pa_StopStream ( stream ) ;
if ( err ! = paNoError ) goto error ;
err = Pa_CloseStream ( stream ) ;
if ( err ! = paNoError ) goto error ;
Pa_Terminate ( ) ;
printf ( " Test finished. \n " ) ;
printf ( " The tone should have been heard for about 5 seconds and all the timing info above should report that about 5 seconds elapsed (except Adc, which is undefined since there was no input device opened). \n " ) ;
return err ;
error :
Pa_Terminate ( ) ;
fprintf ( stderr , " An error occured while using the portaudio stream \n " ) ;
fprintf ( stderr , " Error number: %d \n " , err ) ;
fprintf ( stderr , " Error message: %s \n " , Pa_GetErrorText ( err ) ) ;
return err ;
}