annotate src/portaudio_20161030/test/patest_latency.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 284acf908dcd
children
rev   line source
Chris@4 1 /** @file
Chris@4 2 @ingroup test_src
Chris@4 3 @brief Hear the latency caused by big buffers.
Chris@4 4 Play a sine wave and change frequency based on letter input.
Chris@4 5 @author Phil Burk <philburk@softsynth.com>, and Darren Gibbs
Chris@4 6 */
Chris@4 7 /*
Chris@55 8 * $Id$
Chris@4 9 *
Chris@4 10 * This program uses the PortAudio Portable Audio Library.
Chris@4 11 * For more information see: http://www.portaudio.com
Chris@4 12 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
Chris@4 13 *
Chris@4 14 * Permission is hereby granted, free of charge, to any person obtaining
Chris@4 15 * a copy of this software and associated documentation files
Chris@4 16 * (the "Software"), to deal in the Software without restriction,
Chris@4 17 * including without limitation the rights to use, copy, modify, merge,
Chris@4 18 * publish, distribute, sublicense, and/or sell copies of the Software,
Chris@4 19 * and to permit persons to whom the Software is furnished to do so,
Chris@4 20 * subject to the following conditions:
Chris@4 21 *
Chris@4 22 * The above copyright notice and this permission notice shall be
Chris@4 23 * included in all copies or substantial portions of the Software.
Chris@4 24 *
Chris@4 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@4 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@4 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@4 28 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@4 29 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@4 30 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@4 31 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@4 32 */
Chris@4 33
Chris@4 34 /*
Chris@4 35 * The text above constitutes the entire PortAudio license; however,
Chris@4 36 * the PortAudio community also makes the following non-binding requests:
Chris@4 37 *
Chris@4 38 * Any person wishing to distribute modifications to the Software is
Chris@4 39 * requested to send the modifications to the original developer so that
Chris@4 40 * they can be incorporated into the canonical version. It is also
Chris@4 41 * requested that these non-binding requests be included along with the
Chris@4 42 * license above.
Chris@4 43 */
Chris@4 44
Chris@4 45 #include <stdio.h>
Chris@4 46 #include <math.h>
Chris@4 47 #include "portaudio.h"
Chris@4 48
Chris@4 49 #define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice())
Chris@4 50 #define SAMPLE_RATE (44100)
Chris@4 51 #define FRAMES_PER_BUFFER (64)
Chris@4 52
Chris@4 53 #define MIN_FREQ (100.0f)
Chris@4 54 #define CalcPhaseIncrement(freq) ((freq)/SAMPLE_RATE)
Chris@4 55 #ifndef M_PI
Chris@4 56 #define M_PI (3.14159265)
Chris@4 57 #endif
Chris@4 58 #define TABLE_SIZE (400)
Chris@4 59
Chris@4 60 typedef struct
Chris@4 61 {
Chris@4 62 float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
Chris@4 63 float phase_increment;
Chris@4 64 float left_phase;
Chris@4 65 float right_phase;
Chris@4 66 }
Chris@4 67 paTestData;
Chris@4 68
Chris@4 69 float LookupSine( paTestData *data, float phase );
Chris@4 70 /* Convert phase between and 1.0 to sine value
Chris@4 71 * using linear interpolation.
Chris@4 72 */
Chris@4 73 float LookupSine( paTestData *data, float phase )
Chris@4 74 {
Chris@4 75 float fIndex = phase*TABLE_SIZE;
Chris@4 76 int index = (int) fIndex;
Chris@4 77 float fract = fIndex - index;
Chris@4 78 float lo = data->sine[index];
Chris@4 79 float hi = data->sine[index+1];
Chris@4 80 float val = lo + fract*(hi-lo);
Chris@4 81 return val;
Chris@4 82 }
Chris@4 83
Chris@4 84 /* This routine will be called by the PortAudio engine when audio is needed.
Chris@4 85 ** It may called at interrupt level on some machines so don't do anything
Chris@4 86 ** that could mess up the system like calling malloc() or free().
Chris@4 87 */
Chris@4 88 static int patestCallback( const void *inputBuffer, void *outputBuffer,
Chris@4 89 unsigned long framesPerBuffer,
Chris@4 90 const PaStreamCallbackTimeInfo* timeInfo,
Chris@4 91 PaStreamCallbackFlags statusFlags,
Chris@4 92 void *userData )
Chris@4 93 {
Chris@4 94 paTestData *data = (paTestData*)userData;
Chris@4 95 float *out = (float*)outputBuffer;
Chris@4 96 int i;
Chris@4 97
Chris@4 98 (void) inputBuffer; /* Prevent unused variable warning. */
Chris@4 99
Chris@4 100 for( i=0; i<framesPerBuffer; i++ )
Chris@4 101 {
Chris@4 102 *out++ = LookupSine(data, data->left_phase); /* left */
Chris@4 103 *out++ = LookupSine(data, data->right_phase); /* right */
Chris@4 104 data->left_phase += data->phase_increment;
Chris@4 105 if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f;
Chris@4 106 data->right_phase += (data->phase_increment * 1.5f); /* fifth above */
Chris@4 107 if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f;
Chris@4 108 }
Chris@4 109 return 0;
Chris@4 110 }
Chris@4 111
Chris@4 112 /*******************************************************************/
Chris@4 113 int main(void);
Chris@4 114 int main(void)
Chris@4 115 {
Chris@4 116 PaStream *stream;
Chris@4 117 PaStreamParameters outputParameters;
Chris@4 118 PaError err;
Chris@4 119 paTestData data;
Chris@4 120 int i;
Chris@4 121 int done = 0;
Chris@4 122
Chris@4 123 printf("PortAudio Test: enter letter then hit ENTER.\n" );
Chris@4 124 /* initialise sinusoidal wavetable */
Chris@4 125 for( i=0; i<TABLE_SIZE; i++ )
Chris@4 126 {
Chris@4 127 data.sine[i] = 0.90f * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
Chris@4 128 }
Chris@4 129 data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point. */
Chris@4 130 data.left_phase = data.right_phase = 0.0;
Chris@4 131 data.phase_increment = CalcPhaseIncrement(MIN_FREQ);
Chris@4 132
Chris@4 133 err = Pa_Initialize();
Chris@4 134 if( err != paNoError ) goto error;
Chris@4 135 printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
Chris@4 136
Chris@4 137 outputParameters.device = OUTPUT_DEVICE;
Chris@4 138 if (outputParameters.device == paNoDevice) {
Chris@4 139 fprintf(stderr,"Error: No default output device.\n");
Chris@4 140 goto error;
Chris@4 141 }
Chris@4 142 outputParameters.channelCount = 2; /* stereo output */
Chris@4 143 outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
Chris@4 144 outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
Chris@4 145 outputParameters.hostApiSpecificStreamInfo = NULL;
Chris@4 146
Chris@4 147 printf("Requested output latency = %.4f seconds.\n", outputParameters.suggestedLatency );
Chris@4 148 printf("%d frames per buffer.\n.", FRAMES_PER_BUFFER );
Chris@4 149
Chris@4 150 err = Pa_OpenStream(
Chris@4 151 &stream,
Chris@4 152 NULL, /* no input */
Chris@4 153 &outputParameters,
Chris@4 154 SAMPLE_RATE,
Chris@4 155 FRAMES_PER_BUFFER,
Chris@4 156 paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */
Chris@4 157 patestCallback,
Chris@4 158 &data );
Chris@4 159 if( err != paNoError ) goto error;
Chris@4 160
Chris@4 161 err = Pa_StartStream( stream );
Chris@4 162 if( err != paNoError ) goto error;
Chris@4 163 printf("Play ASCII keyboard. Hit 'q' to stop. (Use RETURN key on Mac)\n");
Chris@4 164 fflush(stdout);
Chris@4 165 while ( !done )
Chris@4 166 {
Chris@4 167 float freq;
Chris@4 168 int index;
Chris@4 169 char c;
Chris@4 170 do
Chris@4 171 {
Chris@4 172 c = getchar();
Chris@4 173 }
Chris@4 174 while( c < ' '); /* Strip white space and control chars. */
Chris@4 175
Chris@4 176 if( c == 'q' ) done = 1;
Chris@4 177 index = c % 26;
Chris@4 178 freq = MIN_FREQ + (index * 40.0);
Chris@4 179 data.phase_increment = CalcPhaseIncrement(freq);
Chris@4 180 }
Chris@4 181 printf("Call Pa_StopStream()\n");
Chris@4 182 err = Pa_StopStream( stream );
Chris@4 183 if( err != paNoError ) goto error;
Chris@4 184 Pa_Terminate();
Chris@4 185 printf("Test finished.\n");
Chris@4 186 return err;
Chris@4 187 error:
Chris@4 188 Pa_Terminate();
Chris@4 189 fprintf( stderr, "An error occured while using the portaudio stream\n" );
Chris@4 190 fprintf( stderr, "Error number: %d\n", err );
Chris@4 191 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
Chris@4 192 return err;
Chris@4 193 }