summaryrefslogtreecommitdiff
path: root/toxav/av_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/av_test.c')
-rw-r--r--toxav/av_test.c270
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
17typedef struct { 39typedef 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
159int 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
176int 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
206int 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
238int 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
244long 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
138int main (int argc, char** argv) 260int 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