test: Add loopback functionality
[platform/core/api/audio-io.git] / test / audio_io_process_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 <assert.h>
22 #include <sound_manager.h>
23 #include <audio_io.h>
24
25 #define DEFAULT_CHANNELS        1
26
27 static int arg_samplerate;
28 static audio_channel_e arg_channels;
29 static audio_sample_type_e arg_format;
30
31 static bool arg_ref_dev_is_set;
32 static int arg_ref_dev;
33 static bool arg_method_is_set;
34 static int arg_method;
35 static bool arg_reference_method_is_set;
36 static int arg_reference_method;
37
38 static char arg_filename[256];
39
40 static int ch_table[] = { 0, AUDIO_CHANNEL_MONO, AUDIO_CHANNEL_STEREO,
41                           AUDIO_CHANNEL_MULTI_3, AUDIO_CHANNEL_MULTI_4, AUDIO_CHANNEL_MULTI_5,
42                           AUDIO_CHANNEL_MULTI_6, AUDIO_CHANNEL_MULTI_7, AUDIO_CHANNEL_MULTI_8,
43                           AUDIO_CHANNEL_MULTI_9, AUDIO_CHANNEL_MULTI_10, AUDIO_CHANNEL_MULTI_11,
44                           AUDIO_CHANNEL_MULTI_12, AUDIO_CHANNEL_MULTI_13, AUDIO_CHANNEL_MULTI_14,
45                           AUDIO_CHANNEL_MULTI_15, AUDIO_CHANNEL_MULTI_16 };
46
47 static void record()
48 {
49         int ret, size;
50         sound_stream_info_h stream_info;
51         audio_in_h input = NULL;
52         FILE *fp = NULL;
53         char *buffer = NULL;
54
55         sound_device_list_h device_list = NULL;
56         sound_device_h device;
57         bool found = false;
58         int id;
59
60         ret = audio_in_create(arg_samplerate, ch_table[arg_channels], AUDIO_SAMPLE_TYPE_S16_LE, &input);
61         if (ret != AUDIO_IO_ERROR_NONE) {
62                 fprintf(stderr, "audio in create error = 0x%x\n", ret);
63                 goto out;
64         }
65
66         ret = sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &stream_info);
67         if (ret) {
68                 fprintf(stderr, "fail to sound_manager_create_stream_information(), ret(0x%x)\n", ret);
69                 goto out;
70         }
71
72         if (arg_reference_method_is_set) {
73                 if (sound_manager_get_device_list(SOUND_DEVICE_ALL_MASK, &device_list) != SOUND_MANAGER_ERROR_NONE) {
74                         fprintf(stderr, "fail to get device list");
75                         goto out;
76                 }
77
78                 while (sound_manager_get_next_device(device_list, &device) == SOUND_MANAGER_ERROR_NONE) {
79                         if (sound_manager_get_device_id(device, &id) != SOUND_MANAGER_ERROR_NONE)
80                                 goto out;
81
82                         if (arg_ref_dev == id) {
83                                 found = true;
84                                 break;
85                         }
86                 }
87
88                 if (!found) {
89                         fprintf(stderr, "Failed to find reference device");
90                         goto out;
91                 }
92
93                 ret = sound_manager_set_effect_method_with_reference(stream_info, arg_reference_method, device);
94                 if (ret != SOUND_MANAGER_ERROR_NONE) {
95                         fprintf(stderr, "fail to sound_manager_set_audio_effect_reference_device(), ret(0x%x)\n", ret);
96                         goto out;
97                 }
98
99                 /* verify */
100                 {
101                         int device_id;
102                         int id;
103                         sound_effect_method_with_reference_e method;
104
105                         ret = sound_manager_get_effect_method_with_reference(stream_info, &method, &device_id);
106                         if (ret != SOUND_MANAGER_ERROR_NONE) {
107                                 fprintf(stderr, "fail to sound_manager_get_audio_effect_reference_device(), ret(0x%x)\n", ret);
108                                 goto out;
109                         }
110
111                         if (sound_manager_get_device_id(device, &id)) {
112                                 fprintf(stderr, "fail to sound_manager_device_id\n");
113                                 goto out;
114                         }
115
116                         if (device_id != id || method != arg_reference_method) {
117                                 fprintf(stderr, "fail to verify aec args\n");
118                                 goto out;
119                         }
120                 }
121         }
122
123         if (arg_method_is_set) {
124                 ret = sound_manager_set_effect_method(stream_info, arg_method);
125                 if (ret != SOUND_MANAGER_ERROR_NONE) {
126                         fprintf(stderr, "failed to sound_manager_set_audio_effect_method(), ret(0x%x)\n", ret);
127                         goto out;
128                 }
129
130                 /* verify */
131                 {
132                         int method;
133
134                         ret = sound_manager_get_effect_method(stream_info, &method);
135                         if (ret != SOUND_MANAGER_ERROR_NONE) {
136                                 fprintf(stderr, "fail to sound_manager_get_audio_effect_reference_device(), ret(0x%x)\n", ret);
137                                 goto out;
138                         }
139
140                         if (method != arg_method) {
141                                 fprintf(stderr, "fail to verify method args\n");
142                                 goto out;
143                         }
144                 }
145         }
146
147         ret = audio_in_set_sound_stream_info(input, stream_info);
148         if (ret != AUDIO_IO_ERROR_NONE) {
149                 fprintf(stderr, "fail to audio_in_set_sound_stream_info(), ret(0x%x)\n", ret);
150                 goto out;
151         }
152
153         ret = audio_in_prepare(input);
154         if (ret != AUDIO_IO_ERROR_NONE) {
155                 fprintf(stderr, "ERROR, prepare\n");
156                 goto out;
157         }
158
159         ret = audio_in_get_buffer_size(input, &size);
160         if (ret != AUDIO_IO_ERROR_NONE) {
161                 fprintf(stderr, "ERROR, get_buffer_size\n");
162                 goto out;
163         }
164
165         if (strcmp(arg_filename, ""))
166                 fp = fopen(arg_filename, "wb");
167         else
168                 fp = fdopen(dup(STDOUT_FILENO), "wb");
169
170         if (!fp) {
171                 fprintf(stderr, "failed to open file(%s)", arg_filename);
172                 goto out;
173         }
174
175         buffer = alloca(size);
176
177         while (1) {
178                 ret = audio_in_read(input, (void *)buffer, size);
179                 if (ret <= 0) {
180                         fprintf(stderr, "FAIL, size=%d, ret=0x%x\n", size, ret);
181                         goto out;
182                 }
183
184                 if (size != ret) {
185                         fprintf(stderr, "Failed to read, size=%d, ret=%d\n", size, ret);
186                         goto out;
187                 }
188
189                 fwrite(buffer, sizeof(short), size/sizeof(short), fp);
190         }
191
192 out:
193         if (fp)
194                 fclose(fp);
195
196         if (input) {
197                 audio_in_unprepare(input);
198                 audio_in_destroy(input);
199         }
200
201         if (device_list)
202                 if (sound_manager_free_device_list(device_list) != SOUND_MANAGER_ERROR_NONE)
203                         fprintf(stderr, "fail to free device list\n");
204
205         return;
206 }
207
208 static void playback_stdin()
209 {
210         int ret, size;
211         char *buffer;
212         audio_out_h output;
213         FILE *fp;
214
215         ret = audio_out_create_new(arg_samplerate, ch_table[arg_channels], AUDIO_SAMPLE_TYPE_S16_LE, &output);
216         assert(ret == AUDIO_IO_ERROR_NONE);
217
218         fp = fdopen(dup(STDIN_FILENO), "r");
219         assert(fp);
220
221         ret = audio_out_get_buffer_size(output, &size);
222         assert(ret == AUDIO_IO_ERROR_NONE);
223
224         buffer = (char *)malloc(size);
225         assert(buffer);
226
227         ret = audio_out_prepare(output);
228         assert(ret == AUDIO_IO_ERROR_NONE);
229
230         while (1) {
231                 if (fread(buffer, size, 1, fp) <= 0)
232                         assert(0);
233
234                 ret = audio_out_write(output, (void *)buffer, size);
235                 assert(ret > 0);
236         }
237
238         free(buffer);
239         fclose(fp);
240         audio_out_destroy(output);
241 }
242
243 static void print_usage()
244 {
245         fprintf(stderr, "Usage\n\n");
246         fprintf(stderr, "audio_io_process_test -r [samplerate] -c [channels] -a [reference_method] -d [reference_device_id] -m [methods] -o [output filename]\n");
247         fprintf(stderr, "e.g) audio_io_process_test -r 48000 -d 1 -m 0x0001 -a 0x0004 -d 1 -o filename (method:webrtc and voicecall)\n");
248
249         fprintf(stderr, "\n");
250         fprintf(stderr, "Please refer to the optional arguments as following.\n\n");
251         fprintf(stderr, "Options\n");
252         fprintf(stderr, "-a\t\taudio-effects with reference device_id like AEC\n");
253         fprintf(stderr, "\t\te.g) refcopy:0x0001, aec-speex:0x0002, aec-webrtc:0x0004\n");
254
255         fprintf(stderr, "-m\t\taudio-effects like noise-suppression\n");
256         fprintf(stderr, "\t\te.g) rnnoise:0x0001, agc-speex:0x0002, pse:0x0200, doorbel:0x0100\n");
257 }
258
259 int main(int argc, char **argv)
260 {
261         setbuf(stdout, NULL);
262         const char *optstring = "r:c:f:m:o:d:a:p";
263         int option;
264         bool playback = false;
265
266         arg_channels = DEFAULT_CHANNELS;
267         arg_format = AUDIO_SAMPLE_TYPE_S16_LE;
268
269         if (argc == 1) {
270                 print_usage();
271                 return 0;
272         }
273
274         fprintf(stderr, "===== Arguments information =====\n");
275         while (-1 != (option = getopt(argc, argv, optstring))) {
276                 switch (option) {
277                         case 'r': /* rate */
278                                 arg_samplerate = atoi(optarg);
279                                 fprintf(stderr, "Samplerate : %d\n", arg_samplerate);
280                                 break;
281                         case 'a': /* sound_effect_method_with_reference_e */
282                                 arg_reference_method_is_set = true;
283                                 arg_reference_method = (int)strtol(optarg, NULL, 16);
284                                 fprintf(stderr, "reference method : 0x%x, optarg(%s)\n",
285                                                 arg_reference_method, optarg);
286                                 break;
287                         case 'd': /* reference device */
288                                 arg_ref_dev_is_set = true;
289                                 arg_ref_dev = atoi(optarg);
290                                 fprintf(stderr, "reference device : %d\n", arg_ref_dev);
291                                 break;
292                         case 'm': /* method */
293                                 arg_method_is_set = true;
294                                 arg_method = (int)strtol(optarg, NULL, 16);
295                                 fprintf(stderr, "method : 0x%x, optarg(%s)\n", arg_method, optarg);
296                                 break;
297                         case 'o': /* output file */
298                                 snprintf(arg_filename, sizeof(arg_filename), "%s", optarg);
299                                 fprintf(stderr, "Output filename : %s\n", arg_filename);
300                                 break;
301                         case 'c': /* channels */
302                                 arg_channels = atoi(optarg);
303                                 fprintf(stderr, "Channels : %d\n", arg_channels);
304                                 if (arg_channels < 1 || arg_channels > 16) {
305                                         fprintf(stderr, "Invalid channels : %d\n", arg_channels);
306                                         return -1;
307                                 }
308                                 break;
309                         case 'f': /* format */
310                                 arg_format = atoi(optarg);
311                                 fprintf(stderr, "Format : %d\n", arg_format);
312                                 break;
313                         case 'p': /* playback for loopback test */
314                                 fprintf(stderr, "Playback : Yes\n");
315                                 playback = true;
316                                 break;
317                         case 'h':
318                         default:
319                                 print_usage();
320                                 return 0;
321                 }
322         }
323         fprintf(stderr, "=================================\n");
324
325         if (playback) {
326                 playback_stdin();
327         }
328
329         if ((arg_reference_method_is_set && !arg_ref_dev_is_set) ||
330                         (!arg_reference_method_is_set && arg_ref_dev_is_set)) {
331                 fprintf(stderr, "need to set reference devices and method both\n");
332                 return -1;
333         }
334
335         record();
336         fprintf(stderr, "END\n");
337
338         return 0;
339 }