annotate src/portaudio_20161030_catalina_patch/test/patest_wire.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 4edcd14160a5
children
rev   line source
Chris@4 1 /** @file patest_wire.c
Chris@4 2 @ingroup test_src
Chris@4 3 @brief Pass input directly to output.
Chris@4 4
Chris@4 5 Note that some HW devices, for example many ISA audio cards
Chris@4 6 on PCs, do NOT support full duplex! For a PC, you normally need
Chris@4 7 a PCI based audio card such as the SBLive.
Chris@4 8
Chris@4 9 @author Phil Burk http://www.softsynth.com
Chris@4 10
Chris@4 11 While adapting to V19-API, I excluded configs with framesPerCallback=0
Chris@4 12 because of an assert in file pa_common/pa_process.c. Pieter, Oct 9, 2003.
Chris@4 13
Chris@4 14 */
Chris@4 15 /*
Chris@55 16 * $Id$
Chris@4 17 *
Chris@4 18 * This program uses the PortAudio Portable Audio Library.
Chris@4 19 * For more information see: http://www.portaudio.com
Chris@4 20 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
Chris@4 21 *
Chris@4 22 * Permission is hereby granted, free of charge, to any person obtaining
Chris@4 23 * a copy of this software and associated documentation files
Chris@4 24 * (the "Software"), to deal in the Software without restriction,
Chris@4 25 * including without limitation the rights to use, copy, modify, merge,
Chris@4 26 * publish, distribute, sublicense, and/or sell copies of the Software,
Chris@4 27 * and to permit persons to whom the Software is furnished to do so,
Chris@4 28 * subject to the following conditions:
Chris@4 29 *
Chris@4 30 * The above copyright notice and this permission notice shall be
Chris@4 31 * included in all copies or substantial portions of the Software.
Chris@4 32 *
Chris@4 33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@4 34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@4 35 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@4 36 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@4 37 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@4 38 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@4 39 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@4 40 */
Chris@4 41
Chris@4 42 /*
Chris@4 43 * The text above constitutes the entire PortAudio license; however,
Chris@4 44 * the PortAudio community also makes the following non-binding requests:
Chris@4 45 *
Chris@4 46 * Any person wishing to distribute modifications to the Software is
Chris@4 47 * requested to send the modifications to the original developer so that
Chris@4 48 * they can be incorporated into the canonical version. It is also
Chris@4 49 * requested that these non-binding requests be included along with the
Chris@4 50 * license above.
Chris@4 51 */
Chris@4 52
Chris@4 53 #include <stdio.h>
Chris@4 54 #include <math.h>
Chris@4 55 #include "portaudio.h"
Chris@4 56
Chris@4 57 #define SAMPLE_RATE (44100)
Chris@4 58
Chris@4 59 typedef struct WireConfig_s
Chris@4 60 {
Chris@4 61 int isInputInterleaved;
Chris@4 62 int isOutputInterleaved;
Chris@4 63 int numInputChannels;
Chris@4 64 int numOutputChannels;
Chris@4 65 int framesPerCallback;
Chris@55 66 /* count status flags */
Chris@55 67 int numInputUnderflows;
Chris@55 68 int numInputOverflows;
Chris@55 69 int numOutputUnderflows;
Chris@55 70 int numOutputOverflows;
Chris@55 71 int numPrimingOutputs;
Chris@55 72 int numCallbacks;
Chris@4 73 } WireConfig_t;
Chris@4 74
Chris@4 75 #define USE_FLOAT_INPUT (1)
Chris@4 76 #define USE_FLOAT_OUTPUT (1)
Chris@4 77
Chris@4 78 /* Latencies set to defaults. */
Chris@4 79
Chris@4 80 #if USE_FLOAT_INPUT
Chris@4 81 #define INPUT_FORMAT paFloat32
Chris@4 82 typedef float INPUT_SAMPLE;
Chris@4 83 #else
Chris@4 84 #define INPUT_FORMAT paInt16
Chris@4 85 typedef short INPUT_SAMPLE;
Chris@4 86 #endif
Chris@4 87
Chris@4 88 #if USE_FLOAT_OUTPUT
Chris@4 89 #define OUTPUT_FORMAT paFloat32
Chris@4 90 typedef float OUTPUT_SAMPLE;
Chris@4 91 #else
Chris@4 92 #define OUTPUT_FORMAT paInt16
Chris@4 93 typedef short OUTPUT_SAMPLE;
Chris@4 94 #endif
Chris@4 95
Chris@4 96 double gInOutScaler = 1.0;
Chris@4 97 #define CONVERT_IN_TO_OUT(in) ((OUTPUT_SAMPLE) ((in) * gInOutScaler))
Chris@4 98
Chris@4 99 #define INPUT_DEVICE (Pa_GetDefaultInputDevice())
Chris@4 100 #define OUTPUT_DEVICE (Pa_GetDefaultOutputDevice())
Chris@4 101
Chris@4 102 static PaError TestConfiguration( WireConfig_t *config );
Chris@4 103
Chris@4 104 static int wireCallback( const void *inputBuffer, void *outputBuffer,
Chris@4 105 unsigned long framesPerBuffer,
Chris@4 106 const PaStreamCallbackTimeInfo* timeInfo,
Chris@4 107 PaStreamCallbackFlags statusFlags,
Chris@4 108 void *userData );
Chris@4 109
Chris@4 110 /* This routine will be called by the PortAudio engine when audio is needed.
Chris@4 111 ** It may be called at interrupt level on some machines so don't do anything
Chris@4 112 ** that could mess up the system like calling malloc() or free().
Chris@4 113 */
Chris@4 114
Chris@4 115 static int wireCallback( const void *inputBuffer, void *outputBuffer,
Chris@4 116 unsigned long framesPerBuffer,
Chris@4 117 const PaStreamCallbackTimeInfo* timeInfo,
Chris@4 118 PaStreamCallbackFlags statusFlags,
Chris@4 119 void *userData )
Chris@4 120 {
Chris@4 121 INPUT_SAMPLE *in;
Chris@4 122 OUTPUT_SAMPLE *out;
Chris@4 123 int inStride;
Chris@4 124 int outStride;
Chris@4 125 int inDone = 0;
Chris@4 126 int outDone = 0;
Chris@4 127 WireConfig_t *config = (WireConfig_t *) userData;
Chris@4 128 unsigned int i;
Chris@4 129 int inChannel, outChannel;
Chris@4 130
Chris@4 131 /* This may get called with NULL inputBuffer during initial setup. */
Chris@4 132 if( inputBuffer == NULL) return 0;
Chris@4 133
Chris@55 134 /* Count flags */
Chris@55 135 if( (statusFlags & paInputUnderflow) != 0 ) config->numInputUnderflows += 1;
Chris@55 136 if( (statusFlags & paInputOverflow) != 0 ) config->numInputOverflows += 1;
Chris@55 137 if( (statusFlags & paOutputUnderflow) != 0 ) config->numOutputUnderflows += 1;
Chris@55 138 if( (statusFlags & paOutputOverflow) != 0 ) config->numOutputOverflows += 1;
Chris@55 139 if( (statusFlags & paPrimingOutput) != 0 ) config->numPrimingOutputs += 1;
Chris@55 140 config->numCallbacks += 1;
Chris@55 141
Chris@4 142 inChannel=0, outChannel=0;
Chris@4 143 while( !(inDone && outDone) )
Chris@4 144 {
Chris@4 145 if( config->isInputInterleaved )
Chris@4 146 {
Chris@4 147 in = ((INPUT_SAMPLE*)inputBuffer) + inChannel;
Chris@4 148 inStride = config->numInputChannels;
Chris@4 149 }
Chris@4 150 else
Chris@4 151 {
Chris@4 152 in = ((INPUT_SAMPLE**)inputBuffer)[inChannel];
Chris@4 153 inStride = 1;
Chris@4 154 }
Chris@4 155
Chris@4 156 if( config->isOutputInterleaved )
Chris@4 157 {
Chris@4 158 out = ((OUTPUT_SAMPLE*)outputBuffer) + outChannel;
Chris@4 159 outStride = config->numOutputChannels;
Chris@4 160 }
Chris@4 161 else
Chris@4 162 {
Chris@4 163 out = ((OUTPUT_SAMPLE**)outputBuffer)[outChannel];
Chris@4 164 outStride = 1;
Chris@4 165 }
Chris@4 166
Chris@4 167 for( i=0; i<framesPerBuffer; i++ )
Chris@4 168 {
Chris@4 169 *out = CONVERT_IN_TO_OUT( *in );
Chris@4 170 out += outStride;
Chris@4 171 in += inStride;
Chris@4 172 }
Chris@4 173
Chris@4 174 if(inChannel < (config->numInputChannels - 1)) inChannel++;
Chris@4 175 else inDone = 1;
Chris@4 176 if(outChannel < (config->numOutputChannels - 1)) outChannel++;
Chris@4 177 else outDone = 1;
Chris@4 178 }
Chris@4 179 return 0;
Chris@4 180 }
Chris@4 181
Chris@4 182 /*******************************************************************/
Chris@4 183 int main(void);
Chris@4 184 int main(void)
Chris@4 185 {
Chris@4 186 PaError err = paNoError;
Chris@4 187 WireConfig_t CONFIG;
Chris@4 188 WireConfig_t *config = &CONFIG;
Chris@4 189 int configIndex = 0;;
Chris@4 190
Chris@4 191 err = Pa_Initialize();
Chris@4 192 if( err != paNoError ) goto error;
Chris@4 193
Chris@4 194 printf("Please connect audio signal to input and listen for it on output!\n");
Chris@4 195 printf("input format = %lu\n", INPUT_FORMAT );
Chris@4 196 printf("output format = %lu\n", OUTPUT_FORMAT );
Chris@4 197 printf("input device ID = %d\n", INPUT_DEVICE );
Chris@4 198 printf("output device ID = %d\n", OUTPUT_DEVICE );
Chris@4 199
Chris@4 200 if( INPUT_FORMAT == OUTPUT_FORMAT )
Chris@4 201 {
Chris@4 202 gInOutScaler = 1.0;
Chris@4 203 }
Chris@4 204 else if( (INPUT_FORMAT == paInt16) && (OUTPUT_FORMAT == paFloat32) )
Chris@4 205 {
Chris@4 206 gInOutScaler = 1.0/32768.0;
Chris@4 207 }
Chris@4 208 else if( (INPUT_FORMAT == paFloat32) && (OUTPUT_FORMAT == paInt16) )
Chris@4 209 {
Chris@4 210 gInOutScaler = 32768.0;
Chris@4 211 }
Chris@4 212
Chris@4 213 for( config->isInputInterleaved = 0; config->isInputInterleaved < 2; config->isInputInterleaved++ )
Chris@4 214 {
Chris@4 215 for( config->isOutputInterleaved = 0; config->isOutputInterleaved < 2; config->isOutputInterleaved++ )
Chris@4 216 {
Chris@4 217 for( config->numInputChannels = 1; config->numInputChannels < 3; config->numInputChannels++ )
Chris@4 218 {
Chris@4 219 for( config->numOutputChannels = 1; config->numOutputChannels < 3; config->numOutputChannels++ )
Chris@4 220 {
Chris@4 221 /* If framesPerCallback = 0, assertion fails in file pa_common/pa_process.c, line 1413: EX. */
Chris@4 222 for( config->framesPerCallback = 64; config->framesPerCallback < 129; config->framesPerCallback += 64 )
Chris@4 223 {
Chris@4 224 printf("-----------------------------------------------\n" );
Chris@4 225 printf("Configuration #%d\n", configIndex++ );
Chris@4 226 err = TestConfiguration( config );
Chris@4 227 /* Give user a chance to bail out. */
Chris@4 228 if( err == 1 )
Chris@4 229 {
Chris@4 230 err = paNoError;
Chris@4 231 goto done;
Chris@4 232 }
Chris@4 233 else if( err != paNoError ) goto error;
Chris@4 234 }
Chris@4 235 }
Chris@4 236 }
Chris@4 237 }
Chris@4 238 }
Chris@4 239
Chris@4 240 done:
Chris@4 241 Pa_Terminate();
Chris@4 242 printf("Full duplex sound test complete.\n"); fflush(stdout);
Chris@4 243 printf("Hit ENTER to quit.\n"); fflush(stdout);
Chris@4 244 getchar();
Chris@4 245 return 0;
Chris@4 246
Chris@4 247 error:
Chris@4 248 Pa_Terminate();
Chris@4 249 fprintf( stderr, "An error occured while using the portaudio stream\n" );
Chris@4 250 fprintf( stderr, "Error number: %d\n", err );
Chris@4 251 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
Chris@4 252 printf("Hit ENTER to quit.\n"); fflush(stdout);
Chris@4 253 getchar();
Chris@4 254 return -1;
Chris@4 255 }
Chris@4 256
Chris@4 257 static PaError TestConfiguration( WireConfig_t *config )
Chris@4 258 {
Chris@4 259 int c;
Chris@4 260 PaError err = paNoError;
Chris@4 261 PaStream *stream;
Chris@4 262 PaStreamParameters inputParameters, outputParameters;
Chris@4 263
Chris@4 264 printf("input %sinterleaved!\n", (config->isInputInterleaved ? " " : "NOT ") );
Chris@4 265 printf("output %sinterleaved!\n", (config->isOutputInterleaved ? " " : "NOT ") );
Chris@4 266 printf("input channels = %d\n", config->numInputChannels );
Chris@4 267 printf("output channels = %d\n", config->numOutputChannels );
Chris@4 268 printf("framesPerCallback = %d\n", config->framesPerCallback );
Chris@4 269
Chris@4 270 inputParameters.device = INPUT_DEVICE; /* default input device */
Chris@4 271 if (inputParameters.device == paNoDevice) {
Chris@4 272 fprintf(stderr,"Error: No default input device.\n");
Chris@4 273 goto error;
Chris@4 274 }
Chris@4 275 inputParameters.channelCount = config->numInputChannels;
Chris@4 276 inputParameters.sampleFormat = INPUT_FORMAT | (config->isInputInterleaved ? 0 : paNonInterleaved);
Chris@4 277 inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
Chris@4 278 inputParameters.hostApiSpecificStreamInfo = NULL;
Chris@4 279
Chris@4 280 outputParameters.device = OUTPUT_DEVICE; /* default output device */
Chris@4 281 if (outputParameters.device == paNoDevice) {
Chris@4 282 fprintf(stderr,"Error: No default output device.\n");
Chris@4 283 goto error;
Chris@4 284 }
Chris@4 285 outputParameters.channelCount = config->numOutputChannels;
Chris@4 286 outputParameters.sampleFormat = OUTPUT_FORMAT | (config->isOutputInterleaved ? 0 : paNonInterleaved);
Chris@4 287 outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
Chris@4 288 outputParameters.hostApiSpecificStreamInfo = NULL;
Chris@4 289
Chris@55 290 config->numInputUnderflows = 0;
Chris@55 291 config->numInputOverflows = 0;
Chris@55 292 config->numOutputUnderflows = 0;
Chris@55 293 config->numOutputOverflows = 0;
Chris@55 294 config->numPrimingOutputs = 0;
Chris@55 295 config->numCallbacks = 0;
Chris@55 296
Chris@4 297 err = Pa_OpenStream(
Chris@4 298 &stream,
Chris@4 299 &inputParameters,
Chris@4 300 &outputParameters,
Chris@4 301 SAMPLE_RATE,
Chris@4 302 config->framesPerCallback, /* frames per buffer */
Chris@4 303 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@4 304 wireCallback,
Chris@4 305 config );
Chris@4 306 if( err != paNoError ) goto error;
Chris@4 307
Chris@4 308 err = Pa_StartStream( stream );
Chris@4 309 if( err != paNoError ) goto error;
Chris@4 310
Chris@55 311 printf("Now recording and playing. - Hit ENTER for next configuration, or 'q' to quit.\n"); fflush(stdout);
Chris@4 312 c = getchar();
Chris@4 313
Chris@4 314 printf("Closing stream.\n");
Chris@4 315 err = Pa_CloseStream( stream );
Chris@4 316 if( err != paNoError ) goto error;
Chris@4 317
Chris@55 318 #define CHECK_FLAG_COUNT(member) \
Chris@55 319 if( config->member > 0 ) printf("FLAGS SET: " #member " = %d\n", config->member );
Chris@55 320 CHECK_FLAG_COUNT( numInputUnderflows );
Chris@55 321 CHECK_FLAG_COUNT( numInputOverflows );
Chris@55 322 CHECK_FLAG_COUNT( numOutputUnderflows );
Chris@55 323 CHECK_FLAG_COUNT( numOutputOverflows );
Chris@55 324 CHECK_FLAG_COUNT( numPrimingOutputs );
Chris@55 325 printf("number of callbacks = %d\n", config->numCallbacks );
Chris@55 326
Chris@4 327 if( c == 'q' ) return 1;
Chris@4 328
Chris@4 329 error:
Chris@4 330 return err;
Chris@4 331 }