annotate src/portaudio_20161030_catalina_patch/examples/paex_wmme_surround.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@55 1 /** @file paex_wmme_surround.c
Chris@55 2 @ingroup examples_src
Chris@55 3 @brief Use WMME-specific channelMask to request 5.1 surround sound output.
Chris@55 4 @author Ross Bencina <rossb@audiomulch.com>
Chris@55 5 */
Chris@55 6 /*
Chris@55 7 * $Id: $
Chris@55 8 * Portable Audio I/O Library
Chris@55 9 * Windows MME surround sound output test
Chris@55 10 *
Chris@55 11 * Copyright (c) 2007 Ross Bencina
Chris@55 12 *
Chris@55 13 * Permission is hereby granted, free of charge, to any person obtaining
Chris@55 14 * a copy of this software and associated documentation files
Chris@55 15 * (the "Software"), to deal in the Software without restriction,
Chris@55 16 * including without limitation the rights to use, copy, modify, merge,
Chris@55 17 * publish, distribute, sublicense, and/or sell copies of the Software,
Chris@55 18 * and to permit persons to whom the Software is furnished to do so,
Chris@55 19 * subject to the following conditions:
Chris@55 20 *
Chris@55 21 * The above copyright notice and this permission notice shall be
Chris@55 22 * included in all copies or substantial portions of the Software.
Chris@55 23 *
Chris@55 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Chris@55 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Chris@55 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
Chris@55 27 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
Chris@55 28 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
Chris@55 29 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
Chris@55 30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Chris@55 31 */
Chris@55 32
Chris@55 33 /*
Chris@55 34 * The text above constitutes the entire PortAudio license; however,
Chris@55 35 * the PortAudio community also makes the following non-binding requests:
Chris@55 36 *
Chris@55 37 * Any person wishing to distribute modifications to the Software is
Chris@55 38 * requested to send the modifications to the original developer so that
Chris@55 39 * they can be incorporated into the canonical version. It is also
Chris@55 40 * requested that these non-binding requests be included along with the
Chris@55 41 * license above.
Chris@55 42 */
Chris@55 43
Chris@55 44 #include <stdio.h>
Chris@55 45 #include <math.h>
Chris@55 46
Chris@55 47 #include <windows.h> /* required when using pa_win_wmme.h */
Chris@55 48 #include <mmsystem.h> /* required when using pa_win_wmme.h */
Chris@55 49
Chris@55 50 #include "portaudio.h"
Chris@55 51 #include "pa_win_wmme.h"
Chris@55 52
Chris@55 53 #define NUM_SECONDS (12)
Chris@55 54 #define SAMPLE_RATE (44100)
Chris@55 55 #define FRAMES_PER_BUFFER (64)
Chris@55 56
Chris@55 57 #ifndef M_PI
Chris@55 58 #define M_PI (3.14159265)
Chris@55 59 #endif
Chris@55 60
Chris@55 61 #define TABLE_SIZE (100)
Chris@55 62
Chris@55 63 #define CHANNEL_COUNT (6)
Chris@55 64
Chris@55 65
Chris@55 66
Chris@55 67 typedef struct
Chris@55 68 {
Chris@55 69 float sine[TABLE_SIZE];
Chris@55 70 int phase;
Chris@55 71 int currentChannel;
Chris@55 72 int cycleCount;
Chris@55 73 }
Chris@55 74 paTestData;
Chris@55 75
Chris@55 76 /* This routine will be called by the PortAudio engine when audio is needed.
Chris@55 77 ** It may called at interrupt level on some machines so don't do anything
Chris@55 78 ** that could mess up the system like calling malloc() or free().
Chris@55 79 */
Chris@55 80 static int patestCallback( const void *inputBuffer, void *outputBuffer,
Chris@55 81 unsigned long framesPerBuffer,
Chris@55 82 const PaStreamCallbackTimeInfo* timeInfo,
Chris@55 83 PaStreamCallbackFlags statusFlags,
Chris@55 84 void *userData )
Chris@55 85 {
Chris@55 86 paTestData *data = (paTestData*)userData;
Chris@55 87 float *out = (float*)outputBuffer;
Chris@55 88 unsigned long i,j;
Chris@55 89
Chris@55 90 (void) timeInfo; /* Prevent unused variable warnings. */
Chris@55 91 (void) statusFlags;
Chris@55 92 (void) inputBuffer;
Chris@55 93
Chris@55 94 for( i=0; i<framesPerBuffer; i++ )
Chris@55 95 {
Chris@55 96 for( j = 0; j < CHANNEL_COUNT; ++j ){
Chris@55 97 if( j == data->currentChannel && data->cycleCount < 4410 ){
Chris@55 98 *out++ = data->sine[data->phase];
Chris@55 99 data->phase += 1 + j; // play each channel at a different pitch so they can be distinguished
Chris@55 100 if( data->phase >= TABLE_SIZE ){
Chris@55 101 data->phase -= TABLE_SIZE;
Chris@55 102 }
Chris@55 103 }else{
Chris@55 104 *out++ = 0;
Chris@55 105 }
Chris@55 106 }
Chris@55 107
Chris@55 108 data->cycleCount++;
Chris@55 109 if( data->cycleCount > 44100 ){
Chris@55 110 data->cycleCount = 0;
Chris@55 111
Chris@55 112 ++data->currentChannel;
Chris@55 113 if( data->currentChannel >= CHANNEL_COUNT )
Chris@55 114 data->currentChannel -= CHANNEL_COUNT;
Chris@55 115 }
Chris@55 116 }
Chris@55 117
Chris@55 118 return paContinue;
Chris@55 119 }
Chris@55 120
Chris@55 121 /*******************************************************************/
Chris@55 122 int main(int argc, char* argv[])
Chris@55 123 {
Chris@55 124 PaStreamParameters outputParameters;
Chris@55 125 PaWinMmeStreamInfo wmmeStreamInfo;
Chris@55 126 PaStream *stream;
Chris@55 127 PaError err;
Chris@55 128 paTestData data;
Chris@55 129 int i;
Chris@55 130 int deviceIndex;
Chris@55 131
Chris@55 132 printf("PortAudio Test: output a sine blip on each channel. SR = %d, BufSize = %d, Chans = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER, CHANNEL_COUNT);
Chris@55 133
Chris@55 134 err = Pa_Initialize();
Chris@55 135 if( err != paNoError ) goto error;
Chris@55 136
Chris@55 137 deviceIndex = Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paMME ) )->defaultOutputDevice;
Chris@55 138 if( argc == 2 ){
Chris@55 139 sscanf( argv[1], "%d", &deviceIndex );
Chris@55 140 }
Chris@55 141
Chris@55 142 printf( "using device id %d (%s)\n", deviceIndex, Pa_GetDeviceInfo(deviceIndex)->name );
Chris@55 143
Chris@55 144 /* initialise sinusoidal wavetable */
Chris@55 145 for( i=0; i<TABLE_SIZE; i++ )
Chris@55 146 {
Chris@55 147 data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
Chris@55 148 }
Chris@55 149
Chris@55 150 data.phase = 0;
Chris@55 151 data.currentChannel = 0;
Chris@55 152 data.cycleCount = 0;
Chris@55 153
Chris@55 154 outputParameters.device = deviceIndex;
Chris@55 155 outputParameters.channelCount = CHANNEL_COUNT;
Chris@55 156 outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
Chris@55 157 outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
Chris@55 158 outputParameters.hostApiSpecificStreamInfo = NULL;
Chris@55 159
Chris@55 160 /* it's not strictly necessary to provide a channelMask for surround sound
Chris@55 161 output. But if you want to be sure which channel mask PortAudio will use
Chris@55 162 then you should supply one */
Chris@55 163 wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo);
Chris@55 164 wmmeStreamInfo.hostApiType = paMME;
Chris@55 165 wmmeStreamInfo.version = 1;
Chris@55 166 wmmeStreamInfo.flags = paWinMmeUseChannelMask;
Chris@55 167 wmmeStreamInfo.channelMask = PAWIN_SPEAKER_5POINT1; /* request 5.1 output format */
Chris@55 168 outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo;
Chris@55 169
Chris@55 170
Chris@55 171 if( Pa_IsFormatSupported( 0, &outputParameters, SAMPLE_RATE ) == paFormatIsSupported ){
Chris@55 172 printf( "Pa_IsFormatSupported reports device will support %d channels.\n", CHANNEL_COUNT );
Chris@55 173 }else{
Chris@55 174 printf( "Pa_IsFormatSupported reports device will not support %d channels.\n", CHANNEL_COUNT );
Chris@55 175 }
Chris@55 176
Chris@55 177 err = Pa_OpenStream(
Chris@55 178 &stream,
Chris@55 179 NULL, /* no input */
Chris@55 180 &outputParameters,
Chris@55 181 SAMPLE_RATE,
Chris@55 182 FRAMES_PER_BUFFER,
Chris@55 183 paClipOff, /* we won't output out of range samples so don't bother clipping them */
Chris@55 184 patestCallback,
Chris@55 185 &data );
Chris@55 186 if( err != paNoError ) goto error;
Chris@55 187
Chris@55 188 err = Pa_StartStream( stream );
Chris@55 189 if( err != paNoError ) goto error;
Chris@55 190
Chris@55 191 printf("Play for %d seconds.\n", NUM_SECONDS );
Chris@55 192 Pa_Sleep( NUM_SECONDS * 1000 );
Chris@55 193
Chris@55 194 err = Pa_StopStream( stream );
Chris@55 195 if( err != paNoError ) goto error;
Chris@55 196
Chris@55 197 err = Pa_CloseStream( stream );
Chris@55 198 if( err != paNoError ) goto error;
Chris@55 199
Chris@55 200 Pa_Terminate();
Chris@55 201 printf("Test finished.\n");
Chris@55 202
Chris@55 203 return err;
Chris@55 204 error:
Chris@55 205 Pa_Terminate();
Chris@55 206 fprintf( stderr, "An error occured while using the portaudio stream\n" );
Chris@55 207 fprintf( stderr, "Error number: %d\n", err );
Chris@55 208 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
Chris@55 209 return err;
Chris@55 210 }
Chris@55 211