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