• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
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 #define LOG_TAG "audio_hw_default"
18 //#define LOG_NDEBUG 0
19 
20 #include <errno.h>
21 #include <malloc.h>
22 #include <pthread.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 #include <unistd.h>
28 
29 #include <log/log.h>
30 
31 #include <hardware/audio.h>
32 #include <hardware/hardware.h>
33 #include <system/audio.h>
34 
35 #define STUB_DEFAULT_SAMPLE_RATE   48000
36 #define STUB_DEFAULT_AUDIO_FORMAT  AUDIO_FORMAT_PCM_16_BIT
37 
38 #define STUB_INPUT_BUFFER_MILLISECONDS  20
39 #define STUB_INPUT_DEFAULT_CHANNEL_MASK AUDIO_CHANNEL_IN_STEREO
40 
41 #define STUB_OUTPUT_BUFFER_MILLISECONDS  10
42 #define STUB_OUTPUT_DEFAULT_CHANNEL_MASK AUDIO_CHANNEL_OUT_STEREO
43 
44 struct stub_audio_device {
45     struct audio_hw_device device;
46 };
47 
48 struct stub_stream_out {
49     struct audio_stream_out stream;
50     int64_t last_write_time_us;
51     uint32_t sample_rate;
52     audio_channel_mask_t channel_mask;
53     audio_format_t format;
54     size_t frame_count;
55 };
56 
57 struct stub_stream_in {
58     struct audio_stream_in stream;
59     int64_t last_read_time_us;
60     uint32_t sample_rate;
61     audio_channel_mask_t channel_mask;
62     audio_format_t format;
63     size_t frame_count;
64 };
65 
out_get_sample_rate(const struct audio_stream * stream)66 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
67 {
68     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
69 
70     ALOGV("out_get_sample_rate: %u", out->sample_rate);
71     return out->sample_rate;
72 }
73 
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)74 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
75 {
76     struct stub_stream_out *out = (struct stub_stream_out *)stream;
77 
78     ALOGV("out_set_sample_rate: %d", rate);
79     out->sample_rate = rate;
80     return 0;
81 }
82 
out_get_buffer_size(const struct audio_stream * stream)83 static size_t out_get_buffer_size(const struct audio_stream *stream)
84 {
85     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
86     size_t buffer_size = out->frame_count *
87                          audio_stream_out_frame_size(&out->stream);
88 
89     ALOGV("out_get_buffer_size: %zu", buffer_size);
90     return buffer_size;
91 }
92 
out_get_channels(const struct audio_stream * stream)93 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
94 {
95     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
96 
97     ALOGV("out_get_channels: %x", out->channel_mask);
98     return out->channel_mask;
99 }
100 
out_get_format(const struct audio_stream * stream)101 static audio_format_t out_get_format(const struct audio_stream *stream)
102 {
103     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
104 
105     ALOGV("out_get_format: %d", out->format);
106     return out->format;
107 }
108 
out_set_format(struct audio_stream * stream,audio_format_t format)109 static int out_set_format(struct audio_stream *stream, audio_format_t format)
110 {
111     struct stub_stream_out *out = (struct stub_stream_out *)stream;
112 
113     ALOGV("out_set_format: %d", format);
114     out->format = format;
115     return 0;
116 }
117 
out_standby(struct audio_stream * stream)118 static int out_standby(struct audio_stream *stream)
119 {
120     ALOGV("out_standby");
121     // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
122     return 0;
123 }
124 
out_dump(const struct audio_stream * stream,int fd)125 static int out_dump(const struct audio_stream *stream, int fd)
126 {
127     ALOGV("out_dump");
128     return 0;
129 }
130 
out_set_parameters(struct audio_stream * stream,const char * kvpairs)131 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
132 {
133     ALOGV("out_set_parameters");
134     return 0;
135 }
136 
out_get_parameters(const struct audio_stream * stream,const char * keys)137 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
138 {
139     ALOGV("out_get_parameters");
140     return strdup("");
141 }
142 
out_get_latency(const struct audio_stream_out * stream)143 static uint32_t out_get_latency(const struct audio_stream_out *stream)
144 {
145     ALOGV("out_get_latency");
146     return STUB_OUTPUT_BUFFER_MILLISECONDS;
147 }
148 
out_set_volume(struct audio_stream_out * stream,float left,float right)149 static int out_set_volume(struct audio_stream_out *stream, float left,
150                           float right)
151 {
152     ALOGV("out_set_volume: Left:%f Right:%f", left, right);
153     return 0;
154 }
155 
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)156 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
157                          size_t bytes)
158 {
159     ALOGV("out_write: bytes: %zu", bytes);
160 
161     /* XXX: fake timing for audio output */
162     struct stub_stream_out *out = (struct stub_stream_out *)stream;
163     struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
164     clock_gettime(CLOCK_MONOTONIC, &t);
165     const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
166     const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
167     int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
168                out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
169     if (sleep_time > 0) {
170         usleep(sleep_time);
171     } else {
172         // we don't sleep when we exit standby (this is typical for a real alsa buffer).
173         sleep_time = 0;
174     }
175     out->last_write_time_us = now + sleep_time;
176     // last_write_time_us is an approximation of when the (simulated) alsa
177     // buffer is believed completely full. The usleep above waits for more space
178     // in the buffer, but by the end of the sleep the buffer is considered
179     // topped-off.
180     //
181     // On the subsequent out_write(), we measure the elapsed time spent in
182     // the mixer. This is subtracted from the sleep estimate based on frames,
183     // thereby accounting for drain in the alsa buffer during mixing.
184     // This is a crude approximation; we don't handle underruns precisely.
185     return bytes;
186 }
187 
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)188 static int out_get_render_position(const struct audio_stream_out *stream,
189                                    uint32_t *dsp_frames)
190 {
191     *dsp_frames = 0;
192     ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
193     return -EINVAL;
194 }
195 
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)196 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
197 {
198     ALOGV("out_add_audio_effect: %p", effect);
199     return 0;
200 }
201 
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)202 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
203 {
204     ALOGV("out_remove_audio_effect: %p", effect);
205     return 0;
206 }
207 
out_get_next_write_timestamp(const struct audio_stream_out * stream,int64_t * timestamp)208 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
209                                         int64_t *timestamp)
210 {
211     *timestamp = 0;
212     ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
213     return -EINVAL;
214 }
215 
216 /** audio_stream_in implementation **/
in_get_sample_rate(const struct audio_stream * stream)217 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
218 {
219     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
220 
221     ALOGV("in_get_sample_rate: %u", in->sample_rate);
222     return in->sample_rate;
223 }
224 
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)225 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
226 {
227     struct stub_stream_in *in = (struct stub_stream_in *)stream;
228 
229     ALOGV("in_set_sample_rate: %u", rate);
230     in->sample_rate = rate;
231     return 0;
232 }
233 
in_get_buffer_size(const struct audio_stream * stream)234 static size_t in_get_buffer_size(const struct audio_stream *stream)
235 {
236     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
237     size_t buffer_size = in->frame_count *
238                          audio_stream_in_frame_size(&in->stream);
239 
240     ALOGV("in_get_buffer_size: %zu", buffer_size);
241     return buffer_size;
242 }
243 
in_get_channels(const struct audio_stream * stream)244 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
245 {
246     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
247 
248     ALOGV("in_get_channels: %x", in->channel_mask);
249     return in->channel_mask;
250 }
251 
in_get_format(const struct audio_stream * stream)252 static audio_format_t in_get_format(const struct audio_stream *stream)
253 {
254     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
255 
256     ALOGV("in_get_format: %d", in->format);
257     return in->format;
258 }
259 
in_set_format(struct audio_stream * stream,audio_format_t format)260 static int in_set_format(struct audio_stream *stream, audio_format_t format)
261 {
262     struct stub_stream_in *in = (struct stub_stream_in *)stream;
263 
264     ALOGV("in_set_format: %d", format);
265     in->format = format;
266     return 0;
267 }
268 
in_standby(struct audio_stream * stream)269 static int in_standby(struct audio_stream *stream)
270 {
271     struct stub_stream_in *in = (struct stub_stream_in *)stream;
272     in->last_read_time_us = 0;
273     return 0;
274 }
275 
in_dump(const struct audio_stream * stream,int fd)276 static int in_dump(const struct audio_stream *stream, int fd)
277 {
278     return 0;
279 }
280 
in_set_parameters(struct audio_stream * stream,const char * kvpairs)281 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
282 {
283     return 0;
284 }
285 
in_get_parameters(const struct audio_stream * stream,const char * keys)286 static char * in_get_parameters(const struct audio_stream *stream,
287                                 const char *keys)
288 {
289     return strdup("");
290 }
291 
in_set_gain(struct audio_stream_in * stream,float gain)292 static int in_set_gain(struct audio_stream_in *stream, float gain)
293 {
294     return 0;
295 }
296 
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)297 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
298                        size_t bytes)
299 {
300     ALOGV("in_read: bytes %zu", bytes);
301 
302     /* XXX: fake timing for audio input */
303     struct stub_stream_in *in = (struct stub_stream_in *)stream;
304     struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
305     clock_gettime(CLOCK_MONOTONIC, &t);
306     const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
307 
308     // we do a full sleep when exiting standby.
309     const bool standby = in->last_read_time_us == 0;
310     const int64_t elapsed_time_since_last_read = standby ?
311             0 : now - in->last_read_time_us;
312     int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
313             in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
314     if (sleep_time > 0) {
315         usleep(sleep_time);
316     } else {
317         sleep_time = 0;
318     }
319     in->last_read_time_us = now + sleep_time;
320     // last_read_time_us is an approximation of when the (simulated) alsa
321     // buffer is drained by the read, and is empty.
322     //
323     // On the subsequent in_read(), we measure the elapsed time spent in
324     // the recording thread. This is subtracted from the sleep estimate based on frames,
325     // thereby accounting for fill in the alsa buffer during the interim.
326     memset(buffer, 0, bytes);
327     return bytes;
328 }
329 
in_get_input_frames_lost(struct audio_stream_in * stream)330 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
331 {
332     return 0;
333 }
334 
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)335 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
336 {
337     return 0;
338 }
339 
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)340 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
341 {
342     return 0;
343 }
344 
samples_per_milliseconds(size_t milliseconds,uint32_t sample_rate,size_t channel_count)345 static size_t samples_per_milliseconds(size_t milliseconds,
346                                        uint32_t sample_rate,
347                                        size_t channel_count)
348 {
349     return milliseconds * sample_rate * channel_count / 1000;
350 }
351 
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out,const char * address __unused)352 static int adev_open_output_stream(struct audio_hw_device *dev,
353                                    audio_io_handle_t handle,
354                                    audio_devices_t devices,
355                                    audio_output_flags_t flags,
356                                    struct audio_config *config,
357                                    struct audio_stream_out **stream_out,
358                                    const char *address __unused)
359 {
360     ALOGV("adev_open_output_stream...");
361 
362     *stream_out = NULL;
363     struct stub_stream_out *out =
364             (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
365     if (!out)
366         return -ENOMEM;
367 
368     out->stream.common.get_sample_rate = out_get_sample_rate;
369     out->stream.common.set_sample_rate = out_set_sample_rate;
370     out->stream.common.get_buffer_size = out_get_buffer_size;
371     out->stream.common.get_channels = out_get_channels;
372     out->stream.common.get_format = out_get_format;
373     out->stream.common.set_format = out_set_format;
374     out->stream.common.standby = out_standby;
375     out->stream.common.dump = out_dump;
376     out->stream.common.set_parameters = out_set_parameters;
377     out->stream.common.get_parameters = out_get_parameters;
378     out->stream.common.add_audio_effect = out_add_audio_effect;
379     out->stream.common.remove_audio_effect = out_remove_audio_effect;
380     out->stream.get_latency = out_get_latency;
381     out->stream.set_volume = out_set_volume;
382     out->stream.write = out_write;
383     out->stream.get_render_position = out_get_render_position;
384     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
385     out->sample_rate = config->sample_rate;
386     if (out->sample_rate == 0)
387         out->sample_rate = STUB_DEFAULT_SAMPLE_RATE;
388     out->channel_mask = config->channel_mask;
389     if (out->channel_mask == AUDIO_CHANNEL_NONE)
390         out->channel_mask = STUB_OUTPUT_DEFAULT_CHANNEL_MASK;
391     out->format = config->format;
392     if (out->format == AUDIO_FORMAT_DEFAULT)
393         out->format = STUB_DEFAULT_AUDIO_FORMAT;
394     out->frame_count = samples_per_milliseconds(
395                            STUB_OUTPUT_BUFFER_MILLISECONDS,
396                            out->sample_rate, 1);
397 
398     ALOGV("adev_open_output_stream: sample_rate: %u, channels: %x, format: %d,"
399           " frames: %zu", out->sample_rate, out->channel_mask, out->format,
400           out->frame_count);
401     *stream_out = &out->stream;
402     return 0;
403 }
404 
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)405 static void adev_close_output_stream(struct audio_hw_device *dev,
406                                      struct audio_stream_out *stream)
407 {
408     ALOGV("adev_close_output_stream...");
409     free(stream);
410 }
411 
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)412 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
413 {
414     ALOGV("adev_set_parameters");
415     return -ENOSYS;
416 }
417 
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)418 static char * adev_get_parameters(const struct audio_hw_device *dev,
419                                   const char *keys)
420 {
421     ALOGV("adev_get_parameters");
422     return strdup("");
423 }
424 
adev_init_check(const struct audio_hw_device * dev)425 static int adev_init_check(const struct audio_hw_device *dev)
426 {
427     ALOGV("adev_init_check");
428     return 0;
429 }
430 
adev_set_voice_volume(struct audio_hw_device * dev,float volume)431 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
432 {
433     ALOGV("adev_set_voice_volume: %f", volume);
434     return -ENOSYS;
435 }
436 
adev_set_master_volume(struct audio_hw_device * dev,float volume)437 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
438 {
439     ALOGV("adev_set_master_volume: %f", volume);
440     return -ENOSYS;
441 }
442 
adev_get_master_volume(struct audio_hw_device * dev,float * volume)443 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
444 {
445     ALOGV("adev_get_master_volume: %f", *volume);
446     return -ENOSYS;
447 }
448 
adev_set_master_mute(struct audio_hw_device * dev,bool muted)449 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
450 {
451     ALOGV("adev_set_master_mute: %d", muted);
452     return -ENOSYS;
453 }
454 
adev_get_master_mute(struct audio_hw_device * dev,bool * muted)455 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
456 {
457     ALOGV("adev_get_master_mute: %d", *muted);
458     return -ENOSYS;
459 }
460 
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)461 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
462 {
463     ALOGV("adev_set_mode: %d", mode);
464     return 0;
465 }
466 
adev_set_mic_mute(struct audio_hw_device * dev,bool state)467 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
468 {
469     ALOGV("adev_set_mic_mute: %d",state);
470     return -ENOSYS;
471 }
472 
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)473 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
474 {
475     ALOGV("adev_get_mic_mute");
476     return -ENOSYS;
477 }
478 
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)479 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
480                                          const struct audio_config *config)
481 {
482     size_t buffer_size = samples_per_milliseconds(
483                              STUB_INPUT_BUFFER_MILLISECONDS,
484                              config->sample_rate,
485                              audio_channel_count_from_in_mask(
486                                  config->channel_mask));
487 
488     if (!audio_has_proportional_frames(config->format)) {
489         // Since the audio data is not proportional choose an arbitrary size for
490         // the buffer.
491         buffer_size *= 4;
492     } else {
493         buffer_size *= audio_bytes_per_sample(config->format);
494     }
495     ALOGV("adev_get_input_buffer_size: %zu", buffer_size);
496     return buffer_size;
497 }
498 
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,struct audio_stream_in ** stream_in,audio_input_flags_t flags __unused,const char * address __unused,audio_source_t source __unused)499 static int adev_open_input_stream(struct audio_hw_device *dev,
500                                   audio_io_handle_t handle,
501                                   audio_devices_t devices,
502                                   struct audio_config *config,
503                                   struct audio_stream_in **stream_in,
504                                   audio_input_flags_t flags __unused,
505                                   const char *address __unused,
506                                   audio_source_t source __unused)
507 {
508     ALOGV("adev_open_input_stream...");
509 
510     *stream_in = NULL;
511     struct stub_stream_in *in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
512     if (!in)
513         return -ENOMEM;
514 
515     in->stream.common.get_sample_rate = in_get_sample_rate;
516     in->stream.common.set_sample_rate = in_set_sample_rate;
517     in->stream.common.get_buffer_size = in_get_buffer_size;
518     in->stream.common.get_channels = in_get_channels;
519     in->stream.common.get_format = in_get_format;
520     in->stream.common.set_format = in_set_format;
521     in->stream.common.standby = in_standby;
522     in->stream.common.dump = in_dump;
523     in->stream.common.set_parameters = in_set_parameters;
524     in->stream.common.get_parameters = in_get_parameters;
525     in->stream.common.add_audio_effect = in_add_audio_effect;
526     in->stream.common.remove_audio_effect = in_remove_audio_effect;
527     in->stream.set_gain = in_set_gain;
528     in->stream.read = in_read;
529     in->stream.get_input_frames_lost = in_get_input_frames_lost;
530     in->sample_rate = config->sample_rate;
531     if (in->sample_rate == 0)
532         in->sample_rate = STUB_DEFAULT_SAMPLE_RATE;
533     in->channel_mask = config->channel_mask;
534     if (in->channel_mask == AUDIO_CHANNEL_NONE)
535         in->channel_mask = STUB_INPUT_DEFAULT_CHANNEL_MASK;
536     in->format = config->format;
537     if (in->format == AUDIO_FORMAT_DEFAULT)
538         in->format = STUB_DEFAULT_AUDIO_FORMAT;
539     in->frame_count = samples_per_milliseconds(
540                           STUB_INPUT_BUFFER_MILLISECONDS, in->sample_rate, 1);
541 
542     ALOGV("adev_open_input_stream: sample_rate: %u, channels: %x, format: %d,"
543           "frames: %zu", in->sample_rate, in->channel_mask, in->format,
544           in->frame_count);
545     *stream_in = &in->stream;
546     return 0;
547 }
548 
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * in)549 static void adev_close_input_stream(struct audio_hw_device *dev,
550                                    struct audio_stream_in *in)
551 {
552     ALOGV("adev_close_input_stream...");
553     return;
554 }
555 
adev_dump(const audio_hw_device_t * device,int fd)556 static int adev_dump(const audio_hw_device_t *device, int fd)
557 {
558     ALOGV("adev_dump");
559     return 0;
560 }
561 
adev_close(hw_device_t * device)562 static int adev_close(hw_device_t *device)
563 {
564     ALOGV("adev_close");
565     free(device);
566     return 0;
567 }
568 
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)569 static int adev_open(const hw_module_t* module, const char* name,
570                      hw_device_t** device)
571 {
572     ALOGV("adev_open: %s", name);
573 
574     struct stub_audio_device *adev;
575 
576     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
577         return -EINVAL;
578 
579     adev = calloc(1, sizeof(struct stub_audio_device));
580     if (!adev)
581         return -ENOMEM;
582 
583     adev->device.common.tag = HARDWARE_DEVICE_TAG;
584     adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
585     adev->device.common.module = (struct hw_module_t *) module;
586     adev->device.common.close = adev_close;
587 
588     adev->device.init_check = adev_init_check;
589     adev->device.set_voice_volume = adev_set_voice_volume;
590     adev->device.set_master_volume = adev_set_master_volume;
591     adev->device.get_master_volume = adev_get_master_volume;
592     adev->device.set_master_mute = adev_set_master_mute;
593     adev->device.get_master_mute = adev_get_master_mute;
594     adev->device.set_mode = adev_set_mode;
595     adev->device.set_mic_mute = adev_set_mic_mute;
596     adev->device.get_mic_mute = adev_get_mic_mute;
597     adev->device.set_parameters = adev_set_parameters;
598     adev->device.get_parameters = adev_get_parameters;
599     adev->device.get_input_buffer_size = adev_get_input_buffer_size;
600     adev->device.open_output_stream = adev_open_output_stream;
601     adev->device.close_output_stream = adev_close_output_stream;
602     adev->device.open_input_stream = adev_open_input_stream;
603     adev->device.close_input_stream = adev_close_input_stream;
604     adev->device.dump = adev_dump;
605 
606     *device = &adev->device.common;
607 
608     return 0;
609 }
610 
611 static struct hw_module_methods_t hal_module_methods = {
612     .open = adev_open,
613 };
614 
615 struct audio_module HAL_MODULE_INFO_SYM = {
616     .common = {
617         .tag = HARDWARE_MODULE_TAG,
618         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
619         .hal_api_version = HARDWARE_HAL_API_VERSION,
620         .id = AUDIO_HARDWARE_MODULE_ID,
621         .name = "Default audio HW HAL",
622         .author = "The Android Open Source Project",
623         .methods = &hal_module_methods,
624     },
625 };
626