1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <gtest/gtest.h>
8
9 extern "C" {
10
11 #include "a2dp-codecs.h"
12 #include "cras_audio_area.h"
13 #include "audio_thread.h"
14 #include "audio_thread_log.h"
15 #include "cras_bt_transport.h"
16 #include "cras_iodev.h"
17
18 #include "cras_a2dp_iodev.h"
19 }
20
21 #define FAKE_OBJECT_PATH "/fake/obj/path"
22
23 #define MAX_A2DP_ENCODE_CALLS 8
24 #define MAX_A2DP_WRITE_CALLS 4
25
26 static struct cras_bt_transport *fake_transport;
27 static cras_audio_format format;
28 static size_t cras_bt_device_append_iodev_called;
29 static size_t cras_bt_device_rm_iodev_called;
30 static size_t cras_iodev_add_node_called;
31 static size_t cras_iodev_rm_node_called;
32 static size_t cras_iodev_set_active_node_called;
33 static size_t cras_bt_transport_acquire_called;
34 static size_t cras_bt_transport_configuration_called;
35 static size_t cras_bt_transport_release_called;
36 static size_t init_a2dp_called;
37 static int init_a2dp_return_val;
38 static size_t destroy_a2dp_called;
39 static size_t drain_a2dp_called;
40 static size_t a2dp_block_size_called;
41 static size_t a2dp_queued_frames_val;
42 static size_t cras_iodev_free_format_called;
43 static size_t cras_iodev_free_resources_called;
44 static int pcm_buf_size_val[MAX_A2DP_ENCODE_CALLS];
45 static unsigned int a2dp_encode_processed_bytes_val[MAX_A2DP_ENCODE_CALLS];
46 static unsigned int a2dp_encode_index;
47 static int a2dp_write_return_val[MAX_A2DP_WRITE_CALLS];
48 static unsigned int a2dp_write_index;
49 static cras_audio_area *dummy_audio_area;
50 static thread_callback write_callback;
51 static void *write_callback_data;
52 static const char *fake_device_name = "fake device name";
53 static const char *cras_bt_device_name_ret;
54 static unsigned int cras_bt_transport_write_mtu_ret;
55
ResetStubData()56 void ResetStubData() {
57 cras_bt_device_append_iodev_called = 0;
58 cras_bt_device_rm_iodev_called = 0;
59 cras_iodev_add_node_called = 0;
60 cras_iodev_rm_node_called = 0;
61 cras_iodev_set_active_node_called = 0;
62 cras_bt_transport_acquire_called = 0;
63 cras_bt_transport_configuration_called = 0;
64 cras_bt_transport_release_called = 0;
65 init_a2dp_called = 0;
66 init_a2dp_return_val = 0;
67 destroy_a2dp_called = 0;
68 drain_a2dp_called = 0;
69 a2dp_block_size_called = 0;
70 a2dp_queued_frames_val = 0;
71 cras_iodev_free_format_called = 0;
72 cras_iodev_free_resources_called = 0;
73 memset(a2dp_encode_processed_bytes_val, 0,
74 sizeof(a2dp_encode_processed_bytes_val));
75 a2dp_encode_index = 0;
76 a2dp_write_index = 0;
77 cras_bt_transport_write_mtu_ret = 800;
78
79 fake_transport = reinterpret_cast<struct cras_bt_transport *>(0x123);
80
81 if (!dummy_audio_area) {
82 dummy_audio_area = (cras_audio_area*)calloc(1,
83 sizeof(*dummy_audio_area) + sizeof(cras_channel_area) * 2);
84 }
85
86 write_callback = NULL;
87 }
88
iodev_set_format(struct cras_iodev * iodev,struct cras_audio_format * fmt)89 int iodev_set_format(struct cras_iodev *iodev,
90 struct cras_audio_format *fmt)
91 {
92 fmt->format = SND_PCM_FORMAT_S16_LE;
93 fmt->num_channels = 2;
94 fmt->frame_rate = 44100;
95 iodev->format = fmt;
96 return 0;
97 }
98
99 namespace {
100
101 static struct timespec time_now;
102
TEST(A2dpIoInit,InitializeA2dpIodev)103 TEST(A2dpIoInit, InitializeA2dpIodev) {
104 struct cras_iodev *iodev;
105
106 atlog = (audio_thread_event_log *)calloc(1, sizeof(audio_thread_event_log));
107
108 ResetStubData();
109
110 cras_bt_device_name_ret = NULL;
111 iodev = a2dp_iodev_create(fake_transport);
112
113 ASSERT_NE(iodev, (void *)NULL);
114 ASSERT_EQ(iodev->direction, CRAS_STREAM_OUTPUT);
115 ASSERT_EQ(1, cras_bt_transport_configuration_called);
116 ASSERT_EQ(1, init_a2dp_called);
117 ASSERT_EQ(1, cras_bt_device_append_iodev_called);
118 ASSERT_EQ(1, cras_iodev_add_node_called);
119 ASSERT_EQ(1, cras_iodev_set_active_node_called);
120
121 /* Assert iodev name matches the object path when bt device doesn't
122 * have its readable name populated. */
123 ASSERT_STREQ(FAKE_OBJECT_PATH, iodev->info.name);
124
125 a2dp_iodev_destroy(iodev);
126
127 ASSERT_EQ(1, cras_bt_device_rm_iodev_called);
128 ASSERT_EQ(1, cras_iodev_rm_node_called);
129 ASSERT_EQ(1, destroy_a2dp_called);
130 ASSERT_EQ(1, cras_iodev_free_resources_called);
131
132 cras_bt_device_name_ret = fake_device_name;
133 /* Assert iodev name matches the bt device's name */
134 iodev = a2dp_iodev_create(fake_transport);
135 ASSERT_STREQ(fake_device_name, iodev->info.name);
136
137 a2dp_iodev_destroy(iodev);
138 }
139
TEST(A2dpIoInit,InitializeFail)140 TEST(A2dpIoInit, InitializeFail) {
141 struct cras_iodev *iodev;
142
143 ResetStubData();
144
145 init_a2dp_return_val = -1;
146 iodev = a2dp_iodev_create(fake_transport);
147
148 ASSERT_EQ(iodev, (void *)NULL);
149 ASSERT_EQ(1, cras_bt_transport_configuration_called);
150 ASSERT_EQ(1, init_a2dp_called);
151 ASSERT_EQ(0, cras_bt_device_append_iodev_called);
152 ASSERT_EQ(0, cras_iodev_add_node_called);
153 ASSERT_EQ(0, cras_iodev_set_active_node_called);
154 ASSERT_EQ(0, cras_iodev_rm_node_called);
155 }
156
TEST(A2dpIoInit,OpenIodev)157 TEST(A2dpIoInit, OpenIodev) {
158 struct cras_iodev *iodev;
159
160 ResetStubData();
161 iodev = a2dp_iodev_create(fake_transport);
162
163 iodev_set_format(iodev, &format);
164 iodev->open_dev(iodev);
165
166 ASSERT_EQ(1, cras_bt_transport_acquire_called);
167
168 iodev->close_dev(iodev);
169 ASSERT_EQ(1, cras_bt_transport_release_called);
170 ASSERT_EQ(1, drain_a2dp_called);
171 ASSERT_EQ(1, cras_iodev_free_format_called);
172
173 a2dp_iodev_destroy(iodev);
174 }
175
TEST(A2dpIoInit,GetPutBuffer)176 TEST(A2dpIoInit, GetPutBuffer) {
177 struct cras_iodev *iodev;
178 struct cras_audio_area *area1, *area2, *area3;
179 uint8_t *area1_buf;
180 unsigned frames;
181
182 ResetStubData();
183 iodev = a2dp_iodev_create(fake_transport);
184
185 iodev_set_format(iodev, &format);
186 iodev->open_dev(iodev);
187 ASSERT_NE(write_callback, (void *)NULL);
188
189 frames = 256;
190 iodev->get_buffer(iodev, &area1, &frames);
191 ASSERT_EQ(256, frames);
192 ASSERT_EQ(256, area1->frames);
193 area1_buf = area1->channels[0].buf;
194
195 /* Test 100 frames(400 bytes) put and all processed. */
196 a2dp_encode_processed_bytes_val[0] = 4096 * 4;
197 a2dp_encode_processed_bytes_val[1] = 400;
198 a2dp_write_index = 0;
199 a2dp_write_return_val[0] = -EAGAIN;
200 a2dp_write_return_val[1] = 400;
201 iodev->put_buffer(iodev, 100);
202 write_callback(write_callback_data);
203 // Start with 4k frames.
204 EXPECT_EQ(4096, pcm_buf_size_val[0]);
205 EXPECT_EQ(400, pcm_buf_size_val[1]);
206
207 iodev->get_buffer(iodev, &area2, &frames);
208 ASSERT_EQ(256, frames);
209 ASSERT_EQ(256, area2->frames);
210
211 /* Assert buf2 points to the same position as buf1 */
212 ASSERT_EQ(400, area2->channels[0].buf - area1_buf);
213
214 /* Test 100 frames(400 bytes) put, only 360 bytes processed,
215 * 40 bytes left in pcm buffer.
216 */
217 a2dp_encode_index = 0;
218 a2dp_encode_processed_bytes_val[0] = 360;
219 a2dp_encode_processed_bytes_val[1] = 0;
220 a2dp_write_index = 0;
221 a2dp_write_return_val[0] = 360;
222 a2dp_write_return_val[1] = 0;
223 iodev->put_buffer(iodev, 100);
224 write_callback(write_callback_data);
225 EXPECT_EQ(400, pcm_buf_size_val[0]);
226 ASSERT_EQ(40, pcm_buf_size_val[1]);
227
228 iodev->get_buffer(iodev, &area3, &frames);
229
230 /* Existing buffer not completed processed, assert new buffer starts from
231 * current write pointer.
232 */
233 ASSERT_EQ(256, frames);
234 EXPECT_EQ(800, area3->channels[0].buf - area1_buf);
235
236 a2dp_iodev_destroy(iodev);
237 }
238
TEST(A2dpIoInif,FramesQueued)239 TEST(A2dpIoInif, FramesQueued) {
240 struct cras_iodev *iodev;
241 struct cras_audio_area *area;
242 struct timespec tstamp;
243 unsigned frames;
244
245 ResetStubData();
246 iodev = a2dp_iodev_create(fake_transport);
247
248 iodev_set_format(iodev, &format);
249 time_now.tv_sec = 0;
250 time_now.tv_nsec = 0;
251 iodev->open_dev(iodev);
252 ASSERT_NE(write_callback, (void *)NULL);
253
254 frames = 256;
255 iodev->get_buffer(iodev, &area, &frames);
256 ASSERT_EQ(256, frames);
257 ASSERT_EQ(256, area->frames);
258
259 /* Put 100 frames, proccessed 400 bytes to a2dp buffer.
260 * Assume 200 bytes written out, queued 50 frames in a2dp buffer.
261 */
262 a2dp_encode_processed_bytes_val[0] = 400;
263 a2dp_encode_processed_bytes_val[1] = 0;
264 a2dp_write_return_val[0] = 200;
265 a2dp_write_return_val[1] = -EAGAIN;
266 a2dp_queued_frames_val = 50;
267 time_now.tv_sec = 0;
268 time_now.tv_nsec = 1000000;
269 iodev->put_buffer(iodev, 300);
270 write_callback(write_callback_data);
271 EXPECT_EQ(350, iodev->frames_queued(iodev, &tstamp));
272 EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
273 EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
274
275 /* After writing another 200 frames, check for correct buffer level. */
276 time_now.tv_sec = 0;
277 time_now.tv_nsec = 2000000;
278 a2dp_encode_index = 0;
279 a2dp_write_index = 0;
280 a2dp_encode_processed_bytes_val[0] = 800;
281 write_callback(write_callback_data);
282 /* 1000000 nsec has passed, estimated queued frames adjusted by 44 */
283 EXPECT_EQ(256, iodev->frames_queued(iodev, &tstamp));
284 EXPECT_EQ(1200, pcm_buf_size_val[0]);
285 EXPECT_EQ(400, pcm_buf_size_val[1]);
286 EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
287 EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
288
289 /* Queued frames and new put buffer are all written */
290 a2dp_encode_processed_bytes_val[0] = 400;
291 a2dp_encode_processed_bytes_val[1] = 0;
292 a2dp_encode_index = 0;
293 a2dp_write_return_val[0] = 400;
294 a2dp_write_return_val[1] = -EAGAIN;
295 a2dp_write_index = 0;
296
297 /* Add wnother 200 samples, get back to the original level. */
298 time_now.tv_sec = 0;
299 time_now.tv_nsec = 50000000;
300 a2dp_encode_processed_bytes_val[0] = 600;
301 iodev->put_buffer(iodev, 200);
302 EXPECT_EQ(1200, pcm_buf_size_val[0]);
303 EXPECT_EQ(200, iodev->frames_queued(iodev, &tstamp));
304 EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
305 EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
306 }
307
TEST(A2dpIo,FlushAtLowBufferLevel)308 TEST(A2dpIo, FlushAtLowBufferLevel) {
309 struct cras_iodev *iodev;
310 struct cras_audio_area *area;
311 struct timespec tstamp;
312 unsigned frames;
313
314 ResetStubData();
315 iodev = a2dp_iodev_create(fake_transport);
316
317 iodev_set_format(iodev, &format);
318 time_now.tv_sec = 0;
319 time_now.tv_nsec = 0;
320 iodev->open_dev(iodev);
321 ASSERT_NE(write_callback, (void *)NULL);
322
323 ASSERT_EQ(iodev->min_buffer_level, 400);
324
325 frames = 700;
326 iodev->get_buffer(iodev, &area, &frames);
327 ASSERT_EQ(700, frames);
328 ASSERT_EQ(700, area->frames);
329
330 /* Fake 111 frames in pre-fill*/
331 a2dp_encode_processed_bytes_val[0] = 111;
332 a2dp_write_return_val[0] = -EAGAIN;
333
334 /* First call to a2dp_encode() processed 800 bytes. */
335 a2dp_encode_processed_bytes_val[1] = 800;
336 a2dp_encode_processed_bytes_val[2] = 0;
337 a2dp_write_return_val[1] = 200;
338
339 /* put_buffer shouldn't trigger the 2nd call to a2dp_encode() because
340 * buffer is low. Fake some data to make sure this test case will fail
341 * when a2dp_encode() called twice.
342 */
343 a2dp_encode_processed_bytes_val[3] = 800;
344 a2dp_encode_processed_bytes_val[4] = 0;
345 a2dp_write_return_val[2] = -EAGAIN;
346
347 time_now.tv_nsec = 10000000;
348 iodev->put_buffer(iodev, 700);
349
350 time_now.tv_nsec = 20000000;
351 EXPECT_EQ(500, iodev->frames_queued(iodev, &tstamp));
352 EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
353 EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
354 }
355
356 } // namespace
357
main(int argc,char ** argv)358 int main(int argc, char **argv) {
359 ::testing::InitGoogleTest(&argc, argv);
360 return RUN_ALL_TESTS();
361 }
362
363 extern "C" {
364
cras_bt_transport_configuration(const struct cras_bt_transport * transport,void * configuration,int len)365 int cras_bt_transport_configuration(const struct cras_bt_transport *transport,
366 void *configuration, int len)
367 {
368 cras_bt_transport_configuration_called++;
369 return 0;
370 }
371
cras_bt_transport_acquire(struct cras_bt_transport * transport)372 int cras_bt_transport_acquire(struct cras_bt_transport *transport)
373 {
374 cras_bt_transport_acquire_called++;
375 return 0;
376 }
377
cras_bt_transport_release(struct cras_bt_transport * transport,unsigned int blocking)378 int cras_bt_transport_release(struct cras_bt_transport *transport,
379 unsigned int blocking)
380 {
381 cras_bt_transport_release_called++;
382 return 0;
383 }
384
cras_bt_transport_fd(const struct cras_bt_transport * transport)385 int cras_bt_transport_fd(const struct cras_bt_transport *transport)
386 {
387 return 0;
388 }
389
cras_bt_transport_object_path(const struct cras_bt_transport * transport)390 const char *cras_bt_transport_object_path(
391 const struct cras_bt_transport *transport)
392 {
393 return FAKE_OBJECT_PATH;
394 }
395
cras_bt_transport_write_mtu(const struct cras_bt_transport * transport)396 uint16_t cras_bt_transport_write_mtu(const struct cras_bt_transport *transport)
397 {
398 return cras_bt_transport_write_mtu_ret;
399 }
400
cras_bt_transport_set_volume(struct cras_bt_transport * transport,uint16_t volume)401 int cras_bt_transport_set_volume(struct cras_bt_transport *transport,
402 uint16_t volume)
403 {
404 return 0;
405 }
406
cras_iodev_free_format(struct cras_iodev * iodev)407 void cras_iodev_free_format(struct cras_iodev *iodev)
408 {
409 cras_iodev_free_format_called++;
410 }
411
cras_iodev_free_resources(struct cras_iodev * iodev)412 void cras_iodev_free_resources(struct cras_iodev *iodev)
413 {
414 cras_iodev_free_resources_called++;
415 }
416
417 // Cras iodev
cras_iodev_add_node(struct cras_iodev * iodev,struct cras_ionode * node)418 void cras_iodev_add_node(struct cras_iodev *iodev, struct cras_ionode *node)
419 {
420 cras_iodev_add_node_called++;
421 iodev->nodes = node;
422 }
423
cras_iodev_rm_node(struct cras_iodev * iodev,struct cras_ionode * node)424 void cras_iodev_rm_node(struct cras_iodev *iodev, struct cras_ionode *node)
425 {
426 cras_iodev_rm_node_called++;
427 iodev->nodes = NULL;
428 }
429
cras_iodev_set_active_node(struct cras_iodev * iodev,struct cras_ionode * node)430 void cras_iodev_set_active_node(struct cras_iodev *iodev,
431 struct cras_ionode *node)
432 {
433 cras_iodev_set_active_node_called++;
434 iodev->active_node = node;
435 }
436
437 // From cras_bt_transport
cras_bt_transport_device(const struct cras_bt_transport * transport)438 struct cras_bt_device *cras_bt_transport_device(
439 const struct cras_bt_transport *transport)
440 {
441 return reinterpret_cast<struct cras_bt_device *>(0x456);;
442 }
443
cras_bt_transport_profile(const struct cras_bt_transport * transport)444 enum cras_bt_device_profile cras_bt_transport_profile(
445 const struct cras_bt_transport *transport)
446 {
447 return CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
448 }
449
450 // From cras_bt_device
cras_bt_device_name(const struct cras_bt_device * device)451 const char *cras_bt_device_name(const struct cras_bt_device *device)
452 {
453 return cras_bt_device_name_ret;
454 }
455
cras_bt_device_object_path(const struct cras_bt_device * device)456 const char *cras_bt_device_object_path(const struct cras_bt_device *device) {
457 return "/org/bluez/hci0/dev_1A_2B_3C_4D_5E_6F";
458 }
459
cras_bt_device_append_iodev(struct cras_bt_device * device,struct cras_iodev * iodev,enum cras_bt_device_profile profile)460 void cras_bt_device_append_iodev(struct cras_bt_device *device,
461 struct cras_iodev *iodev,
462 enum cras_bt_device_profile profile)
463 {
464 cras_bt_device_append_iodev_called++;
465 }
466
cras_bt_device_rm_iodev(struct cras_bt_device * device,struct cras_iodev * iodev)467 void cras_bt_device_rm_iodev(struct cras_bt_device *device,
468 struct cras_iodev *iodev)
469 {
470 cras_bt_device_rm_iodev_called++;
471 }
472
cras_bt_device_get_use_hardware_volume(struct cras_bt_device * device)473 int cras_bt_device_get_use_hardware_volume(struct cras_bt_device *device)
474 {
475 return 0;
476 }
477
cras_bt_device_cancel_suspend(struct cras_bt_device * device)478 int cras_bt_device_cancel_suspend(struct cras_bt_device *device)
479 {
480 return 0;
481 }
482
cras_bt_device_schedule_suspend(struct cras_bt_device * device,unsigned int msec)483 int cras_bt_device_schedule_suspend(struct cras_bt_device *device,
484 unsigned int msec)
485 {
486 return 0;
487 }
488
init_a2dp(struct a2dp_info * a2dp,a2dp_sbc_t * sbc)489 int init_a2dp(struct a2dp_info *a2dp, a2dp_sbc_t *sbc)
490 {
491 init_a2dp_called++;
492 return init_a2dp_return_val;
493 }
494
destroy_a2dp(struct a2dp_info * a2dp)495 void destroy_a2dp(struct a2dp_info *a2dp)
496 {
497 destroy_a2dp_called++;
498 }
499
a2dp_codesize(struct a2dp_info * a2dp)500 int a2dp_codesize(struct a2dp_info *a2dp)
501 {
502 return 512;
503 }
504
a2dp_block_size(struct a2dp_info * a2dp,int encoded_bytes)505 int a2dp_block_size(struct a2dp_info *a2dp, int encoded_bytes)
506 {
507 a2dp_block_size_called++;
508
509 // Assumes a2dp block size is 1:1 before/after encode.
510 return encoded_bytes;
511 }
512
a2dp_queued_frames(struct a2dp_info * a2dp)513 int a2dp_queued_frames(struct a2dp_info *a2dp)
514 {
515 return a2dp_queued_frames_val;
516 }
517
a2dp_drain(struct a2dp_info * a2dp)518 void a2dp_drain(struct a2dp_info *a2dp)
519 {
520 drain_a2dp_called++;
521 }
522
a2dp_encode(struct a2dp_info * a2dp,const void * pcm_buf,int pcm_buf_size,int format_bytes,size_t link_mtu)523 int a2dp_encode(struct a2dp_info *a2dp, const void *pcm_buf, int pcm_buf_size,
524 int format_bytes, size_t link_mtu) {
525 unsigned int processed;
526
527 if (a2dp_encode_index == MAX_A2DP_ENCODE_CALLS)
528 return 0;
529 processed = a2dp_encode_processed_bytes_val[a2dp_encode_index];
530 pcm_buf_size_val[a2dp_encode_index] = pcm_buf_size;
531 a2dp_encode_index++;
532 return processed;
533 }
534
a2dp_write(struct a2dp_info * a2dp,int stream_fd,size_t link_mtu)535 int a2dp_write(struct a2dp_info *a2dp, int stream_fd, size_t link_mtu) {
536 return a2dp_write_return_val[a2dp_write_index++];;
537 }
538
clock_gettime(clockid_t clk_id,struct timespec * tp)539 int clock_gettime(clockid_t clk_id, struct timespec *tp) {
540 *tp = time_now;
541 return 0;
542 }
543
cras_iodev_init_audio_area(struct cras_iodev * iodev,int num_channels)544 void cras_iodev_init_audio_area(struct cras_iodev *iodev,
545 int num_channels) {
546 iodev->area = dummy_audio_area;
547 }
548
cras_iodev_free_audio_area(struct cras_iodev * iodev)549 void cras_iodev_free_audio_area(struct cras_iodev *iodev) {
550 }
551
cras_audio_area_config_buf_pointers(struct cras_audio_area * area,const struct cras_audio_format * fmt,uint8_t * base_buffer)552 void cras_audio_area_config_buf_pointers(struct cras_audio_area *area,
553 const struct cras_audio_format *fmt,
554 uint8_t *base_buffer)
555 {
556 dummy_audio_area->channels[0].buf = base_buffer;
557 }
558
cras_iodev_list_get_audio_thread()559 struct audio_thread *cras_iodev_list_get_audio_thread()
560 {
561 return NULL;
562 }
563 // From audio_thread
564 struct audio_thread_event_log *atlog;
565
audio_thread_add_write_callback(int fd,thread_callback cb,void * data)566 void audio_thread_add_write_callback(int fd, thread_callback cb, void *data) {
567 write_callback = cb;
568 write_callback_data = data;
569 }
570
audio_thread_rm_callback_sync(struct audio_thread * thread,int fd)571 int audio_thread_rm_callback_sync(struct audio_thread *thread, int fd) {
572 return 0;
573 }
574
audio_thread_enable_callback(int fd,int enabled)575 void audio_thread_enable_callback(int fd, int enabled) {
576 }
577
578 }
579