annotate src/portaudio_20161030_catalina_patch/examples/paex_sine_c++.cpp @ 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@55 1 /** @file paex_sine.c
Chris@55 2 @ingroup examples_src
Chris@55 3 @brief Play a sine wave for several seconds.
Chris@55 4 @author Ross Bencina <rossb@audiomulch.com>
Chris@55 5 @author Phil Burk <philburk@softsynth.com>
Chris@55 6 */
Chris@55 7 /*
Chris@55 8 * $Id: paex_sine.c 1752 2011-09-08 03:21:55Z philburk $
Chris@55 9 *
Chris@55 10 * This program uses the PortAudio Portable Audio Library.
Chris@55 11 * For more information see: http://www.portaudio.com/
Chris@55 12 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
Chris@55 13 *
Chris@55 14 * Permission is hereby granted, free of charge, to any person obtaining
Chris@55 15 * a copy of this software and associated documentation files
Chris@55 16 * (the "Software"), to deal in the Software without restriction,
Chris@55 17 * including without limitation the rights to use, copy, modify, merge,
Chris@55 18 * publish, distribute, sublicense, and/or sell copies of the Software,
Chris@55 19 * and to permit persons to whom the Software is furnished to do so,
Chris@55 20 * subject to the following conditions:
Chris@55 21 *
Chris@55 22 * The above copyright notice and this permission notice shall be
Chris@55 23 * included in all copies or substantial portions of the Software.
Chris@55 24 *
Chris@55 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@55 26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@55 27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@55 28 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@55 29 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@55 30 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@55 31 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@55 32 */
Chris@55 33
Chris@55 34 /*
Chris@55 35 * The text above constitutes the entire PortAudio license; however,
Chris@55 36 * the PortAudio community also makes the following non-binding requests:
Chris@55 37 *
Chris@55 38 * Any person wishing to distribute modifications to the Software is
Chris@55 39 * requested to send the modifications to the original developer so that
Chris@55 40 * they can be incorporated into the canonical version. It is also
Chris@55 41 * requested that these non-binding requests be included along with the
Chris@55 42 * license above.
Chris@55 43 */
Chris@55 44 #include <stdio.h>
Chris@55 45 #include <math.h>
Chris@55 46 #include "portaudio.h"
Chris@55 47
Chris@55 48 #define NUM_SECONDS (5)
Chris@55 49 #define SAMPLE_RATE (44100)
Chris@55 50 #define FRAMES_PER_BUFFER (64)
Chris@55 51
Chris@55 52 #ifndef M_PI
Chris@55 53 #define M_PI (3.14159265)
Chris@55 54 #endif
Chris@55 55
Chris@55 56 #define TABLE_SIZE (200)
Chris@55 57
Chris@55 58 class Sine
Chris@55 59 {
Chris@55 60 public:
Chris@55 61 Sine() : stream(0), left_phase(0), right_phase(0)
Chris@55 62 {
Chris@55 63 /* initialise sinusoidal wavetable */
Chris@55 64 for( int i=0; i<TABLE_SIZE; i++ )
Chris@55 65 {
Chris@55 66 sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
Chris@55 67 }
Chris@55 68
Chris@55 69 sprintf( message, "No Message" );
Chris@55 70 }
Chris@55 71
Chris@55 72 bool open(PaDeviceIndex index)
Chris@55 73 {
Chris@55 74 PaStreamParameters outputParameters;
Chris@55 75
Chris@55 76 outputParameters.device = index;
Chris@55 77 if (outputParameters.device == paNoDevice) {
Chris@55 78 return false;
Chris@55 79 }
Chris@55 80
Chris@55 81 const PaDeviceInfo* pInfo = Pa_GetDeviceInfo(index);
Chris@55 82 if (pInfo != 0)
Chris@55 83 {
Chris@55 84 printf("Output device name: '%s'\r", pInfo->name);
Chris@55 85 }
Chris@55 86
Chris@55 87 outputParameters.channelCount = 2; /* stereo output */
Chris@55 88 outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
Chris@55 89 outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
Chris@55 90 outputParameters.hostApiSpecificStreamInfo = NULL;
Chris@55 91
Chris@55 92 PaError err = Pa_OpenStream(
Chris@55 93 &stream,
Chris@55 94 NULL, /* no input */
Chris@55 95 &outputParameters,
Chris@55 96 SAMPLE_RATE,
Chris@55 97 paFramesPerBufferUnspecified,
Chris@55 98 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@55 99 &Sine::paCallback,
Chris@55 100 this /* Using 'this' for userData so we can cast to Sine* in paCallback method */
Chris@55 101 );
Chris@55 102
Chris@55 103 if (err != paNoError)
Chris@55 104 {
Chris@55 105 /* Failed to open stream to device !!! */
Chris@55 106 return false;
Chris@55 107 }
Chris@55 108
Chris@55 109 err = Pa_SetStreamFinishedCallback( stream, &Sine::paStreamFinished );
Chris@55 110
Chris@55 111 if (err != paNoError)
Chris@55 112 {
Chris@55 113 Pa_CloseStream( stream );
Chris@55 114 stream = 0;
Chris@55 115
Chris@55 116 return false;
Chris@55 117 }
Chris@55 118
Chris@55 119 return true;
Chris@55 120 }
Chris@55 121
Chris@55 122 bool close()
Chris@55 123 {
Chris@55 124 if (stream == 0)
Chris@55 125 return false;
Chris@55 126
Chris@55 127 PaError err = Pa_CloseStream( stream );
Chris@55 128 stream = 0;
Chris@55 129
Chris@55 130 return (err == paNoError);
Chris@55 131 }
Chris@55 132
Chris@55 133
Chris@55 134 bool start()
Chris@55 135 {
Chris@55 136 if (stream == 0)
Chris@55 137 return false;
Chris@55 138
Chris@55 139 PaError err = Pa_StartStream( stream );
Chris@55 140
Chris@55 141 return (err == paNoError);
Chris@55 142 }
Chris@55 143
Chris@55 144 bool stop()
Chris@55 145 {
Chris@55 146 if (stream == 0)
Chris@55 147 return false;
Chris@55 148
Chris@55 149 PaError err = Pa_StopStream( stream );
Chris@55 150
Chris@55 151 return (err == paNoError);
Chris@55 152 }
Chris@55 153
Chris@55 154 private:
Chris@55 155 /* The instance callback, where we have access to every method/variable in object of class Sine */
Chris@55 156 int paCallbackMethod(const void *inputBuffer, void *outputBuffer,
Chris@55 157 unsigned long framesPerBuffer,
Chris@55 158 const PaStreamCallbackTimeInfo* timeInfo,
Chris@55 159 PaStreamCallbackFlags statusFlags)
Chris@55 160 {
Chris@55 161 float *out = (float*)outputBuffer;
Chris@55 162 unsigned long i;
Chris@55 163
Chris@55 164 (void) timeInfo; /* Prevent unused variable warnings. */
Chris@55 165 (void) statusFlags;
Chris@55 166 (void) inputBuffer;
Chris@55 167
Chris@55 168 for( i=0; i<framesPerBuffer; i++ )
Chris@55 169 {
Chris@55 170 *out++ = sine[left_phase]; /* left */
Chris@55 171 *out++ = sine[right_phase]; /* right */
Chris@55 172 left_phase += 1;
Chris@55 173 if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
Chris@55 174 right_phase += 3; /* higher pitch so we can distinguish left and right. */
Chris@55 175 if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
Chris@55 176 }
Chris@55 177
Chris@55 178 return paContinue;
Chris@55 179
Chris@55 180 }
Chris@55 181
Chris@55 182 /* This routine will be called by the PortAudio engine when audio is needed.
Chris@55 183 ** It may called at interrupt level on some machines so don't do anything
Chris@55 184 ** that could mess up the system like calling malloc() or free().
Chris@55 185 */
Chris@55 186 static int paCallback( const void *inputBuffer, void *outputBuffer,
Chris@55 187 unsigned long framesPerBuffer,
Chris@55 188 const PaStreamCallbackTimeInfo* timeInfo,
Chris@55 189 PaStreamCallbackFlags statusFlags,
Chris@55 190 void *userData )
Chris@55 191 {
Chris@55 192 /* Here we cast userData to Sine* type so we can call the instance method paCallbackMethod, we can do that since
Chris@55 193 we called Pa_OpenStream with 'this' for userData */
Chris@55 194 return ((Sine*)userData)->paCallbackMethod(inputBuffer, outputBuffer,
Chris@55 195 framesPerBuffer,
Chris@55 196 timeInfo,
Chris@55 197 statusFlags);
Chris@55 198 }
Chris@55 199
Chris@55 200
Chris@55 201 void paStreamFinishedMethod()
Chris@55 202 {
Chris@55 203 printf( "Stream Completed: %s\n", message );
Chris@55 204 }
Chris@55 205
Chris@55 206 /*
Chris@55 207 * This routine is called by portaudio when playback is done.
Chris@55 208 */
Chris@55 209 static void paStreamFinished(void* userData)
Chris@55 210 {
Chris@55 211 return ((Sine*)userData)->paStreamFinishedMethod();
Chris@55 212 }
Chris@55 213
Chris@55 214 PaStream *stream;
Chris@55 215 float sine[TABLE_SIZE];
Chris@55 216 int left_phase;
Chris@55 217 int right_phase;
Chris@55 218 char message[20];
Chris@55 219 };
Chris@55 220
Chris@55 221 class ScopedPaHandler
Chris@55 222 {
Chris@55 223 public:
Chris@55 224 ScopedPaHandler()
Chris@55 225 : _result(Pa_Initialize())
Chris@55 226 {
Chris@55 227 }
Chris@55 228 ~ScopedPaHandler()
Chris@55 229 {
Chris@55 230 if (_result == paNoError)
Chris@55 231 {
Chris@55 232 Pa_Terminate();
Chris@55 233 }
Chris@55 234 }
Chris@55 235
Chris@55 236 PaError result() const { return _result; }
Chris@55 237
Chris@55 238 private:
Chris@55 239 PaError _result;
Chris@55 240 };
Chris@55 241
Chris@55 242
Chris@55 243 /*******************************************************************/
Chris@55 244 int main(void);
Chris@55 245 int main(void)
Chris@55 246 {
Chris@55 247 Sine sine;
Chris@55 248
Chris@55 249 printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
Chris@55 250
Chris@55 251 ScopedPaHandler paInit;
Chris@55 252 if( paInit.result() != paNoError ) goto error;
Chris@55 253
Chris@55 254 if (sine.open(Pa_GetDefaultOutputDevice()))
Chris@55 255 {
Chris@55 256 if (sine.start())
Chris@55 257 {
Chris@55 258 printf("Play for %d seconds.\n", NUM_SECONDS );
Chris@55 259 Pa_Sleep( NUM_SECONDS * 1000 );
Chris@55 260
Chris@55 261 sine.stop();
Chris@55 262 }
Chris@55 263
Chris@55 264 sine.close();
Chris@55 265 }
Chris@55 266
Chris@55 267 printf("Test finished.\n");
Chris@55 268 return paNoError;
Chris@55 269
Chris@55 270 error:
Chris@55 271 fprintf( stderr, "An error occured while using the portaudio stream\n" );
Chris@55 272 fprintf( stderr, "Error number: %d\n", paInit.result() );
Chris@55 273 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( paInit.result() ) );
Chris@55 274 return 1;
Chris@55 275 }