Changes rand() to rand_r()
[platform/core/api/audio-io.git] / test / audio_io_test.c
1 /*
2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <math.h>
22 #include <pthread.h>
23 #include <sound_manager.h>
24 #include <audio_io.h>
25 #include <time.h>
26
27 #ifndef M_PI
28 #define M_PI  (3.14159265)
29 #endif
30
31 #define TABLE_SIZE   (200)
32 typedef struct {
33         float sine[TABLE_SIZE];
34         int left_channel;
35         int right_channel;
36 } test_wav_t;
37 test_wav_t test_wav;
38
39 static int ch_table[] = { 0, AUDIO_CHANNEL_MONO, AUDIO_CHANNEL_STEREO,
40                           AUDIO_CHANNEL_MULTI_3, AUDIO_CHANNEL_MULTI_4, AUDIO_CHANNEL_MULTI_5,
41                           AUDIO_CHANNEL_MULTI_6, AUDIO_CHANNEL_MULTI_7, AUDIO_CHANNEL_MULTI_8 };
42 static char *state_str[] = { "IDLE", "RUNNING", "PAUSED" };
43
44 static void _audio_in_state_cb(audio_in_h handle, audio_io_state_e previous, audio_io_state_e current,
45                                                                 bool by_policy, void *user_data)
46 {
47         printf(">>> _audio_in_state_cb() : handle(%p), (%d,%s) => (%d,%s), by_policy(%d), user_data(%p)\n",
48                         handle, previous, state_str[previous], current, state_str[current], by_policy, user_data);
49 }
50
51 static void _audio_out_state_cb(audio_out_h handle, audio_io_state_e previous, audio_io_state_e current,
52                                                                 bool by_policy, void *user_data)
53 {
54         printf(">>> _audio_out_state_cb() : handle(%p), (%d,%s) => (%d,%s), by_policy(%d), user_data(%p)\n",
55                         handle, previous, state_str[previous], current, state_str[current], by_policy, user_data);
56 }
57
58 static void _play_file(char *file, int length, int num, int ch)
59 {
60         int i = 0;
61         int ret = 0;
62         int total_length = length * num;
63         audio_out_h output;
64         FILE *fp = fopen(file, "r");
65         if (fp == NULL) {
66                 printf("fopen failed\n");
67                 return;
68         }
69
70         char *buf = malloc(total_length);
71         if (buf == NULL) {
72                 printf("malloc failed\n");
73                 fclose(fp);
74                 return;
75         }
76
77         printf("# start to play [%s][%d][%d]\n", file, total_length, ch);
78         printf(" > create\n");
79         audio_out_create_new(44100, ch_table[ch], AUDIO_SAMPLE_TYPE_S16_LE, &output);
80         if (fread(buf, 1, total_length, fp) != total_length)
81                 printf("error!!!!\n");
82
83         ret = audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
84         if (ret != AUDIO_IO_ERROR_NONE) {
85                 printf("audio_out_set_state_changed_cb failed. \n");
86         }
87
88         printf("  > prepare\n");
89         audio_out_prepare(output);
90
91         char *pbuf = buf;
92         for (i = 0; i < num; i++) {
93                 printf("### write = (%d/%d) ============== \n", i, num);
94                 audio_out_write(output, pbuf, length);
95                 pbuf += length;
96
97         }
98         printf("  < unprepare\n");
99         audio_out_drain(output);
100         audio_out_unprepare(output);
101
102         printf(" < destroy\n");
103         audio_out_destroy(output);
104
105         fclose(fp);
106         free(buf);
107
108         printf("# play done\n");
109 }
110
111 #define DUMP_FILE "/root/test.raw"
112
113 FILE *fp = NULL;
114
115 static void _audio_out_stream_cb(audio_out_h handle, size_t nbytes, void *user_data)
116 {
117         char *buf = NULL;
118         int read_bytes = 0;
119         int written = 0;
120
121         if (fp == NULL) {
122                 printf("FILE is NULL\n");
123                 return;
124         }
125
126         buf = (char *)malloc(nbytes);
127         if (!buf) {
128                 printf("malloc(%zu) failed\n", nbytes);
129                 return;
130         }
131
132         read_bytes = fread(buf, 1, nbytes, fp);
133
134         written = audio_out_write(handle, buf, read_bytes);
135         printf("written : %6d/%6d (requested %zu)\n", written, read_bytes, nbytes);
136
137         if (read_bytes < nbytes) {
138                 printf("EOS!!!!\n");
139                 fclose(fp);
140                 fp = NULL;
141         }
142         free(buf);
143 }
144
145 static void _play_file_sample_async(char *file, int frequency, int ch, int type)
146 {
147         audio_out_h output;
148         int file_size = 0;
149
150         if (ch < 0 || ch > 2)
151                 ch = 0;
152
153         fp = fopen(file, "r");
154         if (fp == NULL) {
155                 printf("open failed\n");
156                 return;
157         }
158         printf("start to play [%s] of size [%d] with [%d][%d][%d]\n", file, file_size, frequency, ch, type);
159         audio_out_create_new(frequency, ch_table[ch], AUDIO_SAMPLE_TYPE_U8 + type, &output);
160
161         audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
162         audio_out_set_stream_cb(output, _audio_out_stream_cb, fp);
163         audio_out_prepare(output);
164
165         while (fp) {
166                 usleep(10000); /* 10ms */
167         }
168
169         printf("FINISHED!!!\n");
170
171         audio_out_unprepare(output);
172         audio_out_destroy(output);
173
174         printf("play done\n");
175 }
176
177 static void _play_file_sample_sync(char *file, int frequency, int ch, int type)
178 {
179         audio_out_h output;
180         int file_size = 0;
181         int read_bytes = 0;
182         int buffer_size = 0;
183         char *buf = NULL;
184         FILE *fp = NULL;
185         int i = 0;
186
187         if (ch < 0 || ch > 2)
188                 ch = 0;
189
190         fp = fopen(file, "r");
191         if (fp == NULL) {
192                 printf("open failed\n");
193                 return;
194         }
195         /* Get the size */
196         fseek(fp, 0, SEEK_END);
197         file_size = ftell(fp);
198         fseek(fp, 0, SEEK_SET);
199
200         printf("Play [%s] of size [%d] with [%d][%d][%d]\n", file, file_size, frequency, ch, type);
201         audio_out_create_new(frequency, ch_table[ch], AUDIO_SAMPLE_TYPE_U8 + type, &output);
202
203         audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
204         audio_out_prepare(output);
205
206         audio_out_get_buffer_size(output, &buffer_size);
207         buf = (char *)malloc(buffer_size);
208         if (buf == NULL) {
209                 printf("malloc failed\n");
210                 goto EXIT;
211         }
212
213         printf("Press any key to continue....\n");
214         getchar();
215         printf("Start to read[%d] from file and write : \n", buffer_size);
216
217         while (file_size > 0) {
218                 read_bytes = fread(buf, 1, buffer_size, fp);
219                 printf(".");
220                 i++;
221                 if (i % 10 == 0)
222                         printf("|");
223                 if (i % 100 == 0) {
224                         printf("\n");
225                         i = 0;
226                 }
227                 audio_out_write(output, buf, read_bytes);
228                 file_size = file_size - read_bytes;
229                 usleep(10000);
230         }
231
232 EXIT:
233         audio_out_unprepare(output);
234         audio_out_destroy(output);
235
236         if (buf)
237                 free(buf);
238         if (fp)
239                 fclose(fp);
240
241         printf("\nEOS!!!! Play done\n");
242 }
243
244 static int _record_and_play(int length, int num, int ch)
245 {
246         int ret, size, i;
247         audio_in_h input = NULL;
248         FILE *fp = NULL;
249         char *buffer = NULL;
250
251         ret = audio_in_create(44100, ch_table[ch], AUDIO_SAMPLE_TYPE_S16_LE, &input);
252         if (ret != AUDIO_IO_ERROR_NONE) {
253                 printf("audio in create error = 0x%x\n", ret);
254                 return -1;
255         }
256
257         ret = audio_in_set_state_changed_cb(input, _audio_in_state_cb, NULL);
258         if (ret != AUDIO_IO_ERROR_NONE) {
259                 printf("audio_in_set_state_changed_cb failed. \n");
260                 goto error;
261         }
262
263         ret = audio_in_prepare(input);
264         if (ret != AUDIO_IO_ERROR_NONE) {
265                 printf("ERROR, prepare\n");
266                 goto error;
267         }
268
269         fp = fopen(DUMP_FILE, "wb+");
270         if (fp == NULL) {
271                 printf("ERROR, file open failed\n");
272                 goto error;
273         }
274
275         ret = audio_in_get_buffer_size(input, &size);
276         if (ret != AUDIO_IO_ERROR_NONE) {
277                 printf("ERROR, prepare\n");
278                 goto error;
279         }
280
281         size = length;
282         buffer = alloca(size);
283
284         for (i = 0; i < num; i++) {
285                 printf("### read = (%d/%d) ============== ", i, num);
286                 if ((ret = audio_in_read(input, (void *)buffer, size)) > AUDIO_IO_ERROR_NONE) {
287                         fwrite(buffer, size, sizeof(char), fp);
288                         printf("PASS, size=%d, ret=0x%x\n", size, ret);
289                 } else {
290                         printf("FAIL, size=%d, ret=0x%x\n", size, ret);
291                 }
292         }
293
294         fclose(fp);
295
296         audio_in_unprepare(input);
297         audio_in_destroy(input);
298
299         _play_file(DUMP_FILE, length, num, ch);
300
301         return 0;
302
303 error:
304         audio_in_destroy(input);
305         if (fp)
306                 fclose(fp);
307         return -1;
308 }
309
310 static int _direct_loopback()
311 {
312         int ret, size;
313         audio_in_h input = NULL;
314         audio_out_h output = NULL;
315         char *buffer = NULL;
316         int i = 0;
317
318         ret = audio_in_create(16000, AUDIO_CHANNEL_MONO, AUDIO_SAMPLE_TYPE_S16_LE, &input);
319         if (ret != AUDIO_IO_ERROR_NONE) {
320                 printf("audio_in_create_ex failed. \n");
321                 return ret;
322         }
323         ret = audio_out_create_new(16000, AUDIO_CHANNEL_MONO, AUDIO_SAMPLE_TYPE_S16_LE, &output);
324         if (ret != AUDIO_IO_ERROR_NONE) {
325                 printf("audio_out_create_new failed. \n");
326                 goto exit;
327         }
328
329         ret = audio_in_prepare(input);
330         if (ret != 0) {
331                 printf("audio_in_prepare failed, err(0x%x)\n", ret);
332                 goto exit;
333         }
334
335         ret = audio_in_get_buffer_size(input, &size);
336         if (ret != AUDIO_IO_ERROR_NONE) {
337                 printf("audio_in_get_buffer_size failed, err(0x%x)\n", ret);
338                 goto exit;
339         }
340
341         printf("size(%d)\n", size);
342         buffer = alloca(size);
343
344         ret = audio_out_prepare(output);
345         if (ret != 0) {
346                 printf("audio_out_prepare failed, err(0x%x)\n", ret);
347                 goto exit;
348         }
349
350         if (buffer == NULL) {
351                 printf("buffer is null\n");
352                 ret = -1;
353                 goto exit;
354         }
355
356         printf("Start to loopback(read/write) with [16kHz/MONO/S16LE]!!!\n");
357
358         while (1) {
359                 ret = audio_in_read(input, (void *)buffer, size);
360                 if (ret > AUDIO_IO_ERROR_NONE) {
361                         ret = audio_out_write(output, buffer, size);
362                         if (ret > AUDIO_IO_ERROR_NONE) {
363                                 printf(".");
364                                 i++;
365                                 if (i % 10 == 0)
366                                         printf("|");
367                                 if (i % 100 == 0) {
368                                         printf("\n");
369                                         i = 0;
370                                 }
371                         } else {
372                                 printf("audio read success, write failed. buffer(%p), size(%d)\n", buffer, size);
373                         }
374                 } else {
375                         printf("audio read/write failed. buffer(%p), size(%d)\n", buffer, size);
376                 }
377                 usleep(10000);
378         }
379
380 exit:
381         if (input)
382                 audio_in_destroy(input);
383         if (output)
384                 audio_out_destroy(output);
385
386         return ret;
387
388 }
389
390 audio_in_h input;
391 audio_out_h output;
392
393 FILE *fp_w = NULL;
394
395 sound_stream_info_h g_stream_info_read_h = NULL;
396 sound_stream_info_h g_stream_info_write_h = NULL;
397
398 static void _focus_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask,
399                                         sound_stream_focus_state_e focus_state,
400                                         sound_stream_focus_change_reason_e reason_for_change, int sound_behavior,
401                                         const char *additional_info, void *user_data)
402 {
403         printf("*** focus_callback_read is called, stream_info(%p, read(%p)/write(%p)) ***\n",
404                         stream_info, g_stream_info_read_h, g_stream_info_write_h);
405         printf(" - reason_for_change(%d), additional_info(%s), user_data(%p)\n",
406                         reason_for_change, additional_info, user_data);
407         printf(" - focus_state is :%d \n", focus_state);
408
409         return;
410 }
411
412 static void _audio_io_stream_read_cb(audio_in_h handle, size_t nbytes, void *user_data)
413 {
414         const void *buffer = NULL;
415         unsigned int len = (unsigned int)nbytes;
416
417         if (len == 0)
418                 return;
419
420         audio_in_peek(handle, &buffer, &len);
421         if (fp_w)
422                 fwrite(buffer, sizeof(char), len, fp_w);
423         audio_in_drop(handle);
424 }
425
426 static void _audio_io_stream_write_cb(audio_out_h handle, size_t nbytes, void *user_data)
427 {
428         short *buffer = NULL;
429         int i = 0;
430
431         if (nbytes == 0)
432                 return;
433
434         buffer = (short *)malloc(nbytes);
435         if (buffer == NULL) {
436                 printf("malloc failed\n");
437                 return;
438         }
439         memset(buffer, 0, nbytes);
440
441         for (i = 0; i < nbytes / 2; i += 2) {
442                 buffer[i] = (short)32768 *test_wav.sine[test_wav.left_channel]; /* left */
443                 buffer[i + 1] = (short)32768 *test_wav.sine[test_wav.right_channel]; /* right */
444                 test_wav.left_channel += 1;
445                 if (test_wav.left_channel >= TABLE_SIZE)
446                         test_wav.left_channel -= TABLE_SIZE;
447                 test_wav.right_channel += 3;
448                 if (test_wav.right_channel >= TABLE_SIZE)
449                         test_wav.right_channel -= TABLE_SIZE;
450         }
451
452         audio_out_write(handle, buffer, nbytes);
453
454         free(buffer);
455 }
456
457 int _convert_cmd_and_run(char cmd, int mode)
458 {
459         int ret = 0;
460         switch (cmd) {
461         case 'P':
462                 if (mode & 0x01)
463                         ret = audio_out_prepare(output);
464                 if (mode & 0x02)
465                         ret = audio_in_prepare(input);
466                 break;
467         case 'u':
468                 if (mode & 0x01)
469                         ret = audio_out_unprepare(output);
470                 if (mode & 0x02)
471                         ret = audio_in_unprepare(input);
472                 break;
473         case 'p':
474                 if (mode & 0x01)
475                         ret = audio_out_pause(output);
476                 if (mode & 0x02)
477                         ret = audio_in_pause(input);
478                 break;
479         case 'r':
480                 if (mode & 0x01)
481                         ret = audio_out_resume(output);
482                 if (mode & 0x02)
483                         ret = audio_in_resume(input);
484                 break;
485         case 'd':
486                 if (mode & 0x01)
487                         ret = audio_out_drain(output);
488                 break;
489         case 'f':
490                 if (mode & 0x01)
491                         ret = audio_out_flush(output);
492                 if (mode & 0x02)
493                         ret = audio_in_flush(input);
494                 break;
495         case 'i':
496                 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _focus_cb, NULL, &g_stream_info_write_h);
497                 if (ret)
498                         printf("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
499                 break;
500         case 'q': /* quit */
501                 ret = 1;
502                 break;
503         default:
504                 ret = 1;
505                 break;
506         }
507         return ret;
508 }
509
510 int audio_io_async_test(int mode)
511 {
512         int ret, size;
513         char *buffer = NULL;
514         int i = 0;
515
516         char cmd = 0;
517         int cmd_ret;
518
519         int write_mode = (mode & 0x01);
520         int read_mode = (mode & 0x02);
521
522         sound_stream_focus_state_e playback_focus_state;
523         sound_stream_focus_state_e recording_focus_state;
524
525         if ((write_mode == 0) && (read_mode == 0)) {
526                 printf("not vaild mode.\n");
527                 return 0;
528         }
529
530         if (read_mode) {
531
532                 printf("audio_in_create\n");
533                 ret = audio_in_create(44100, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &input);
534                 if (ret != AUDIO_IO_ERROR_NONE) {
535                         printf("audio_in_create_ex failed. \n");
536                         return 0;
537                 }
538                 printf("audio_in_create success!!! [%p]\n", input);
539
540                 ret = audio_in_set_stream_cb(input, _audio_io_stream_read_cb, NULL);
541                 if (ret != AUDIO_IO_ERROR_NONE) {
542                         printf("audio_in_set_stream_cb failed. \n");
543                         goto EXIT;
544                 }
545                 printf("audio_in_set_stream_cb success!!! [%p]\n", input);
546
547                 ret = audio_in_set_state_changed_cb(input, _audio_in_state_cb, NULL);
548                 if (ret != AUDIO_IO_ERROR_NONE) {
549                         printf("audio_out_set_state_changed_cb failed. \n");
550                         goto EXIT;
551                 }
552                 printf("audio_out_set_state_changed_cb success!!! [%p]\n", input);
553
554                 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _focus_cb, NULL, &g_stream_info_read_h);
555                 if (ret) {
556                         printf("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
557                         goto EXIT;
558                 }
559                 ret = audio_in_set_sound_stream_info(input, g_stream_info_read_h);
560                 if (ret)
561                         printf("fail to audio_in_set_sound_stream_info(), ret(0x%x)\n", ret);
562
563                 ret = sound_manager_acquire_focus(g_stream_info_read_h, SOUND_STREAM_FOCUS_FOR_RECORDING, SOUND_BEHAVIOR_NONE, NULL);
564                 if (ret) {
565                         printf("fail to sound_manager_acquire_focus() for RECORDING, ret(0x%x)\n", ret);
566                         goto EXIT;
567                 }
568
569                 fp_w = fopen("/tmp/pcm_w.raw", "w");
570         }
571
572         if (write_mode) {
573                 printf("before audio_out_create_new\n");
574                 getchar();
575
576                 printf("audio_out_create_new\n");
577                 ret = audio_out_create_new(44100, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &output);
578                 if (ret != AUDIO_IO_ERROR_NONE) {
579                         printf("audio_out_create_new failed. \n");
580                         goto EXIT;
581                 }
582                 printf("audio_out_create_new success!!! [%p]\n", output);
583
584                 ret = audio_out_set_stream_cb(output, _audio_io_stream_write_cb, NULL);
585                 if (ret != AUDIO_IO_ERROR_NONE) {
586                         printf("audio_out_set_stream_cb failed. \n");
587                         goto EXIT;
588                 }
589                 printf("audio_out_set_stream_cb success!!! [%p]\n", output);
590
591                 ret = audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
592                 if (ret != AUDIO_IO_ERROR_NONE) {
593                         printf("audio_out_set_state_changed_cb failed. \n");
594                         goto EXIT;
595                 }
596                 printf("audio_out_set_state_changed_cb success!!! [%p]\n", output);
597
598                 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _focus_cb, NULL, &g_stream_info_write_h);
599                 if (ret) {
600                         printf("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
601                         goto EXIT;
602                 }
603
604                 ret = audio_out_set_sound_stream_info(output, g_stream_info_write_h);
605                 if (ret)
606                         printf("fail to audio_out_set_sound_stream_info(), ret(0x%x)\n", ret);
607
608                 ret = sound_manager_acquire_focus(g_stream_info_write_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
609                 if (ret) {
610                         printf("fail to sound_manager_acquire_focus() for PLAYBACK, ret(0x%x)\n", ret);
611                         goto EXIT;
612                 }
613
614                 /* generate wave data */
615                 for (i = 0; i < TABLE_SIZE; i++)
616                         test_wav.sine[i] = 0.9 * (float)sin(((double)i / (double)TABLE_SIZE) * M_PI * 2.);
617                 test_wav.left_channel = test_wav.right_channel = 0;
618         }
619
620         if (read_mode) {
621                 printf("before audio_in_prepare\n");
622                 getchar();
623                 printf("audio_in_prepare\n");
624                 ret = audio_in_prepare(input);
625                 if (ret != 0) {
626                         printf("audio_in_prepare failed, err(0x%x)\n", ret);
627                         audio_in_destroy(input);
628                         goto EXIT;
629                 } else {
630                         ret = audio_in_get_buffer_size(input, &size);
631                         if (ret != AUDIO_IO_ERROR_NONE) {
632                                 printf("audio_in_get_buffer_size failed, err(0x%x)\n", ret);
633                                 goto EXIT;
634                         } else {
635                                 printf("size(%d)\n", size);
636                                 buffer = alloca(size);
637                         }
638                 }
639
640                 if (buffer == NULL) {
641                         printf("buffer is null\n");
642                         goto EXIT;
643                 }
644         }
645
646         if (write_mode) {
647                 printf("before audio_out_prepare\n");
648                 getchar();
649                 printf("audio_out_prepare\n");
650                 ret = audio_out_prepare(output);
651                 if (ret != 0) {
652                         printf("audio_out_prepare failed, err(0x%x)\n", ret);
653                         audio_out_destroy(output);
654                         goto EXIT;
655                 }
656         }
657
658         do {
659                 printf("command(q:quit) : ");
660                 ret = getchar();
661                 if (ret == EOF)
662                         goto EXIT;
663                 cmd = (char)ret;
664                 if (cmd != '\n')
665                         getchar();
666                 cmd_ret = _convert_cmd_and_run(cmd, mode);
667                 printf("  - result code : %d\n", cmd_ret);
668         } while (cmd != 'q');
669
670 EXIT:
671         if (read_mode) {
672                 if (input) {
673                         printf("audio_in_unprepare\n");
674                         audio_in_unprepare(input);
675                         printf("audio_in_destroy\n");
676                         audio_in_destroy(input);
677                         input = NULL;
678                 }
679
680                 if (fp_w) {
681                         fclose(fp_w);
682                         fp_w = NULL;
683                 }
684
685                 if (g_stream_info_read_h) {
686                         ret = sound_manager_get_focus_state(g_stream_info_read_h, NULL, &recording_focus_state);
687                         if (recording_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
688                                 ret = sound_manager_release_focus(g_stream_info_read_h, SOUND_STREAM_FOCUS_FOR_RECORDING, SOUND_BEHAVIOR_NONE, NULL);
689                                 if (ret)
690                                         printf("fail to sound_manager_release_focus() for recording, ret(0x%x)\n", ret);
691                         }
692                         ret = sound_manager_destroy_stream_information(g_stream_info_read_h);
693                         if (ret)
694                                 printf("fail to sound_manager_destroy_stream_information(), ret(0x%x)\n", ret);
695                         g_stream_info_read_h = NULL;
696                 }
697         }
698
699         if (write_mode) {
700                 if (output) {
701                         printf("audio_out_unprepare\n");
702                         audio_out_unprepare(output);
703                         printf("audio_out_destroy\n");
704                         audio_out_destroy(output);
705                 }
706
707                 if (g_stream_info_write_h) {
708                         ret = sound_manager_get_focus_state(g_stream_info_write_h, &playback_focus_state, NULL);
709                         if (playback_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
710                                 ret = sound_manager_release_focus(g_stream_info_write_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
711                                 if (ret)
712                                         printf("fail to sound_manager_release_focus() for playback, ret(0x%x)\n", ret);
713                         }
714                         ret = sound_manager_destroy_stream_information(g_stream_info_write_h);
715                         if (ret)
716                                 printf("fail to sound_manager_destroy_stream_information(), ret(0x%x)\n", ret);
717                         g_stream_info_write_h = NULL;
718                 }
719         }
720
721         return 0;
722 }
723
724 #define THREAD_MAX 10
725 #define TEST_COUNT 500
726 static void *thread_stress_test_audio_in(void *data)
727 {
728         int i, j;
729         int rate;
730         char *buf;
731         int buffer_size;
732         audio_channel_e ch;
733         audio_sample_type_e type;
734         unsigned int seed = (unsigned int)time(NULL);
735
736         audio_in_h input = (audio_in_h)data;
737
738         audio_in_prepare(input);
739         audio_in_get_buffer_size(input, &buffer_size);
740         buf = (char *)malloc(buffer_size);
741         if (buf == NULL) {
742                 printf("malloc failed\n");
743                 goto EXIT;
744         }
745
746         for (i=0; i<TEST_COUNT; i++) {
747                 switch (rand_r(&seed) % 8) {
748                         case 0:
749                                 audio_in_prepare(input);
750                                 break;
751                         case 1:
752                                 audio_in_read(input, buf, buffer_size);
753                                 break;
754                         case 2:
755                                 audio_in_pause(input);
756                                 break;
757                         case 3:
758                                 audio_in_resume(input);
759                                 break;
760                         case 4:
761                                 audio_in_flush(input);
762                                 break;
763                         case 5:
764                                 audio_in_unprepare(input);
765                                 break;
766                         case 6:
767                                 audio_in_prepare(input);
768                                 for  (j = 0; j < 10; j++)
769                                         audio_in_read(input, buf, buffer_size);
770                                 break;
771                         case 7:
772                                 audio_in_get_buffer_size(input, &buffer_size);
773                                 audio_in_get_sample_rate(input, &rate);
774                                 audio_in_get_channel(input, &ch);
775                                 audio_in_get_sample_type(input, &type);
776                                 break;
777                         default:
778                                 break;
779                 }
780                 if ((i % (TEST_COUNT/10)) == 0)
781                         printf("audio_in: %x thread. count(%d/%d)\n", (int)pthread_self(), i, TEST_COUNT);
782         }
783         audio_in_unprepare(input);
784
785 EXIT:
786         if (buf) {
787                 free(buf);
788                 buf = NULL;
789         }
790
791         pthread_exit(0);
792 }
793
794 static void *thread_stress_test_audio_out(void *data)
795 {
796         int i, j;
797         int rate;
798         char *buf;
799         int buffer_size;
800         audio_channel_e ch;
801         audio_sample_type_e type;
802         unsigned int seed = (unsigned int)time(NULL);
803
804         audio_out_h output = (audio_out_h)data;
805
806         srand(time(NULL));
807
808         audio_out_get_buffer_size(output, &buffer_size);
809
810         buf = (char *)malloc(buffer_size);
811         if (buf == NULL) {
812                 printf("malloc failed\n");
813                 goto EXIT;
814         }
815
816         audio_out_prepare(output);
817         for (i = 0; i < TEST_COUNT; i++) {
818                 switch (rand_r(&seed) % 9) {
819                         case 0:
820                                 audio_out_prepare(output);
821                                 break;
822                         case 1:
823                                 audio_out_write(output, buf, buffer_size);
824                                 break;
825                         case 2:
826                                 audio_out_pause(output);
827                                 break;
828                         case 3:
829                                 audio_out_resume(output);
830                                 break;
831                         case 4:
832                                 audio_out_drain(output);
833                                 break;
834                         case 5:
835                                 audio_out_flush(output);
836                                 break;
837                         case 6:
838                                 audio_out_write(output, buf, buffer_size);
839                                 break;
840                         case 7:
841                                 audio_out_prepare(output);
842                                 for  (j = 0; j < 10; j++)
843                                         audio_out_write(output, buf, buffer_size);
844                                 break;
845                         case 8:
846                                 audio_out_get_buffer_size(output, &buffer_size);
847                                 audio_out_get_sample_rate(output, &rate);
848                                 audio_out_get_channel(output, &ch);
849                                 audio_out_get_sample_type(output, &type);
850                                 break;
851                         default:
852                                 break;
853                 }
854                 if ((i % (TEST_COUNT/10)) == 0)
855                         printf("audio_out: %x thread. count(%d/%d)\n", (int)pthread_self(), i, TEST_COUNT);
856         }
857         audio_out_unprepare(output);
858
859 EXIT:
860         if (buf)
861                 free(buf);
862
863         pthread_exit(0);
864 }
865
866 int audio_io_stress_test()
867 {
868         int i;
869         int ret;
870         audio_out_h output[2];
871         audio_in_h input;
872
873         int status;
874         pthread_t t[THREAD_MAX];
875
876         void out_stream_cb(audio_out_h handle, size_t nbytes, void *user_data) {
877                 char * buf = (char *)malloc(nbytes);
878                 if (!buf) {
879                         printf("malloc(%zu) failed\n", nbytes);
880                         return;
881                 }
882                 audio_out_write(handle, buf, nbytes);
883                 free(buf);
884                 return;
885         }
886
887         void in_stream_cb(audio_in_h handle, size_t nbytes, void *user_data) {
888                 void* buf = NULL;
889                 unsigned int size = nbytes;
890
891                 audio_in_peek(handle, (const void **)buf, &size);
892                 audio_in_drop(handle);
893                 return;
894         }
895
896         void state_changed_cb(audio_out_h handle, audio_io_state_e previous, audio_io_state_e current, bool by_policy, void *user_data) {
897                 return;
898         }
899
900         /* audio_out sync */
901         ret = audio_out_create_new(48000, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &output[0]);
902         if (ret != AUDIO_IO_ERROR_NONE) {
903                 printf("audio_out_create_new failed. \n");
904                 return 0;
905         }
906         audio_out_set_state_changed_cb(output[0], state_changed_cb, NULL);
907
908         /* audio_out async */
909         ret = audio_out_create_new(48000, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &output[1]);
910         if (ret != AUDIO_IO_ERROR_NONE) {
911                 printf("audio_out_create_new failed. \n");
912                 return 0;
913         }
914         audio_out_set_stream_cb(output[1], out_stream_cb, NULL);
915         audio_out_set_state_changed_cb(output[1], state_changed_cb, NULL);
916
917         /* audio_in */
918         ret = audio_in_create(44100, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &input);
919         if (ret != AUDIO_IO_ERROR_NONE) {
920                 printf("audio in create error = 0x%x\n", ret);
921                 return -1;
922         }
923         audio_in_set_stream_cb(input, in_stream_cb, NULL);
924
925         printf("audio out sync test\n");
926         for (i = 0; i < THREAD_MAX; i++)
927                 pthread_create(&t[i], NULL, thread_stress_test_audio_out, output[0]);
928
929         for (i = 0; i < THREAD_MAX; i++) {
930                 pthread_join(t[i], (void**)&status);
931                 printf("thread %d finished\n", i);
932         }
933
934         printf("audio out async test\n");
935         for (i = 0; i < THREAD_MAX; i++)
936                 pthread_create(&t[i], NULL, thread_stress_test_audio_out, output[1]);
937
938         for (i = 0; i < THREAD_MAX; i++) {
939                 pthread_join(t[i], (void**)&status);
940                 printf("thread %d finished\n", i);
941         }
942
943         printf("audio in test\n");
944         for (i = 0; i < THREAD_MAX; i++)
945                 pthread_create(&t[i], NULL, thread_stress_test_audio_in, input);
946
947         for (i = 0; i < THREAD_MAX; i++) {
948                 pthread_join(t[i], (void**)&status);
949                 printf("thread %d finished\n", i);
950         }
951
952         audio_out_destroy(output[0]);
953         audio_out_destroy(output[1]);
954         audio_in_destroy(input);
955
956         printf("stress test end\n");
957
958         return 0;
959 }
960
961 int main(int argc, char **argv)
962 {
963         setbuf(stdout, NULL);
964
965         if (argc == 2 && !strcmp(argv[1], "loopback")) {
966                 _direct_loopback();
967         } else if (argc == 3 && !strcmp(argv[1], "async")) {
968                 audio_io_async_test(atoi(argv[2]));
969         } else if (argc == 2 && !strcmp(argv[1], "stress")) {
970                 audio_io_stress_test();
971         } else if (argc == 4) {
972                 int channel_idx = atoi(argv[3]);
973                 if (channel_idx < 0 || channel_idx > 8) {
974                         printf("Invalid channel\n");
975                         return 0;
976                 }
977                 printf("run with [%s][%s][%s]\n", argv[1], argv[2], argv[3]);
978                 _record_and_play(atoi(argv[1]), atoi(argv[2]), channel_idx);
979         } else if (argc == 6) {
980                 if (strcmp(argv[1], "play") == 0)
981                         _play_file_sample_sync(argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
982                 else if (strcmp(argv[1], "playasync") == 0)
983                         _play_file_sample_async(argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
984         } else {
985                 printf("- Usages :\n");
986                 printf("- # audio_io_test loopback\n");
987                 printf("- # audio_io_test stress\n");
988                 printf("- # audio_io_test [length to read] [number of iteration] [channels]\n");
989                 printf("- # audio_io_test async [write(1) | read(2)]\n");
990                 printf("- # audio_io_test play [filename] [sample rate] [channels] [type(0:U8,1:S16LE,2:S24LE,3:S24_32LE)]\n");
991                 printf("- # audio_io_test playasync [filename] [sample rate] [channels] [type(0:U8,1:S16LE,2:S24LE,3:S24_32LE)]\n");
992         }
993         return 0;
994 }