Mercurial > hg > sv-dependency-builds
comparison src/portaudio_20161030/test/patest_in_overflow.c @ 55:284acf908dcd
Add source for PortAudio stable v190600_20161030
author | Chris Cannam |
---|---|
date | Tue, 03 Jan 2017 13:44:07 +0000 |
parents | src/portaudio/test/patest_in_overflow.c@e13257ea84a4 |
children |
comparison
equal
deleted
inserted
replaced
54:5f67a29f0fc7 | 55:284acf908dcd |
---|---|
1 /** @file patest_in_overflow.c | |
2 @ingroup test_src | |
3 @brief Count input overflows (using paInputOverflow flag) under | |
4 overloaded and normal conditions. | |
5 This test uses the same method to overload the stream as does | |
6 patest_out_underflow.c -- it generates sine waves until the cpu load | |
7 exceeds a certain level. However this test is only concerned with | |
8 input and so doesn't ouput any sound. | |
9 | |
10 @author Ross Bencina <rossb@audiomulch.com> | |
11 @author Phil Burk <philburk@softsynth.com> | |
12 */ | |
13 /* | |
14 * $Id$ | |
15 * | |
16 * This program uses the PortAudio Portable Audio Library. | |
17 * For more information see: http://www.portaudio.com | |
18 * Copyright (c) 1999-2004 Ross Bencina and Phil Burk | |
19 * | |
20 * Permission is hereby granted, free of charge, to any person obtaining | |
21 * a copy of this software and associated documentation files | |
22 * (the "Software"), to deal in the Software without restriction, | |
23 * including without limitation the rights to use, copy, modify, merge, | |
24 * publish, distribute, sublicense, and/or sell copies of the Software, | |
25 * and to permit persons to whom the Software is furnished to do so, | |
26 * subject to the following conditions: | |
27 * | |
28 * The above copyright notice and this permission notice shall be | |
29 * included in all copies or substantial portions of the Software. | |
30 * | |
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
32 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
33 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
34 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
35 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
36 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
37 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
38 */ | |
39 | |
40 /* | |
41 * The text above constitutes the entire PortAudio license; however, | |
42 * the PortAudio community also makes the following non-binding requests: | |
43 * | |
44 * Any person wishing to distribute modifications to the Software is | |
45 * requested to send the modifications to the original developer so that | |
46 * they can be incorporated into the canonical version. It is also | |
47 * requested that these non-binding requests be included along with the | |
48 * license above. | |
49 */ | |
50 | |
51 #include <stdio.h> | |
52 #include <math.h> | |
53 #include "portaudio.h" | |
54 | |
55 #define MAX_SINES (500) | |
56 #define MAX_LOAD (1.2) | |
57 #define SAMPLE_RATE (44100) | |
58 #define FRAMES_PER_BUFFER (512) | |
59 #ifndef M_PI | |
60 #define M_PI (3.14159265) | |
61 #endif | |
62 #define TWOPI (M_PI * 2.0) | |
63 | |
64 typedef struct paTestData | |
65 { | |
66 int sineCount; | |
67 double phases[MAX_SINES]; | |
68 int countOverflows; | |
69 int inputOverflowCount; | |
70 } | |
71 paTestData; | |
72 | |
73 /* This routine will be called by the PortAudio engine when audio is needed. | |
74 ** It may called at interrupt level on some machines so don't do anything | |
75 ** that could mess up the system like calling malloc() or free(). | |
76 */ | |
77 static int patestCallback( const void *inputBuffer, void *outputBuffer, | |
78 unsigned long framesPerBuffer, | |
79 const PaStreamCallbackTimeInfo* timeInfo, | |
80 PaStreamCallbackFlags statusFlags, | |
81 void *userData ) | |
82 { | |
83 paTestData *data = (paTestData*)userData; | |
84 float out; /* variable to hold dummy output */ | |
85 unsigned long i; | |
86 int j; | |
87 int finished = paContinue; | |
88 (void) timeInfo; /* Prevent unused variable warning. */ | |
89 (void) inputBuffer; /* Prevent unused variable warning. */ | |
90 (void) outputBuffer; /* Prevent unused variable warning. */ | |
91 | |
92 if( data->countOverflows && (statusFlags & paInputOverflow) ) | |
93 data->inputOverflowCount++; | |
94 | |
95 for( i=0; i<framesPerBuffer; i++ ) | |
96 { | |
97 float output = 0.0; | |
98 double phaseInc = 0.02; | |
99 double phase; | |
100 | |
101 for( j=0; j<data->sineCount; j++ ) | |
102 { | |
103 /* Advance phase of next oscillator. */ | |
104 phase = data->phases[j]; | |
105 phase += phaseInc; | |
106 if( phase > TWOPI ) phase -= TWOPI; | |
107 | |
108 phaseInc *= 1.02; | |
109 if( phaseInc > 0.5 ) phaseInc *= 0.5; | |
110 | |
111 /* This is not a very efficient way to calc sines. */ | |
112 output += (float) sin( phase ); | |
113 data->phases[j] = phase; | |
114 } | |
115 /* this is an input-only stream so we don't actually use the output */ | |
116 out = (float) (output / data->sineCount); | |
117 (void) out; /* suppress unused variable warning*/ | |
118 } | |
119 | |
120 return finished; | |
121 } | |
122 | |
123 /*******************************************************************/ | |
124 int main(void); | |
125 int main(void) | |
126 { | |
127 PaStreamParameters inputParameters; | |
128 PaStream *stream; | |
129 PaError err; | |
130 int safeSineCount, stressedSineCount; | |
131 int safeOverflowCount, stressedOverflowCount; | |
132 paTestData data = {0}; | |
133 double load; | |
134 | |
135 | |
136 printf("PortAudio Test: input only, no sound output. Load callback by performing calculations, count input overflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n", | |
137 SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD ); | |
138 | |
139 err = Pa_Initialize(); | |
140 if( err != paNoError ) goto error; | |
141 | |
142 inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ | |
143 if (inputParameters.device == paNoDevice) { | |
144 fprintf(stderr,"Error: No default input device.\n"); | |
145 goto error; | |
146 } | |
147 inputParameters.channelCount = 1; /* mono output */ | |
148 inputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ | |
149 inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; | |
150 inputParameters.hostApiSpecificStreamInfo = NULL; | |
151 | |
152 err = Pa_OpenStream( | |
153 &stream, | |
154 &inputParameters, | |
155 NULL, /* no output */ | |
156 SAMPLE_RATE, | |
157 FRAMES_PER_BUFFER, | |
158 paClipOff, /* we won't output out of range samples so don't bother clipping them */ | |
159 patestCallback, | |
160 &data ); | |
161 if( err != paNoError ) goto error; | |
162 err = Pa_StartStream( stream ); | |
163 if( err != paNoError ) goto error; | |
164 | |
165 printf("Establishing load conditions...\n" ); | |
166 | |
167 /* Determine number of sines required to get to 50% */ | |
168 do | |
169 { | |
170 data.sineCount++; | |
171 Pa_Sleep( 100 ); | |
172 | |
173 load = Pa_GetStreamCpuLoad( stream ); | |
174 printf("sineCount = %d, CPU load = %f\n", data.sineCount, load ); | |
175 } | |
176 while( load < 0.5 && data.sineCount < (MAX_SINES-1)); | |
177 | |
178 safeSineCount = data.sineCount; | |
179 | |
180 /* Calculate target stress value then ramp up to that level*/ | |
181 stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD ); | |
182 if( stressedSineCount > MAX_SINES ) | |
183 stressedSineCount = MAX_SINES; | |
184 for( ; data.sineCount < stressedSineCount; data.sineCount++ ) | |
185 { | |
186 Pa_Sleep( 100 ); | |
187 load = Pa_GetStreamCpuLoad( stream ); | |
188 printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load ); | |
189 } | |
190 | |
191 printf("Counting overflows for 5 seconds.\n"); | |
192 data.countOverflows = 1; | |
193 Pa_Sleep( 5000 ); | |
194 | |
195 stressedOverflowCount = data.inputOverflowCount; | |
196 | |
197 data.countOverflows = 0; | |
198 data.sineCount = safeSineCount; | |
199 | |
200 printf("Resuming safe load...\n"); | |
201 Pa_Sleep( 1500 ); | |
202 data.inputOverflowCount = 0; | |
203 Pa_Sleep( 1500 ); | |
204 load = Pa_GetStreamCpuLoad( stream ); | |
205 printf("sineCount = %d, CPU load = %f\n", data.sineCount, load ); | |
206 | |
207 printf("Counting overflows for 5 seconds.\n"); | |
208 data.countOverflows = 1; | |
209 Pa_Sleep( 5000 ); | |
210 | |
211 safeOverflowCount = data.inputOverflowCount; | |
212 | |
213 printf("Stop stream.\n"); | |
214 err = Pa_StopStream( stream ); | |
215 if( err != paNoError ) goto error; | |
216 | |
217 err = Pa_CloseStream( stream ); | |
218 if( err != paNoError ) goto error; | |
219 | |
220 Pa_Terminate(); | |
221 | |
222 if( stressedOverflowCount == 0 ) | |
223 printf("Test failed, no input overflows detected under stress.\n"); | |
224 else if( safeOverflowCount != 0 ) | |
225 printf("Test failed, %d unexpected overflows detected under safe load.\n", safeOverflowCount); | |
226 else | |
227 printf("Test passed, %d expected input overflows detected under stress, 0 unexpected overflows detected under safe load.\n", stressedOverflowCount ); | |
228 | |
229 return err; | |
230 error: | |
231 Pa_Terminate(); | |
232 fprintf( stderr, "An error occured while using the portaudio stream\n" ); | |
233 fprintf( stderr, "Error number: %d\n", err ); | |
234 fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); | |
235 return err; | |
236 } |