Mercurial > hg > sv-dependency-builds
comparison src/portaudio/test/patest_sync.c @ 4:e13257ea84a4
Add bzip2, zlib, liblo, portaudio sources
author | Chris Cannam |
---|---|
date | Wed, 20 Mar 2013 13:59:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:6c505a35919a | 4:e13257ea84a4 |
---|---|
1 /** @file patest_sync.c | |
2 @ingroup test_src | |
3 @brief Test time stamping and synchronization of audio and video. | |
4 | |
5 A high latency is used so we can hear the difference in time. | |
6 Random durations are used so we know we are hearing the right beep | |
7 and not the one before or after. | |
8 | |
9 Sequence of events: | |
10 -# Foreground requests a beep. | |
11 -# Background randomly schedules a beep. | |
12 -# Foreground waits for the beep to be heard based on PaUtil_GetTime(). | |
13 -# Foreground outputs video (printf) in sync with audio. | |
14 -# Repeat. | |
15 | |
16 @author Phil Burk http://www.softsynth.com | |
17 */ | |
18 /* | |
19 * $Id: patest_sync.c 1368 2008-03-01 00:38:27Z rossb $ | |
20 * | |
21 * This program uses the PortAudio Portable Audio Library. | |
22 * For more information see: http://www.portaudio.com | |
23 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk | |
24 * | |
25 * Permission is hereby granted, free of charge, to any person obtaining | |
26 * a copy of this software and associated documentation files | |
27 * (the "Software"), to deal in the Software without restriction, | |
28 * including without limitation the rights to use, copy, modify, merge, | |
29 * publish, distribute, sublicense, and/or sell copies of the Software, | |
30 * and to permit persons to whom the Software is furnished to do so, | |
31 * subject to the following conditions: | |
32 * | |
33 * The above copyright notice and this permission notice shall be | |
34 * included in all copies or substantial portions of the Software. | |
35 * | |
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
37 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
38 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
39 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
40 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
41 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
42 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
43 */ | |
44 | |
45 /* | |
46 * The text above constitutes the entire PortAudio license; however, | |
47 * the PortAudio community also makes the following non-binding requests: | |
48 * | |
49 * Any person wishing to distribute modifications to the Software is | |
50 * requested to send the modifications to the original developer so that | |
51 * they can be incorporated into the canonical version. It is also | |
52 * requested that these non-binding requests be included along with the | |
53 * license above. | |
54 */ | |
55 | |
56 #include <stdio.h> | |
57 #include <math.h> | |
58 #include "portaudio.h" | |
59 #include "pa_util.h" | |
60 #define NUM_BEEPS (6) | |
61 #define SAMPLE_RATE (44100) | |
62 #define SAMPLE_PERIOD (1.0/44100.0) | |
63 #define FRAMES_PER_BUFFER (256) | |
64 #define BEEP_DURATION (400) | |
65 #define LATENCY_MSEC (2000) | |
66 #define SLEEP_MSEC (10) | |
67 #define TIMEOUT_MSEC (15000) | |
68 | |
69 #define STATE_BKG_IDLE (0) | |
70 #define STATE_BKG_PENDING (1) | |
71 #define STATE_BKG_BEEPING (2) | |
72 typedef struct | |
73 { | |
74 float left_phase; | |
75 float right_phase; | |
76 int state; | |
77 volatile int requestBeep; /* Set by foreground, cleared by background. */ | |
78 PaTime beepTime; | |
79 int beepCount; | |
80 double latency; /* For debugging. */ | |
81 } | |
82 paTestData; | |
83 | |
84 static unsigned long GenerateRandomNumber( void ); | |
85 /************************************************************/ | |
86 /* Calculate pseudo-random 32 bit number based on linear congruential method. */ | |
87 static unsigned long GenerateRandomNumber( void ) | |
88 { | |
89 static unsigned long randSeed = 99887766; /* Change this for different random sequences. */ | |
90 randSeed = (randSeed * 196314165) + 907633515; | |
91 return randSeed; | |
92 } | |
93 | |
94 /* This routine will be called by the PortAudio engine when audio is needed. | |
95 ** It may called at interrupt level on some machines so don't do anything | |
96 ** that could mess up the system like calling malloc() or free(). | |
97 */ | |
98 static int patestCallback( const void *inputBuffer, void *outputBuffer, | |
99 unsigned long framesPerBuffer, | |
100 const PaStreamCallbackTimeInfo *timeInfo, | |
101 PaStreamCallbackFlags statusFlags, void *userData ) | |
102 { | |
103 /* Cast data passed through stream to our structure. */ | |
104 paTestData *data = (paTestData*)userData; | |
105 float *out = (float*)outputBuffer; | |
106 unsigned int i; | |
107 (void) inputBuffer; | |
108 | |
109 data->latency = timeInfo->outputBufferDacTime - timeInfo->currentTime; | |
110 | |
111 for( i=0; i<framesPerBuffer; i++ ) | |
112 { | |
113 switch( data->state ) | |
114 { | |
115 case STATE_BKG_IDLE: | |
116 /* Schedule beep at some random time in the future. */ | |
117 if( data->requestBeep ) | |
118 { | |
119 int random = GenerateRandomNumber() >> 14; | |
120 data->beepTime = timeInfo->outputBufferDacTime + (( (double)(random + SAMPLE_RATE)) * SAMPLE_PERIOD ); | |
121 data->state = STATE_BKG_PENDING; | |
122 } | |
123 *out++ = 0.0; /* left */ | |
124 *out++ = 0.0; /* right */ | |
125 break; | |
126 | |
127 case STATE_BKG_PENDING: | |
128 if( (timeInfo->outputBufferDacTime + (i*SAMPLE_PERIOD)) >= data->beepTime ) | |
129 { | |
130 data->state = STATE_BKG_BEEPING; | |
131 data->beepCount = BEEP_DURATION; | |
132 data->left_phase = data->right_phase = 0.0; | |
133 } | |
134 *out++ = 0.0; /* left */ | |
135 *out++ = 0.0; /* right */ | |
136 break; | |
137 | |
138 case STATE_BKG_BEEPING: | |
139 if( data->beepCount <= 0 ) | |
140 { | |
141 data->state = STATE_BKG_IDLE; | |
142 data->requestBeep = 0; | |
143 *out++ = 0.0; /* left */ | |
144 *out++ = 0.0; /* right */ | |
145 } | |
146 else | |
147 { | |
148 /* Play sawtooth wave. */ | |
149 *out++ = data->left_phase; /* left */ | |
150 *out++ = data->right_phase; /* right */ | |
151 /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */ | |
152 data->left_phase += 0.01f; | |
153 /* When signal reaches top, drop back down. */ | |
154 if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f; | |
155 /* higher pitch so we can distinguish left and right. */ | |
156 data->right_phase += 0.03f; | |
157 if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f; | |
158 } | |
159 data->beepCount -= 1; | |
160 break; | |
161 | |
162 default: | |
163 data->state = STATE_BKG_IDLE; | |
164 break; | |
165 } | |
166 } | |
167 return 0; | |
168 } | |
169 /*******************************************************************/ | |
170 int main(void); | |
171 int main(void) | |
172 { | |
173 PaStream *stream; | |
174 PaError err; | |
175 paTestData DATA; | |
176 int i, timeout; | |
177 PaTime previousTime; | |
178 PaStreamParameters outputParameters; | |
179 printf("PortAudio Test: you should see BEEP at the same time you hear it.\n"); | |
180 printf("Wait for a few seconds random delay between BEEPs.\n"); | |
181 printf("BEEP %d times.\n", NUM_BEEPS ); | |
182 /* Initialize our DATA for use by callback. */ | |
183 DATA.left_phase = DATA.right_phase = 0.0; | |
184 DATA.state = STATE_BKG_IDLE; | |
185 DATA.requestBeep = 0; | |
186 /* Initialize library before making any other calls. */ | |
187 err = Pa_Initialize(); | |
188 if( err != paNoError ) goto error; | |
189 | |
190 outputParameters.device = Pa_GetDefaultOutputDevice(); | |
191 if (outputParameters.device == paNoDevice) { | |
192 fprintf(stderr,"Error: No default output device.\n"); | |
193 goto error; | |
194 } | |
195 outputParameters.channelCount = 2; | |
196 outputParameters.hostApiSpecificStreamInfo = NULL; | |
197 outputParameters.sampleFormat = paFloat32; | |
198 outputParameters.suggestedLatency = (double)LATENCY_MSEC / 1000; | |
199 | |
200 /* Open an audio I/O stream. */ | |
201 err = Pa_OpenStream( | |
202 &stream, | |
203 NULL, /* no input */ | |
204 &outputParameters, | |
205 SAMPLE_RATE, | |
206 FRAMES_PER_BUFFER, /* frames per buffer */ | |
207 paClipOff, /* we won't output out of range samples so don't bother clipping them */ | |
208 patestCallback, | |
209 &DATA ); | |
210 if( err != paNoError ) goto error; | |
211 | |
212 err = Pa_StartStream( stream ); | |
213 if( err != paNoError ) goto error; | |
214 | |
215 printf("started\n"); | |
216 fflush(stdout); | |
217 | |
218 previousTime = Pa_GetStreamTime( stream ); | |
219 for( i=0; i<NUM_BEEPS; i++ ) | |
220 { | |
221 /* Request a beep from background. */ | |
222 DATA.requestBeep = 1; | |
223 | |
224 /* Wait for background to acknowledge request. */ | |
225 timeout = TIMEOUT_MSEC; | |
226 while( (DATA.requestBeep == 1) && (timeout-- > 0 ) ) Pa_Sleep(SLEEP_MSEC); | |
227 if( timeout <= 0 ) | |
228 { | |
229 fprintf( stderr, "Timed out waiting for background to acknowledge request.\n" ); | |
230 goto error; | |
231 } | |
232 printf("calc beep for %9.3f, latency = %6.3f\n", DATA.beepTime, DATA.latency ); | |
233 fflush(stdout); | |
234 | |
235 /* Wait for scheduled beep time. */ | |
236 timeout = TIMEOUT_MSEC + (10000/SLEEP_MSEC); | |
237 while( (Pa_GetStreamTime( stream ) < DATA.beepTime) && (timeout-- > 0 ) ) | |
238 { | |
239 Pa_Sleep(SLEEP_MSEC); | |
240 } | |
241 if( timeout <= 0 ) | |
242 { | |
243 fprintf( stderr, "Timed out waiting for time. Now = %9.3f, Beep for %9.3f.\n", | |
244 PaUtil_GetTime(), DATA.beepTime ); | |
245 goto error; | |
246 } | |
247 | |
248 /* Beep should be sounding now so print synchronized BEEP. */ | |
249 printf("hear \"BEEP\" at %9.3f, delta = %9.3f\n", | |
250 Pa_GetStreamTime( stream ), (DATA.beepTime - previousTime) ); | |
251 fflush(stdout); | |
252 | |
253 previousTime = DATA.beepTime; | |
254 } | |
255 | |
256 err = Pa_StopStream( stream ); | |
257 if( err != paNoError ) goto error; | |
258 | |
259 err = Pa_CloseStream( stream ); | |
260 if( err != paNoError ) goto error; | |
261 | |
262 Pa_Terminate(); | |
263 printf("Test finished.\n"); | |
264 return err; | |
265 error: | |
266 Pa_Terminate(); | |
267 fprintf( stderr, "An error occured while using the portaudio stream\n" ); | |
268 fprintf( stderr, "Error number: %d\n", err ); | |
269 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); | |
270 return err; | |
271 } |