Mercurial > hg > sv-dependency-builds
comparison src/portaudio/qa/paqa_errs.c @ 89:8a15ff55d9af
Add bzip2, zlib, liblo, portaudio sources
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Wed, 20 Mar 2013 13:59:52 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
88:fe7c3a0b0259 | 89:8a15ff55d9af |
---|---|
1 /** @file paqa_errs.c | |
2 @ingroup qa_src | |
3 @brief Self Testing Quality Assurance app for PortAudio | |
4 Do lots of bad things to test error reporting. | |
5 @author Phil Burk http://www.softsynth.com | |
6 Pieter Suurmond adapted to V19 API. | |
7 */ | |
8 /* | |
9 * $Id: paqa_errs.c 1756 2011-09-08 06:09:29Z philburk $ | |
10 * | |
11 * This program uses the PortAudio Portable Audio Library. | |
12 * For more information see: http://www.portaudio.com | |
13 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk | |
14 * | |
15 * Permission is hereby granted, free of charge, to any person obtaining | |
16 * a copy of this software and associated documentation files | |
17 * (the "Software"), to deal in the Software without restriction, | |
18 * including without limitation the rights to use, copy, modify, merge, | |
19 * publish, distribute, sublicense, and/or sell copies of the Software, | |
20 * and to permit persons to whom the Software is furnished to do so, | |
21 * subject to the following conditions: | |
22 * | |
23 * The above copyright notice and this permission notice shall be | |
24 * included in all copies or substantial portions of the Software. | |
25 * | |
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
29 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
30 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
31 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
32 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
33 */ | |
34 | |
35 /* | |
36 * The text above constitutes the entire PortAudio license; however, | |
37 * the PortAudio community also makes the following non-binding requests: | |
38 * | |
39 * Any person wishing to distribute modifications to the Software is | |
40 * requested to send the modifications to the original developer so that | |
41 * they can be incorporated into the canonical version. It is also | |
42 * requested that these non-binding requests be included along with the | |
43 * license above. | |
44 */ | |
45 | |
46 #include <stdio.h> | |
47 #include <math.h> | |
48 | |
49 #include "portaudio.h" | |
50 | |
51 /*--------- Definitions ---------*/ | |
52 #define MODE_INPUT (0) | |
53 #define MODE_OUTPUT (1) | |
54 #define FRAMES_PER_BUFFER (64) | |
55 #define SAMPLE_RATE (44100.0) | |
56 | |
57 typedef struct PaQaData | |
58 { | |
59 unsigned long framesLeft; | |
60 int numChannels; | |
61 int bytesPerSample; | |
62 int mode; | |
63 } | |
64 PaQaData; | |
65 | |
66 static int gNumPassed = 0; /* Two globals */ | |
67 static int gNumFailed = 0; | |
68 | |
69 /*------------------- Macros ------------------------------*/ | |
70 /* Print ERROR if it fails. Tally success or failure. Odd */ | |
71 /* do-while wrapper seems to be needed for some compilers. */ | |
72 | |
73 #define EXPECT(_exp) \ | |
74 do \ | |
75 { \ | |
76 if ((_exp)) {\ | |
77 gNumPassed++; \ | |
78 } \ | |
79 else { \ | |
80 printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \ | |
81 gNumFailed++; \ | |
82 goto error; \ | |
83 } \ | |
84 } while(0) | |
85 | |
86 #define HOPEFOR(_exp) \ | |
87 do \ | |
88 { \ | |
89 if ((_exp)) {\ | |
90 gNumPassed++; \ | |
91 } \ | |
92 else { \ | |
93 printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \ | |
94 gNumFailed++; \ | |
95 } \ | |
96 } while(0) | |
97 | |
98 /*-------------------------------------------------------------------------*/ | |
99 /* This routine will be called by the PortAudio engine when audio is needed. | |
100 It may be called at interrupt level on some machines so don't do anything | |
101 that could mess up the system like calling malloc() or free(). | |
102 */ | |
103 static int QaCallback( const void* inputBuffer, | |
104 void* outputBuffer, | |
105 unsigned long framesPerBuffer, | |
106 const PaStreamCallbackTimeInfo* timeInfo, | |
107 PaStreamCallbackFlags statusFlags, | |
108 void* userData ) | |
109 { | |
110 unsigned long i; | |
111 unsigned char* out = (unsigned char *) outputBuffer; | |
112 PaQaData* data = (PaQaData *) userData; | |
113 | |
114 (void)inputBuffer; /* Prevent "unused variable" warnings. */ | |
115 | |
116 /* Zero out buffer so we don't hear terrible noise. */ | |
117 if( data->mode == MODE_OUTPUT ) | |
118 { | |
119 unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample; | |
120 for( i=0; i<numBytes; i++ ) | |
121 { | |
122 *out++ = 0; | |
123 } | |
124 } | |
125 /* Are we through yet? */ | |
126 if( data->framesLeft > framesPerBuffer ) | |
127 { | |
128 data->framesLeft -= framesPerBuffer; | |
129 return 0; | |
130 } | |
131 else | |
132 { | |
133 data->framesLeft = 0; | |
134 return 1; | |
135 } | |
136 } | |
137 | |
138 static PaDeviceIndex FindInputOnlyDevice(void) | |
139 { | |
140 PaDeviceIndex result = Pa_GetDefaultInputDevice(); | |
141 if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxOutputChannels == 0 ) | |
142 return result; | |
143 | |
144 for( result = 0; result < Pa_GetDeviceCount(); ++result ) | |
145 { | |
146 if( Pa_GetDeviceInfo(result)->maxOutputChannels == 0 ) | |
147 return result; | |
148 } | |
149 | |
150 return paNoDevice; | |
151 } | |
152 | |
153 static PaDeviceIndex FindOutputOnlyDevice(void) | |
154 { | |
155 PaDeviceIndex result = Pa_GetDefaultOutputDevice(); | |
156 if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxInputChannels == 0 ) | |
157 return result; | |
158 | |
159 for( result = 0; result < Pa_GetDeviceCount(); ++result ) | |
160 { | |
161 if( Pa_GetDeviceInfo(result)->maxInputChannels == 0 ) | |
162 return result; | |
163 } | |
164 | |
165 return paNoDevice; | |
166 } | |
167 | |
168 /*-------------------------------------------------------------------------------------------------*/ | |
169 static int TestBadOpens( void ) | |
170 { | |
171 PaStream* stream = NULL; | |
172 PaError result; | |
173 PaQaData myData; | |
174 PaStreamParameters ipp, opp; | |
175 const PaDeviceInfo* info = NULL; | |
176 | |
177 | |
178 /* Setup data for synthesis thread. */ | |
179 myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */ | |
180 myData.numChannels = 1; | |
181 myData.mode = MODE_OUTPUT; | |
182 | |
183 /*----------------------------- No devices specified: */ | |
184 ipp.device = opp.device = paNoDevice; | |
185 ipp.channelCount = opp.channelCount = 0; /* Also no channels. */ | |
186 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
187 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
188 /* Take the low latency of the default device for all subsequent tests. */ | |
189 info = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice()); | |
190 ipp.suggestedLatency = info ? info->defaultLowInputLatency : 0.100; | |
191 info = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice()); | |
192 opp.suggestedLatency = info ? info->defaultLowOutputLatency : 0.100; | |
193 HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp, | |
194 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
195 paClipOff, QaCallback, &myData )) == paInvalidDevice)); | |
196 | |
197 /*----------------------------- No devices specified #2: */ | |
198 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, NULL, | |
199 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
200 paClipOff, QaCallback, &myData )) == paInvalidDevice)); | |
201 | |
202 /*----------------------------- Out of range input device specified: */ | |
203 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
204 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
205 ipp.channelCount = 0; ipp.device = Pa_GetDeviceCount(); /* And no output device, and no channels. */ | |
206 opp.channelCount = 0; opp.device = paNoDevice; | |
207 HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL, | |
208 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
209 paClipOff, QaCallback, &myData )) == paInvalidDevice)); | |
210 | |
211 /*----------------------------- Out of range output device specified: */ | |
212 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
213 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
214 ipp.channelCount = 0; ipp.device = paNoDevice; /* And no input device, and no channels. */ | |
215 opp.channelCount = 0; opp.device = Pa_GetDeviceCount(); | |
216 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp, | |
217 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
218 paClipOff, QaCallback, &myData )) == paInvalidDevice)); | |
219 | |
220 if (Pa_GetDefaultInputDevice() != paNoDevice) { | |
221 /*----------------------------- Zero input channels: */ | |
222 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
223 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
224 ipp.channelCount = 0; ipp.device = Pa_GetDefaultInputDevice(); | |
225 opp.channelCount = 0; opp.device = paNoDevice; /* And no output device, and no output channels. */ | |
226 HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL, | |
227 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
228 paClipOff, QaCallback, &myData )) == paInvalidChannelCount)); | |
229 } | |
230 | |
231 if (Pa_GetDefaultOutputDevice() != paNoDevice) { | |
232 /*----------------------------- Zero output channels: */ | |
233 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
234 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
235 ipp.channelCount = 0; ipp.device = paNoDevice; /* And no input device, and no input channels. */ | |
236 opp.channelCount = 0; opp.device = Pa_GetDefaultOutputDevice(); | |
237 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp, | |
238 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
239 paClipOff, QaCallback, &myData )) == paInvalidChannelCount)); | |
240 } | |
241 /*----------------------------- Nonzero input and output channels but no output device: */ | |
242 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
243 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
244 ipp.channelCount = 2; ipp.device = Pa_GetDefaultInputDevice(); /* Both stereo. */ | |
245 opp.channelCount = 2; opp.device = paNoDevice; | |
246 HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp, | |
247 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
248 paClipOff, QaCallback, &myData )) == paInvalidDevice)); | |
249 | |
250 /*----------------------------- Nonzero input and output channels but no input device: */ | |
251 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
252 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
253 ipp.channelCount = 2; ipp.device = paNoDevice; | |
254 opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice(); | |
255 HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp, | |
256 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
257 paClipOff, QaCallback, &myData )) == paInvalidDevice)); | |
258 | |
259 if (Pa_GetDefaultOutputDevice() != paNoDevice) { | |
260 /*----------------------------- NULL stream pointer: */ | |
261 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
262 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
263 ipp.channelCount = 0; ipp.device = paNoDevice; /* Output is more likely than input. */ | |
264 opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice(); /* Only 2 output channels. */ | |
265 HOPEFOR(((result = Pa_OpenStream(NULL, &ipp, &opp, | |
266 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
267 paClipOff, QaCallback, &myData )) == paBadStreamPtr)); | |
268 | |
269 /*----------------------------- Low sample rate: */ | |
270 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
271 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
272 ipp.channelCount = 0; ipp.device = paNoDevice; | |
273 opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice(); | |
274 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp, | |
275 1.0, FRAMES_PER_BUFFER, /* 1 cycle per second (1 Hz) is too low. */ | |
276 paClipOff, QaCallback, &myData )) == paInvalidSampleRate)); | |
277 | |
278 /*----------------------------- High sample rate: */ | |
279 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
280 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
281 ipp.channelCount = 0; ipp.device = paNoDevice; | |
282 opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice(); | |
283 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp, | |
284 10000000.0, FRAMES_PER_BUFFER, /* 10^6 cycles per second (10 MHz) is too high. */ | |
285 paClipOff, QaCallback, &myData )) == paInvalidSampleRate)); | |
286 | |
287 /*----------------------------- NULL callback: */ | |
288 /* NULL callback is valid in V19 -- it means use blocking read/write stream | |
289 | |
290 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
291 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
292 ipp.channelCount = 0; ipp.device = paNoDevice; | |
293 opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice(); | |
294 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp, | |
295 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
296 paClipOff, | |
297 NULL, | |
298 &myData )) == paNullCallback)); | |
299 */ | |
300 | |
301 /*----------------------------- Bad flag: */ | |
302 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
303 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
304 ipp.channelCount = 0; ipp.device = paNoDevice; | |
305 opp.channelCount = 2; opp.device = Pa_GetDefaultOutputDevice(); | |
306 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp, | |
307 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
308 255, /* Is 8 maybe legal V19 API? */ | |
309 QaCallback, &myData )) == paInvalidFlag)); | |
310 } | |
311 | |
312 /*----------------------------- using input device as output device: */ | |
313 if( FindInputOnlyDevice() != paNoDevice ) | |
314 { | |
315 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
316 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
317 ipp.channelCount = 0; ipp.device = paNoDevice; /* And no input device, and no channels. */ | |
318 opp.channelCount = 2; opp.device = FindInputOnlyDevice(); | |
319 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp, | |
320 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
321 paClipOff, QaCallback, &myData )) == paInvalidChannelCount)); | |
322 } | |
323 | |
324 /*----------------------------- using output device as input device: */ | |
325 if( FindOutputOnlyDevice() != paNoDevice ) | |
326 { | |
327 ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL; | |
328 ipp.sampleFormat = opp.sampleFormat = paFloat32; | |
329 ipp.channelCount = 2; ipp.device = FindOutputOnlyDevice(); | |
330 opp.channelCount = 0; opp.device = paNoDevice; /* And no output device, and no channels. */ | |
331 HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL, | |
332 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
333 paClipOff, QaCallback, &myData )) == paInvalidChannelCount)); | |
334 | |
335 } | |
336 | |
337 if( stream != NULL ) Pa_CloseStream( stream ); | |
338 return result; | |
339 } | |
340 | |
341 /*-----------------------------------------------------------------------------------------*/ | |
342 static int TestBadActions( void ) | |
343 { | |
344 PaStream* stream = NULL; | |
345 const PaDeviceInfo* deviceInfo = NULL; | |
346 PaError result = 0; | |
347 PaQaData myData; | |
348 PaStreamParameters opp; | |
349 const PaDeviceInfo* info = NULL; | |
350 | |
351 /* Setup data for synthesis thread. */ | |
352 myData.framesLeft = (unsigned long)(SAMPLE_RATE * 100); /* 100 seconds */ | |
353 myData.numChannels = 1; | |
354 myData.mode = MODE_OUTPUT; | |
355 | |
356 opp.device = Pa_GetDefaultOutputDevice(); /* Default output. */ | |
357 opp.channelCount = 2; /* Stereo output. */ | |
358 opp.hostApiSpecificStreamInfo = NULL; | |
359 opp.sampleFormat = paFloat32; | |
360 info = Pa_GetDeviceInfo(opp.device); | |
361 opp.suggestedLatency = info ? info->defaultLowOutputLatency : 0.100; | |
362 | |
363 if (opp.device != paNoDevice) { | |
364 HOPEFOR(((result = Pa_OpenStream(&stream, NULL, /* Take NULL as input parame- */ | |
365 &opp, /* ters, meaning try only output. */ | |
366 SAMPLE_RATE, FRAMES_PER_BUFFER, | |
367 paClipOff, QaCallback, &myData )) == paNoError)); | |
368 } | |
369 | |
370 HOPEFOR(((deviceInfo = Pa_GetDeviceInfo(paNoDevice)) == NULL)); | |
371 HOPEFOR(((deviceInfo = Pa_GetDeviceInfo(87654)) == NULL)); | |
372 HOPEFOR(((result = Pa_StartStream(NULL)) == paBadStreamPtr)); | |
373 HOPEFOR(((result = Pa_StopStream(NULL)) == paBadStreamPtr)); | |
374 HOPEFOR(((result = Pa_IsStreamStopped(NULL)) == paBadStreamPtr)); | |
375 HOPEFOR(((result = Pa_IsStreamActive(NULL)) == paBadStreamPtr)); | |
376 HOPEFOR(((result = Pa_CloseStream(NULL)) == paBadStreamPtr)); | |
377 HOPEFOR(((result = Pa_SetStreamFinishedCallback(NULL, NULL)) == paBadStreamPtr)); | |
378 HOPEFOR(((result = !Pa_GetStreamInfo(NULL)))); | |
379 HOPEFOR(((result = Pa_GetStreamTime(NULL)) == 0.0)); | |
380 HOPEFOR(((result = Pa_GetStreamCpuLoad(NULL)) == 0.0)); | |
381 HOPEFOR(((result = Pa_ReadStream(NULL, NULL, 0)) == paBadStreamPtr)); | |
382 HOPEFOR(((result = Pa_WriteStream(NULL, NULL, 0)) == paBadStreamPtr)); | |
383 | |
384 /** @todo test Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable */ | |
385 | |
386 if (stream != NULL) Pa_CloseStream(stream); | |
387 return result; | |
388 } | |
389 | |
390 /*---------------------------------------------------------------------*/ | |
391 int main(void); | |
392 int main(void) | |
393 { | |
394 PaError result; | |
395 | |
396 EXPECT(((result = Pa_Initialize()) == paNoError)); | |
397 TestBadOpens(); | |
398 TestBadActions(); | |
399 error: | |
400 Pa_Terminate(); | |
401 printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed); | |
402 return 0; | |
403 } |