diff options
Diffstat (limited to 'toxav/av_test.c')
-rw-r--r-- | toxav/av_test.c | 270 |
1 files changed, 254 insertions, 16 deletions
diff --git a/toxav/av_test.c b/toxav/av_test.c index bb79eedc..01484249 100644 --- a/toxav/av_test.c +++ b/toxav/av_test.c | |||
@@ -1,6 +1,18 @@ | |||
1 | #include "toxav.h" | 1 | #include "toxav.h" |
2 | #include "../toxcore/tox.h" | 2 | #include "../toxcore/tox.h" |
3 | 3 | ||
4 | #ifdef __APPLE__ | ||
5 | # include <OpenAL/al.h> | ||
6 | # include <OpenAL/alc.h> | ||
7 | #else | ||
8 | # include <AL/al.h> | ||
9 | # include <AL/alc.h> | ||
10 | /* compatibility with older versions of OpenAL */ | ||
11 | # ifndef ALC_ALL_DEVICES_SPECIFIER | ||
12 | # include <AL/alext.h> | ||
13 | # endif /* ALC_ALL_DEVICES_SPECIFIER */ | ||
14 | #endif /* __APPLE__ */ | ||
15 | |||
4 | #include <assert.h> | 16 | #include <assert.h> |
5 | #include <stdio.h> | 17 | #include <stdio.h> |
6 | #include <stdlib.h> | 18 | #include <stdlib.h> |
@@ -14,6 +26,16 @@ | |||
14 | #define c_sleep(x) usleep(1000*x) | 26 | #define c_sleep(x) usleep(1000*x) |
15 | #endif | 27 | #endif |
16 | 28 | ||
29 | /* Enable/disable tests */ | ||
30 | #define TEST_REGULAR_AV 0 | ||
31 | #define TEST_REGULAR_A 0 | ||
32 | #define TEST_REGULAR_V 0 | ||
33 | #define TEST_REJECT 0 | ||
34 | #define TEST_CANCEL 0 | ||
35 | #define TEST_MUTE_UNMUTE 0 | ||
36 | #define TEST_TRANSFER_A 1 | ||
37 | |||
38 | |||
17 | typedef struct { | 39 | typedef struct { |
18 | bool incoming; | 40 | bool incoming; |
19 | uint32_t state; | 41 | uint32_t state; |
@@ -134,9 +156,201 @@ void iterate(Tox* Bsn, ToxAV* AliceAV, ToxAV* BobAV) | |||
134 | c_sleep(20); | 156 | c_sleep(20); |
135 | } | 157 | } |
136 | 158 | ||
159 | int device_read_frame(ALCdevice* device, int32_t frame_dur, int16_t* PCM, size_t max_size) | ||
160 | { | ||
161 | int f_size = (48000 * frame_dur / 1000); | ||
162 | |||
163 | if (max_size < f_size) | ||
164 | return -1; | ||
165 | |||
166 | /* Don't block if not enough data */ | ||
167 | int32_t samples; | ||
168 | alcGetIntegerv(device, ALC_CAPTURE_SAMPLES, sizeof(int32_t), &samples); | ||
169 | if (samples < f_size) | ||
170 | return 0; | ||
171 | |||
172 | alcCaptureSamples(device, PCM, f_size); | ||
173 | return f_size; | ||
174 | } | ||
175 | |||
176 | int device_play_frame(uint32_t source, int16_t* PCM, size_t size) | ||
177 | { | ||
178 | uint32_t bufid; | ||
179 | int32_t processed, queued; | ||
180 | alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); | ||
181 | alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); | ||
182 | |||
183 | if(processed) { | ||
184 | uint32_t bufids[processed]; | ||
185 | alSourceUnqueueBuffers(source, processed, bufids); | ||
186 | alDeleteBuffers(processed - 1, bufids + 1); | ||
187 | bufid = bufids[0]; | ||
188 | } | ||
189 | else if(queued < 16) | ||
190 | alGenBuffers(1, &bufid); | ||
191 | else | ||
192 | return 0; | ||
193 | |||
194 | |||
195 | alBufferData(bufid, AL_FORMAT_STEREO16, PCM, size * 2 * 2, 48000); | ||
196 | alSourceQueueBuffers(source, 1, &bufid); | ||
197 | |||
198 | int32_t state; | ||
199 | alGetSourcei(source, AL_SOURCE_STATE, &state); | ||
200 | |||
201 | if(state != AL_PLAYING) | ||
202 | alSourcePlay(source); | ||
203 | return 1; | ||
204 | } | ||
205 | |||
206 | int print_devices() | ||
207 | { | ||
208 | const char* default_input; | ||
209 | const char* default_output; | ||
210 | |||
211 | const char *device; | ||
212 | |||
213 | printf("Default input device: %s\n", alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)); | ||
214 | printf("Default output device: %s\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER)); | ||
215 | |||
216 | printf("\n"); | ||
217 | |||
218 | printf("Input devices:\n"); | ||
219 | |||
220 | int i = 0; | ||
221 | for(device = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); *device; | ||
222 | device += strlen( device ) + 1, ++i) { | ||
223 | printf("%d) %s\n", i, device); | ||
224 | } | ||
225 | |||
226 | printf("\n"); | ||
227 | printf("Output devices:\n"); | ||
228 | |||
229 | i = 0; | ||
230 | for(device = alcGetString(NULL, ALC_DEVICE_SPECIFIER); *device; | ||
231 | device += strlen( device ) + 1, ++i) { | ||
232 | printf("%d) %s\n", i, device); | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | int print_help(const char* name, int rc) | ||
239 | { | ||
240 | fprintf(stderr, "Usage: %s [-h] <in device> <out device>\n", name); | ||
241 | return rc; | ||
242 | } | ||
243 | |||
244 | long get_device_idx(const char* arg) | ||
245 | { | ||
246 | if (strcmp(arg, "-") == 0) | ||
247 | return -1; /* Default */ | ||
248 | |||
249 | char *p; | ||
250 | long res = strtol(arg, &p, 10); | ||
251 | |||
252 | if (*p) { | ||
253 | fprintf(stderr, "Invalid device!"); | ||
254 | exit(1); | ||
255 | } | ||
256 | |||
257 | return res; | ||
258 | } | ||
137 | 259 | ||
138 | int main (int argc, char** argv) | 260 | int main (int argc, char** argv) |
139 | { | 261 | { |
262 | if (argc == 2) { | ||
263 | if (strcmp(argv[1], "-d") == 0 || strcmp(argv[1], "--devices") == 0) { | ||
264 | return print_devices(); | ||
265 | } | ||
266 | if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { | ||
267 | return print_help(argv[0], 0); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | if (argc != 3) { | ||
272 | fprintf(stderr, "Invalid input!\n"); | ||
273 | return print_help(argv[0], 1); | ||
274 | } | ||
275 | |||
276 | int i; | ||
277 | |||
278 | const char* in_device_name = ""; | ||
279 | const char* out_device_name = ""; | ||
280 | |||
281 | { | ||
282 | long dev = get_device_idx(argv[1]); | ||
283 | if (dev == -1) | ||
284 | in_device_name = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER); | ||
285 | else | ||
286 | { | ||
287 | const char* tmp; | ||
288 | i = -1; | ||
289 | for(tmp = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); *tmp && i != dev; | ||
290 | tmp += strlen( tmp ) + 1, ++i) | ||
291 | in_device_name = tmp; | ||
292 | } | ||
293 | |||
294 | printf("Input device: %s\n", in_device_name); | ||
295 | } | ||
296 | |||
297 | { | ||
298 | long dev = get_device_idx(argv[1]); | ||
299 | if (dev == -1) | ||
300 | out_device_name = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); | ||
301 | else | ||
302 | { | ||
303 | const char* tmp; | ||
304 | i = -1; | ||
305 | for(tmp = alcGetString(NULL, ALC_DEVICE_SPECIFIER); *tmp && i != dev; | ||
306 | tmp += strlen( tmp ) + 1, ++i) | ||
307 | out_device_name = tmp; | ||
308 | } | ||
309 | |||
310 | printf("Output device: %s\n", out_device_name); | ||
311 | } | ||
312 | |||
313 | ALCdevice* out_device; | ||
314 | ALCcontext* out_ctx; | ||
315 | uint32_t source; | ||
316 | uint32_t buffers[5]; | ||
317 | |||
318 | { /* Open output device */ | ||
319 | out_device = alcOpenDevice(out_device_name); | ||
320 | if ( !out_device ) { | ||
321 | fprintf(stderr, "Failed to open playback device: %s: %d\n", out_device_name, alGetError()); | ||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | out_ctx = alcCreateContext(out_device, NULL); | ||
326 | alcMakeContextCurrent(out_ctx); | ||
327 | |||
328 | alGenBuffers(5, buffers); | ||
329 | alGenSources((uint32_t)1, &source); | ||
330 | alSourcei(source, AL_LOOPING, AL_FALSE); | ||
331 | |||
332 | uint16_t zeros[10000]; | ||
333 | memset(zeros, 0, 10000); | ||
334 | |||
335 | for ( i = 0; i < 5; ++i ) | ||
336 | alBufferData(buffers[i], AL_FORMAT_STEREO16, zeros, 10000, 48000); | ||
337 | |||
338 | alSourceQueueBuffers(source, 5, buffers); | ||
339 | alSourcePlay(source); | ||
340 | } | ||
341 | |||
342 | ALCdevice* in_device; | ||
343 | |||
344 | { /* Open input device */ | ||
345 | in_device = alcCaptureOpenDevice(in_device_name, 48000, AL_FORMAT_STEREO16, 10000); | ||
346 | if ( !in_device ) { | ||
347 | fprintf(stderr, "Failed to open capture device: %s: %d\n", in_device_name, alGetError()); | ||
348 | return 1; | ||
349 | } | ||
350 | |||
351 | alcCaptureStart(in_device); | ||
352 | } | ||
353 | |||
140 | Tox *Bsn = tox_new(0); | 354 | Tox *Bsn = tox_new(0); |
141 | Tox *Alice = tox_new(0); | 355 | Tox *Alice = tox_new(0); |
142 | Tox *Bob = tox_new(0); | 356 | Tox *Bob = tox_new(0); |
@@ -163,7 +377,7 @@ int main (int argc, char** argv) | |||
163 | 377 | ||
164 | 378 | ||
165 | #define REGULAR_CALL_FLOW(A_BR, V_BR) \ | 379 | #define REGULAR_CALL_FLOW(A_BR, V_BR) \ |
166 | { \ | 380 | do { \ |
167 | memset(&AliceCC, 0, sizeof(CallControl)); \ | 381 | memset(&AliceCC, 0, sizeof(CallControl)); \ |
168 | memset(&BobCC, 0, sizeof(CallControl)); \ | 382 | memset(&BobCC, 0, sizeof(CallControl)); \ |
169 | \ | 383 | \ |
@@ -208,20 +422,26 @@ int main (int argc, char** argv) | |||
208 | iterate(Bsn, AliceAV, BobAV); \ | 422 | iterate(Bsn, AliceAV, BobAV); \ |
209 | } \ | 423 | } \ |
210 | printf("Success!\n");\ | 424 | printf("Success!\n");\ |
211 | } | 425 | } while(0) |
212 | |||
213 | printf("\nTrying regular call (Audio and Video)...\n"); | ||
214 | REGULAR_CALL_FLOW(48, 4000); | ||
215 | |||
216 | printf("\nTrying regular call (Audio only)...\n"); | ||
217 | REGULAR_CALL_FLOW(48, 0); | ||
218 | |||
219 | printf("\nTrying regular call (Video only)...\n"); | ||
220 | REGULAR_CALL_FLOW(0, 4000); | ||
221 | 426 | ||
427 | if (TEST_REGULAR_AV) { | ||
428 | printf("\nTrying regular call (Audio and Video)...\n"); | ||
429 | REGULAR_CALL_FLOW(48, 4000); | ||
430 | } | ||
431 | |||
432 | if (TEST_REGULAR_A) { | ||
433 | printf("\nTrying regular call (Audio only)...\n"); | ||
434 | REGULAR_CALL_FLOW(48, 0); | ||
435 | } | ||
436 | |||
437 | if (TEST_REGULAR_V) { | ||
438 | printf("\nTrying regular call (Video only)...\n"); | ||
439 | REGULAR_CALL_FLOW(0, 4000); | ||
440 | } | ||
441 | |||
222 | #undef REGULAR_CALL_FLOW | 442 | #undef REGULAR_CALL_FLOW |
223 | 443 | ||
224 | { /* Alice calls; Bob rejects */ | 444 | if (TEST_REJECT) { /* Alice calls; Bob rejects */ |
225 | printf("\nTrying reject flow...\n"); | 445 | printf("\nTrying reject flow...\n"); |
226 | 446 | ||
227 | memset(&AliceCC, 0, sizeof(CallControl)); | 447 | memset(&AliceCC, 0, sizeof(CallControl)); |
@@ -257,7 +477,7 @@ int main (int argc, char** argv) | |||
257 | printf("Success!\n"); | 477 | printf("Success!\n"); |
258 | } | 478 | } |
259 | 479 | ||
260 | { /* Alice calls; Alice cancels while ringing */ | 480 | if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */ |
261 | printf("\nTrying cancel (while ringing) flow...\n"); | 481 | printf("\nTrying cancel (while ringing) flow...\n"); |
262 | 482 | ||
263 | memset(&AliceCC, 0, sizeof(CallControl)); | 483 | memset(&AliceCC, 0, sizeof(CallControl)); |
@@ -294,10 +514,9 @@ int main (int argc, char** argv) | |||
294 | printf("Success!\n"); | 514 | printf("Success!\n"); |
295 | } | 515 | } |
296 | 516 | ||
297 | { /* Check Mute-Unmute etc */ | 517 | if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */ |
298 | printf("\nTrying mute functionality...\n"); | 518 | printf("\nTrying mute functionality...\n"); |
299 | 519 | ||
300 | |||
301 | memset(&AliceCC, 0, sizeof(CallControl)); | 520 | memset(&AliceCC, 0, sizeof(CallControl)); |
302 | memset(&BobCC, 0, sizeof(CallControl)); | 521 | memset(&BobCC, 0, sizeof(CallControl)); |
303 | 522 | ||
@@ -382,7 +601,23 @@ int main (int argc, char** argv) | |||
382 | printf("Success!\n"); | 601 | printf("Success!\n"); |
383 | } | 602 | } |
384 | 603 | ||
385 | 604 | if (TEST_TRANSFER_A) { /* Audio encoding/decoding and transfer */ | |
605 | printf("\nTrying audio enc/dec...\n"); | ||
606 | |||
607 | int16_t PCM[10000]; | ||
608 | time_t start_time = time(NULL); | ||
609 | |||
610 | /* Run for 5 seconds */ | ||
611 | while ( start_time + 10 > time(NULL) ) { | ||
612 | int frame_size = device_read_frame(in_device, 20, PCM, sizeof(PCM)); | ||
613 | if (frame_size > 0) | ||
614 | device_play_frame(source, PCM, frame_size); | ||
615 | // c_sleep(20); | ||
616 | } | ||
617 | |||
618 | printf("Success!"); | ||
619 | } | ||
620 | |||
386 | toxav_kill(BobAV); | 621 | toxav_kill(BobAV); |
387 | toxav_kill(AliceAV); | 622 | toxav_kill(AliceAV); |
388 | tox_kill(Bob); | 623 | tox_kill(Bob); |
@@ -390,5 +625,8 @@ int main (int argc, char** argv) | |||
390 | tox_kill(Bsn); | 625 | tox_kill(Bsn); |
391 | 626 | ||
392 | printf("\nTest successful!\n"); | 627 | printf("\nTest successful!\n"); |
628 | |||
629 | alcCloseDevice(out_device); | ||
630 | alcCaptureCloseDevice(in_device); | ||
393 | return 0; | 631 | return 0; |
394 | } \ No newline at end of file | 632 | } \ No newline at end of file |