annotate src/portaudio/test/patest_suggested_vs_streaminfo_latency.c @ 23:619f715526df sv_v2.1

Update Vamp plugin SDK to 2.5
author Chris Cannam
date Thu, 09 May 2013 10:52:46 +0100
parents e13257ea84a4
children
rev   line source
Chris@4 1 /** @file patest_suggested_vs_streaminfo_latency.c
Chris@4 2 @ingroup test_src
Chris@4 3 @brief Print suggested vs. PaStreamInfo reported actual latency
Chris@4 4 @author Ross Bencina <rossb@audiomulch.com>
Chris@4 5
Chris@4 6 Opens streams with a sequence of suggested latency values
Chris@4 7 from 0 to 2 seconds in .5ms intervals and gathers the resulting actual
Chris@4 8 latency values. Output a csv file and graph suggested vs. actual. Run
Chris@4 9 with framesPerBuffer unspecified, powers of 2 and multiples of 50 and
Chris@4 10 prime number buffer sizes.
Chris@4 11 */
Chris@4 12 /*
Chris@4 13 * $Id: patest_sine.c 1368 2008-03-01 00:38:27Z rossb $
Chris@4 14 *
Chris@4 15 * This program uses the PortAudio Portable Audio Library.
Chris@4 16 * For more information see: http://www.portaudio.com/
Chris@4 17 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
Chris@4 18 *
Chris@4 19 * Permission is hereby granted, free of charge, to any person obtaining
Chris@4 20 * a copy of this software and associated documentation files
Chris@4 21 * (the "Software"), to deal in the Software without restriction,
Chris@4 22 * including without limitation the rights to use, copy, modify, merge,
Chris@4 23 * publish, distribute, sublicense, and/or sell copies of the Software,
Chris@4 24 * and to permit persons to whom the Software is furnished to do so,
Chris@4 25 * subject to the following conditions:
Chris@4 26 *
Chris@4 27 * The above copyright notice and this permission notice shall be
Chris@4 28 * included in all copies or substantial portions of the Software.
Chris@4 29 *
Chris@4 30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@4 31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@4 32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@4 33 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@4 34 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@4 35 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@4 36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@4 37 */
Chris@4 38
Chris@4 39 /*
Chris@4 40 * The text above constitutes the entire PortAudio license; however,
Chris@4 41 * the PortAudio community also makes the following non-binding requests:
Chris@4 42 *
Chris@4 43 * Any person wishing to distribute modifications to the Software is
Chris@4 44 * requested to send the modifications to the original developer so that
Chris@4 45 * they can be incorporated into the canonical version. It is also
Chris@4 46 * requested that these non-binding requests be included along with the
Chris@4 47 * license above.
Chris@4 48 */
Chris@4 49 #include <stdio.h>
Chris@4 50 #include <stdlib.h>
Chris@4 51 #include <string.h>
Chris@4 52 #include <math.h>
Chris@4 53 #include "portaudio.h"
Chris@4 54
Chris@4 55 #define SAMPLE_RATE (44100)
Chris@4 56 #define FRAMES_PER_BUFFER 2//(128)
Chris@4 57 #define NUM_CHANNELS (2)
Chris@4 58
Chris@4 59 #define SUGGESTED_LATENCY_START_SECONDS (0.0)
Chris@4 60 #define SUGGESTED_LATENCY_END_SECONDS (2.0)
Chris@4 61 #define SUGGESTED_LATENCY_INCREMENT_SECONDS (0.0005) /* half a millisecond increments */
Chris@4 62
Chris@4 63
Chris@4 64 /* dummy callback. does nothing. never gets called */
Chris@4 65 static int patestCallback( const void *inputBuffer, void *outputBuffer,
Chris@4 66 unsigned long framesPerBuffer,
Chris@4 67 const PaStreamCallbackTimeInfo* timeInfo,
Chris@4 68 PaStreamCallbackFlags statusFlags,
Chris@4 69 void *userData )
Chris@4 70 {
Chris@4 71 return paContinue;
Chris@4 72 }
Chris@4 73
Chris@4 74 /*******************************************************************/
Chris@4 75 static void usage()
Chris@4 76 {
Chris@4 77 int i;
Chris@4 78 const PaDeviceInfo *deviceInfo;
Chris@4 79 const char *channelString;
Chris@4 80
Chris@4 81 fprintf( stderr, "PortAudio suggested (requested) vs. resulting (reported) stream latency test\n" );
Chris@4 82 fprintf( stderr, "Usage: x.exe input-device-index output-device-index sample-rate frames-per-buffer\n" );
Chris@4 83 fprintf( stderr, "Use -1 for default device index, or use one of these:\n" );
Chris@4 84 for( i=0; i < Pa_GetDeviceCount(); ++i ){
Chris@4 85 deviceInfo = Pa_GetDeviceInfo(i);
Chris@4 86 if( deviceInfo->maxInputChannels > 0 && deviceInfo->maxOutputChannels > 0 )
Chris@4 87 channelString = "full-duplex";
Chris@4 88 else if( deviceInfo->maxInputChannels > 0 )
Chris@4 89 channelString = "input only";
Chris@4 90 else
Chris@4 91 channelString = "output only";
Chris@4 92
Chris@4 93 fprintf( stderr, "%d (%s, %s, %s)\n", i, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name, channelString );
Chris@4 94 }
Chris@4 95 Pa_Terminate();
Chris@4 96 exit(-1);
Chris@4 97 }
Chris@4 98
Chris@4 99 int main( int argc, const char* argv[] );
Chris@4 100 int main( int argc, const char* argv[] )
Chris@4 101 {
Chris@4 102 PaStreamParameters inputParameters, outputParameters;
Chris@4 103 PaStream *stream;
Chris@4 104 PaError err;
Chris@4 105 PaTime suggestedLatency;
Chris@4 106 const PaStreamInfo *streamInfo;
Chris@4 107 const PaDeviceInfo *deviceInfo;
Chris@4 108 float sampleRate = SAMPLE_RATE;
Chris@4 109 int framesPerBuffer = FRAMES_PER_BUFFER;
Chris@4 110 err = Pa_Initialize();
Chris@4 111 if( err != paNoError ) goto error;
Chris@4 112
Chris@4 113 if( argc > 1 && strcmp(argv[1],"-h") == 0 )
Chris@4 114 usage();
Chris@4 115
Chris@4 116 if( argc > 3 ){
Chris@4 117 sampleRate = atoi(argv[3]);
Chris@4 118 }
Chris@4 119
Chris@4 120 if( argc > 4 ){
Chris@4 121 framesPerBuffer = atoi(argv[4]);
Chris@4 122 }
Chris@4 123
Chris@4 124 printf("# sample rate=%f, frames per buffer=%d\n", (float)sampleRate, framesPerBuffer );
Chris@4 125
Chris@4 126 inputParameters.device = -1;
Chris@4 127 if( argc > 1 )
Chris@4 128 inputParameters.device = atoi(argv[1]);
Chris@4 129 if( inputParameters.device == -1 ){
Chris@4 130 inputParameters.device = Pa_GetDefaultInputDevice();
Chris@4 131 if (inputParameters.device == paNoDevice) {
Chris@4 132 fprintf(stderr,"Error: No default input device available.\n");
Chris@4 133 goto error;
Chris@4 134 }
Chris@4 135 }else{
Chris@4 136 deviceInfo = Pa_GetDeviceInfo(inputParameters.device);
Chris@4 137 if( !deviceInfo ){
Chris@4 138 fprintf(stderr,"Error: Invalid input device index.\n");
Chris@4 139 usage();
Chris@4 140 }
Chris@4 141 if( deviceInfo->maxInputChannels == 0 ){
Chris@4 142 fprintf(stderr,"Error: Specified input device has no input channels (an output only device?).\n");
Chris@4 143 usage();
Chris@4 144 }
Chris@4 145 }
Chris@4 146
Chris@4 147 inputParameters.channelCount = NUM_CHANNELS;
Chris@4 148 inputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
Chris@4 149 inputParameters.hostApiSpecificStreamInfo = NULL;
Chris@4 150
Chris@4 151 deviceInfo = Pa_GetDeviceInfo(inputParameters.device);
Chris@4 152 printf( "# using input device id %d (%s, %s)\n", inputParameters.device, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name );
Chris@4 153
Chris@4 154
Chris@4 155 outputParameters.device = -1;
Chris@4 156 if( argc > 2 )
Chris@4 157 outputParameters.device = atoi(argv[2]);
Chris@4 158 if( outputParameters.device == -1 ){
Chris@4 159 outputParameters.device = Pa_GetDefaultOutputDevice();
Chris@4 160 if (outputParameters.device == paNoDevice) {
Chris@4 161 fprintf(stderr,"Error: No default output device available.\n");
Chris@4 162 goto error;
Chris@4 163 }
Chris@4 164 }else{
Chris@4 165 deviceInfo = Pa_GetDeviceInfo(outputParameters.device);
Chris@4 166 if( !deviceInfo ){
Chris@4 167 fprintf(stderr,"Error: Invalid output device index.\n");
Chris@4 168 usage();
Chris@4 169 }
Chris@4 170 if( deviceInfo->maxOutputChannels == 0 ){
Chris@4 171 fprintf(stderr,"Error: Specified output device has no output channels (an input only device?).\n");
Chris@4 172 usage();
Chris@4 173 }
Chris@4 174 }
Chris@4 175
Chris@4 176 outputParameters.channelCount = NUM_CHANNELS;
Chris@4 177 outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
Chris@4 178 outputParameters.hostApiSpecificStreamInfo = NULL;
Chris@4 179
Chris@4 180 deviceInfo = Pa_GetDeviceInfo(outputParameters.device);
Chris@4 181 printf( "# using output device id %d (%s, %s)\n", outputParameters.device, deviceInfo->name, Pa_GetHostApiInfo(deviceInfo->hostApi)->name );
Chris@4 182
Chris@4 183
Chris@4 184 printf( "# suggested latency, half duplex PaStreamInfo::outputLatency, half duplex PaStreamInfo::inputLatency, full duplex PaStreamInfo::outputLatency, full duplex PaStreamInfo::inputLatency\n" );
Chris@4 185 suggestedLatency = SUGGESTED_LATENCY_START_SECONDS;
Chris@4 186 while( suggestedLatency <= SUGGESTED_LATENCY_END_SECONDS ){
Chris@4 187
Chris@4 188 outputParameters.suggestedLatency = suggestedLatency;
Chris@4 189 inputParameters.suggestedLatency = suggestedLatency;
Chris@4 190
Chris@4 191 printf( "%f, ", suggestedLatency );
Chris@4 192
Chris@4 193 /* ------------------------------ output ------------------------------ */
Chris@4 194
Chris@4 195 err = Pa_OpenStream(
Chris@4 196 &stream,
Chris@4 197 NULL, /* no input */
Chris@4 198 &outputParameters,
Chris@4 199 sampleRate,
Chris@4 200 framesPerBuffer,
Chris@4 201 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@4 202 patestCallback,
Chris@4 203 0 );
Chris@4 204 if( err != paNoError ) goto error;
Chris@4 205
Chris@4 206 streamInfo = Pa_GetStreamInfo( stream );
Chris@4 207
Chris@4 208 printf( "%f,", streamInfo->outputLatency );
Chris@4 209
Chris@4 210 err = Pa_CloseStream( stream );
Chris@4 211 if( err != paNoError ) goto error;
Chris@4 212
Chris@4 213 /* ------------------------------ input ------------------------------ */
Chris@4 214
Chris@4 215 err = Pa_OpenStream(
Chris@4 216 &stream,
Chris@4 217 &inputParameters,
Chris@4 218 NULL, /* no output */
Chris@4 219 sampleRate,
Chris@4 220 framesPerBuffer,
Chris@4 221 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@4 222 patestCallback,
Chris@4 223 0 );
Chris@4 224 if( err != paNoError ) goto error;
Chris@4 225
Chris@4 226 streamInfo = Pa_GetStreamInfo( stream );
Chris@4 227
Chris@4 228 printf( "%f,", streamInfo->inputLatency );
Chris@4 229
Chris@4 230 err = Pa_CloseStream( stream );
Chris@4 231 if( err != paNoError ) goto error;
Chris@4 232
Chris@4 233 /* ------------------------------ full duplex ------------------------------ */
Chris@4 234
Chris@4 235 err = Pa_OpenStream(
Chris@4 236 &stream,
Chris@4 237 &inputParameters,
Chris@4 238 &outputParameters,
Chris@4 239 sampleRate,
Chris@4 240 framesPerBuffer,
Chris@4 241 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@4 242 patestCallback,
Chris@4 243 0 );
Chris@4 244 if( err != paNoError ) goto error;
Chris@4 245
Chris@4 246 streamInfo = Pa_GetStreamInfo( stream );
Chris@4 247
Chris@4 248 printf( "%f,%f", streamInfo->outputLatency, streamInfo->inputLatency );
Chris@4 249
Chris@4 250 err = Pa_CloseStream( stream );
Chris@4 251 if( err != paNoError ) goto error;
Chris@4 252
Chris@4 253 /* ------------------------------------------------------------ */
Chris@4 254
Chris@4 255 printf( "\n" );
Chris@4 256 suggestedLatency += SUGGESTED_LATENCY_INCREMENT_SECONDS;
Chris@4 257 }
Chris@4 258
Chris@4 259 Pa_Terminate();
Chris@4 260 printf("# Test finished.\n");
Chris@4 261
Chris@4 262 return err;
Chris@4 263 error:
Chris@4 264 Pa_Terminate();
Chris@4 265 fprintf( stderr, "An error occured while using the portaudio stream\n" );
Chris@4 266 fprintf( stderr, "Error number: %d\n", err );
Chris@4 267 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
Chris@4 268 return err;
Chris@4 269 }