2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <sound_manager.h>
26 #define M_PI (3.14159265)
29 #define TABLE_SIZE (200)
31 float sine[TABLE_SIZE];
37 static int ch_table[3] = { 0, AUDIO_CHANNEL_MONO, AUDIO_CHANNEL_STEREO };
38 static char *state_str[] = { "IDLE", "RUNNING", "PAUSED" };
40 static void _audio_in_state_cb(audio_in_h handle, audio_io_state_e previous, audio_io_state_e current,
41 bool by_policy, void *user_data)
43 printf(">>> _audio_in_state_cb() : handle(%p), (%d,%s) => (%d,%s), by_policy(%d), user_data(%p)\n",
44 handle, previous, state_str[previous], current, state_str[current], by_policy, user_data);
47 static void _audio_out_state_cb(audio_out_h handle, audio_io_state_e previous, audio_io_state_e current,
48 bool by_policy, void *user_data)
50 printf(">>> _audio_out_state_cb() : handle(%p), (%d,%s) => (%d,%s), by_policy(%d), user_data(%p)\n",
51 handle, previous, state_str[previous], current, state_str[current], by_policy, user_data);
54 static void _play_file(char *file, int length, int num, int ch)
58 int total_length = length * num;
60 FILE *fp = fopen(file, "r");
62 printf("fopen failed\n");
66 char *buf = malloc(total_length);
68 printf("malloc failed\n");
73 printf("# start to play [%s][%d][%d]\n", file, total_length, ch);
74 printf(" > create\n");
75 audio_out_create_new(44100, ch_table[ch], AUDIO_SAMPLE_TYPE_S16_LE, &output);
76 if (fread(buf, 1, total_length, fp) != total_length)
77 printf("error!!!!\n");
79 ret = audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
80 if (ret != AUDIO_IO_ERROR_NONE) {
81 printf("audio_out_set_state_changed_cb failed. \n");
84 printf(" > prepare\n");
85 audio_out_prepare(output);
88 for (i = 0; i < num; i++) {
89 printf("### write = (%d/%d) ============== \n", i, num);
90 audio_out_write(output, pbuf, length);
94 printf(" < unprepare\n");
95 audio_out_drain(output);
96 audio_out_unprepare(output);
98 printf(" < destroy\n");
99 audio_out_destroy(output);
104 printf("# play done\n");
107 #define DUMP_FILE "/root/test.raw"
111 static void _audio_out_stream_cb(audio_out_h handle, size_t nbytes, void *user_data)
118 printf("FILE is NULL\n");
122 buf = (char *)malloc(nbytes);
124 read_bytes = fread(buf, 1, nbytes, fp);
126 written = audio_out_write(handle, buf, read_bytes);
127 printf("written : %6d/%6d (requested %zu)\n", written, read_bytes, nbytes);
129 if (read_bytes < nbytes) {
137 static void _play_file_sample_async(char *file, int frequency, int ch, int type)
142 if (ch < 0 || ch > 2)
145 fp = fopen(file, "r");
147 printf("open failed\n");
150 printf("start to play [%s] of size [%d] with [%d][%d][%d]\n", file, file_size, frequency, ch, type);
151 audio_out_create_new(frequency, ch_table[ch], AUDIO_SAMPLE_TYPE_U8 + type, &output);
153 audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
154 audio_out_set_stream_cb(output, _audio_out_stream_cb, fp);
155 audio_out_prepare(output);
158 usleep(10000); /* 10ms */
161 printf("FINISHED!!!\n");
163 audio_out_unprepare(output);
164 audio_out_destroy(output);
166 printf("play done\n");
169 static void _play_file_sample_sync(char *file, int frequency, int ch, int type)
179 if (ch < 0 || ch > 2)
182 fp = fopen(file, "r");
184 printf("open failed\n");
188 fseek(fp, 0, SEEK_END);
189 file_size = ftell(fp);
190 fseek(fp, 0, SEEK_SET);
192 printf("Play [%s] of size [%d] with [%d][%d][%d]\n", file, file_size, frequency, ch, type);
193 audio_out_create_new(frequency, ch_table[ch], AUDIO_SAMPLE_TYPE_U8 + type, &output);
195 audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
196 audio_out_prepare(output);
198 audio_out_get_buffer_size(output, &buffer_size);
199 buf = (char *)malloc(buffer_size);
201 printf("malloc failed\n");
205 printf("Press any key to continue....\n");
207 printf("Start to read[%d] from file and write : \n", buffer_size);
209 while (file_size > 0) {
210 read_bytes = fread(buf, 1, buffer_size, fp);
219 audio_out_write(output, buf, read_bytes);
220 file_size = file_size - read_bytes;
225 audio_out_unprepare(output);
226 audio_out_destroy(output);
233 printf("\nEOS!!!! Play done\n");
236 static int _record_and_play(int length, int num, int ch)
239 audio_in_h input = NULL;
243 ret = audio_in_create(44100, ch_table[ch], AUDIO_SAMPLE_TYPE_S16_LE, &input);
244 if (ret != AUDIO_IO_ERROR_NONE) {
245 printf("audio in create error = 0x%x\n", ret);
249 ret = audio_in_set_state_changed_cb(input, _audio_in_state_cb, NULL);
250 if (ret != AUDIO_IO_ERROR_NONE) {
251 printf("audio_in_set_state_changed_cb failed. \n");
255 ret = audio_in_prepare(input);
256 if (ret != AUDIO_IO_ERROR_NONE) {
257 printf("ERROR, prepare\n");
261 fp = fopen(DUMP_FILE, "wb+");
263 printf("ERROR, file open failed\n");
267 ret = audio_in_get_buffer_size(input, &size);
268 if (ret != AUDIO_IO_ERROR_NONE) {
269 printf("ERROR, prepare\n");
274 buffer = alloca(size);
276 for (i = 0; i < num; i++) {
277 printf("### read = (%d/%d) ============== ", i, num);
278 if ((ret = audio_in_read(input, (void *)buffer, size)) > AUDIO_IO_ERROR_NONE) {
279 fwrite(buffer, size, sizeof(char), fp);
280 printf("PASS, size=%d, ret=0x%x\n", size, ret);
282 printf("FAIL, size=%d, ret=0x%x\n", size, ret);
288 audio_in_unprepare(input);
289 audio_in_destroy(input);
291 _play_file(DUMP_FILE, length, num, ch);
296 audio_in_destroy(input);
302 static int _direct_loopback()
305 audio_in_h input = NULL;
306 audio_out_h output = NULL;
310 ret = audio_in_create(16000, AUDIO_CHANNEL_MONO, AUDIO_SAMPLE_TYPE_S16_LE, &input);
311 if (ret != AUDIO_IO_ERROR_NONE) {
312 printf("audio_in_create_ex failed. \n");
315 ret = audio_out_create_new(16000, AUDIO_CHANNEL_MONO, AUDIO_SAMPLE_TYPE_S16_LE, &output);
316 if (ret != AUDIO_IO_ERROR_NONE) {
317 printf("audio_out_create_new failed. \n");
321 ret = audio_in_prepare(input);
323 printf("audio_in_prepare failed, err(0x%x)\n", ret);
327 ret = audio_in_get_buffer_size(input, &size);
328 if (ret != AUDIO_IO_ERROR_NONE) {
329 printf("audio_in_get_buffer_size failed, err(0x%x)\n", ret);
333 printf("size(%d)\n", size);
334 buffer = alloca(size);
336 ret = audio_out_prepare(output);
338 printf("audio_out_prepare failed, err(0x%x)\n", ret);
342 if (buffer == NULL) {
343 printf("buffer is null\n");
348 printf("Start to loopback(read/write) with [16kHz/MONO/S16LE]!!!\n");
351 ret = audio_in_read(input, (void *)buffer, size);
352 if (ret > AUDIO_IO_ERROR_NONE) {
353 ret = audio_out_write(output, buffer, size);
354 if (ret > AUDIO_IO_ERROR_NONE) {
364 printf("audio read success, write failed. buffer(%p), size(%d)\n", buffer, size);
367 printf("audio read/write failed. buffer(%p), size(%d)\n", buffer, size);
374 audio_in_destroy(input);
376 audio_out_destroy(output);
387 sound_stream_info_h g_stream_info_read_h = NULL;
388 sound_stream_info_h g_stream_info_write_h = NULL;
390 static void _focus_cb(sound_stream_info_h stream_info, sound_stream_focus_mask_e focus_mask,
391 sound_stream_focus_state_e focus_state,
392 sound_stream_focus_change_reason_e reason_for_change, int sound_behavior,
393 const char *additional_info, void *user_data)
395 printf("*** focus_callback_read is called, stream_info(%p, read(%p)/write(%p)) ***\n",
396 stream_info, g_stream_info_read_h, g_stream_info_write_h);
397 printf(" - reason_for_change(%d), additional_info(%s), user_data(%p)\n",
398 reason_for_change, additional_info, user_data);
399 printf(" - focus_state is :%d \n", focus_state);
404 static void _audio_io_stream_read_cb(audio_in_h handle, size_t nbytes, void *user_data)
406 const void *buffer = NULL;
407 unsigned int len = (unsigned int)nbytes;
412 audio_in_peek(handle, &buffer, &len);
414 fwrite(buffer, sizeof(char), len, fp_w);
415 audio_in_drop(handle);
418 static void _audio_io_stream_write_cb(audio_out_h handle, size_t nbytes, void *user_data)
420 short *buffer = NULL;
426 buffer = (short *)malloc(nbytes);
427 if (buffer == NULL) {
428 printf("malloc failed\n");
431 memset(buffer, 0, nbytes);
433 for (i = 0; i < nbytes / 2; i += 2) {
434 buffer[i] = (short)32768 *test_wav.sine[test_wav.left_channel]; /* left */
435 buffer[i + 1] = (short)32768 *test_wav.sine[test_wav.right_channel]; /* right */
436 test_wav.left_channel += 1;
437 if (test_wav.left_channel >= TABLE_SIZE)
438 test_wav.left_channel -= TABLE_SIZE;
439 test_wav.right_channel += 3;
440 if (test_wav.right_channel >= TABLE_SIZE)
441 test_wav.right_channel -= TABLE_SIZE;
444 audio_out_write(handle, buffer, nbytes);
449 int _convert_cmd_and_run(char cmd, int mode)
455 ret = audio_out_prepare(output);
457 ret = audio_in_prepare(input);
461 ret = audio_out_unprepare(output);
463 ret = audio_in_unprepare(input);
467 ret = audio_out_pause(output);
469 ret = audio_in_pause(input);
473 ret = audio_out_resume(output);
475 ret = audio_in_resume(input);
479 ret = audio_out_drain(output);
483 ret = audio_out_flush(output);
485 ret = audio_in_flush(input);
488 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _focus_cb, NULL, &g_stream_info_write_h);
490 printf("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
502 int audio_io_async_test(int mode)
511 int write_mode = (mode & 0x01);
512 int read_mode = (mode & 0x02);
514 sound_stream_focus_state_e playback_focus_state;
515 sound_stream_focus_state_e recording_focus_state;
517 if ((write_mode == 0) && (read_mode == 0)) {
518 printf("not vaild mode.\n");
524 printf("audio_in_create\n");
525 ret = audio_in_create(44100, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &input);
526 if (ret != AUDIO_IO_ERROR_NONE) {
527 printf("audio_in_create_ex failed. \n");
530 printf("audio_in_create success!!! [%p]\n", input);
532 ret = audio_in_set_stream_cb(input, _audio_io_stream_read_cb, NULL);
533 if (ret != AUDIO_IO_ERROR_NONE) {
534 printf("audio_in_set_stream_cb failed. \n");
537 printf("audio_in_set_stream_cb success!!! [%p]\n", input);
539 ret = audio_in_set_state_changed_cb(input, _audio_in_state_cb, NULL);
540 if (ret != AUDIO_IO_ERROR_NONE) {
541 printf("audio_out_set_state_changed_cb failed. \n");
544 printf("audio_out_set_state_changed_cb success!!! [%p]\n", input);
546 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _focus_cb, NULL, &g_stream_info_read_h);
548 printf("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
551 ret = audio_in_set_sound_stream_info(input, g_stream_info_read_h);
553 printf("fail to audio_in_set_sound_stream_info(), ret(0x%x)\n", ret);
555 ret = sound_manager_acquire_focus(g_stream_info_read_h, SOUND_STREAM_FOCUS_FOR_RECORDING, SOUND_BEHAVIOR_NONE, NULL);
557 printf("fail to sound_manager_acquire_focus() for RECORDING, ret(0x%x)\n", ret);
561 fp_w = fopen("/tmp/pcm_w.raw", "w");
565 printf("before audio_out_create_new\n");
568 printf("audio_out_create_new\n");
569 ret = audio_out_create_new(44100, AUDIO_CHANNEL_STEREO, AUDIO_SAMPLE_TYPE_S16_LE, &output);
570 if (ret != AUDIO_IO_ERROR_NONE) {
571 printf("audio_out_create_new failed. \n");
574 printf("audio_out_create_new success!!! [%p]\n", output);
576 ret = audio_out_set_stream_cb(output, _audio_io_stream_write_cb, NULL);
577 if (ret != AUDIO_IO_ERROR_NONE) {
578 printf("audio_out_set_stream_cb failed. \n");
581 printf("audio_out_set_stream_cb success!!! [%p]\n", output);
583 ret = audio_out_set_state_changed_cb(output, _audio_out_state_cb, NULL);
584 if (ret != AUDIO_IO_ERROR_NONE) {
585 printf("audio_out_set_state_changed_cb failed. \n");
588 printf("audio_out_set_state_changed_cb success!!! [%p]\n", output);
590 ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, _focus_cb, NULL, &g_stream_info_write_h);
592 printf("fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
596 ret = audio_out_set_sound_stream_info(output, g_stream_info_write_h);
598 printf("fail to audio_out_set_sound_stream_info(), ret(0x%x)\n", ret);
600 ret = sound_manager_acquire_focus(g_stream_info_write_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
602 printf("fail to sound_manager_acquire_focus() for PLAYBACK, ret(0x%x)\n", ret);
606 /* generate wave data */
607 for (i = 0; i < TABLE_SIZE; i++)
608 test_wav.sine[i] = 0.9 * (float)sin(((double)i / (double)TABLE_SIZE) * M_PI * 2.);
609 test_wav.left_channel = test_wav.right_channel = 0;
613 printf("before audio_in_prepare\n");
615 printf("audio_in_prepare\n");
616 ret = audio_in_prepare(input);
618 printf("audio_in_prepare failed, err(0x%x)\n", ret);
619 audio_in_destroy(input);
622 ret = audio_in_get_buffer_size(input, &size);
623 if (ret != AUDIO_IO_ERROR_NONE) {
624 printf("audio_in_get_buffer_size failed, err(0x%x)\n", ret);
627 printf("size(%d)\n", size);
628 buffer = alloca(size);
632 if (buffer == NULL) {
633 printf("buffer is null\n");
639 printf("before audio_out_prepare\n");
641 printf("audio_out_prepare\n");
642 ret = audio_out_prepare(output);
644 printf("audio_out_prepare failed, err(0x%x)\n", ret);
645 audio_out_destroy(output);
651 printf("command(q:quit) : ");
658 cmd_ret = _convert_cmd_and_run(cmd, mode);
659 printf(" - result code : %d\n", cmd_ret);
660 } while (cmd != 'q');
665 printf("audio_in_unprepare\n");
666 audio_in_unprepare(input);
667 printf("audio_in_destroy\n");
668 audio_in_destroy(input);
677 if (g_stream_info_read_h) {
678 ret = sound_manager_get_focus_state(g_stream_info_read_h, NULL, &recording_focus_state);
679 if (recording_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
680 ret = sound_manager_release_focus(g_stream_info_read_h, SOUND_STREAM_FOCUS_FOR_RECORDING, SOUND_BEHAVIOR_NONE, NULL);
682 printf("fail to sound_manager_release_focus() for recording, ret(0x%x)\n", ret);
684 ret = sound_manager_destroy_stream_information(g_stream_info_read_h);
686 printf("fail to sound_manager_destroy_stream_information(), ret(0x%x)\n", ret);
687 g_stream_info_read_h = NULL;
693 printf("audio_out_unprepare\n");
694 audio_out_unprepare(output);
695 printf("audio_out_destroy\n");
696 audio_out_destroy(output);
699 if (g_stream_info_write_h) {
700 ret = sound_manager_get_focus_state(g_stream_info_write_h, &playback_focus_state, NULL);
701 if (playback_focus_state == SOUND_STREAM_FOCUS_STATE_ACQUIRED) {
702 ret = sound_manager_release_focus(g_stream_info_write_h, SOUND_STREAM_FOCUS_FOR_PLAYBACK, SOUND_BEHAVIOR_NONE, NULL);
704 printf("fail to sound_manager_release_focus() for playback, ret(0x%x)\n", ret);
706 ret = sound_manager_destroy_stream_information(g_stream_info_write_h);
708 printf("fail to sound_manager_destroy_stream_information(), ret(0x%x)\n", ret);
709 g_stream_info_write_h = NULL;
716 int main(int argc, char **argv)
718 setbuf(stdout, NULL);
720 if (argc == 2 && !strcmp(argv[1], "loopback")) {
722 } else if (argc == 3 && !strcmp(argv[1], "async")) {
723 audio_io_async_test(atoi(argv[2]));
724 } else if (argc == 4) {
725 int channel_idx = atoi(argv[3]);
726 if (channel_idx < 0 || channel_idx > 2) {
727 printf("Invalid channel\n");
730 printf("run with [%s][%s][%s]\n", argv[1], argv[2], argv[3]);
731 _record_and_play(atoi(argv[1]), atoi(argv[2]), channel_idx);
732 } else if (argc == 6) {
733 if (strcmp(argv[1], "play") == 0)
734 _play_file_sample_sync(argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
735 else if (strcmp(argv[1], "playasync") == 0)
736 _play_file_sample_async(argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
738 printf("- Usages :\n");
739 printf("- # audio_io_test loopback\n");
740 printf("- # audio_io_test [length to read] [number of iteration] [channels]\n");
741 printf("- # audio_io_test async [write(1) | read(2)]\n");
742 printf("- # audio_io_test play [filename] [sample rate] [channels] [type(0:U8,1:S16LE,2:S24LE,3:S24_32LE)]\n");
743 printf("- # audio_io_test playasync [filename] [sample rate] [channels] [type(0:U8,1:S16LE,2:S24LE,3:S24_32LE)]\n");