Home | History | Annotate | Download | only in audio
      1 /*
      2  * Copyright (C) 2012 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_generic"
     18 /*#define LOG_NDEBUG 0*/
     19 
     20 #include <errno.h>
     21 #include <pthread.h>
     22 #include <stdint.h>
     23 #include <stdlib.h>
     24 #include <sys/time.h>
     25 #include <fcntl.h>
     26 
     27 #include <cutils/log.h>
     28 #include <cutils/str_parms.h>
     29 
     30 #include <hardware/hardware.h>
     31 #include <system/audio.h>
     32 #include <hardware/audio.h>
     33 
     34 
     35 #define AUDIO_DEVICE_NAME "/dev/eac"
     36 #define OUT_BUFFER_SIZE 4096
     37 #define OUT_LATENCY_MS 20
     38 #define IN_SAMPLING_RATE 8000
     39 #define IN_BUFFER_SIZE 320
     40 
     41 
     42 struct generic_audio_device {
     43     struct audio_hw_device device;
     44     pthread_mutex_t lock;
     45     struct audio_stream_out *output;
     46     struct audio_stream_in *input;
     47     int fd;
     48     bool mic_mute;
     49 };
     50 
     51 
     52 struct generic_stream_out {
     53     struct audio_stream_out stream;
     54     struct generic_audio_device *dev;
     55     audio_devices_t device;
     56     uint32_t sample_rate;
     57 };
     58 
     59 struct generic_stream_in {
     60     struct audio_stream_in stream;
     61     struct generic_audio_device *dev;
     62     audio_devices_t device;
     63 };
     64 
     65 
     66 static uint32_t out_get_sample_rate(const struct audio_stream *stream)
     67 {
     68     struct generic_stream_out *out = (struct generic_stream_out *)stream;
     69     return out->sample_rate;
     70 }
     71 
     72 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
     73 {
     74     return -ENOSYS;
     75 }
     76 
     77 static size_t out_get_buffer_size(const struct audio_stream *stream)
     78 {
     79     return OUT_BUFFER_SIZE;
     80 }
     81 
     82 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
     83 {
     84     return AUDIO_CHANNEL_OUT_STEREO;
     85 }
     86 
     87 static audio_format_t out_get_format(const struct audio_stream *stream)
     88 {
     89     return AUDIO_FORMAT_PCM_16_BIT;
     90 }
     91 
     92 static int out_set_format(struct audio_stream *stream, audio_format_t format)
     93 {
     94     return -ENOSYS;
     95 }
     96 
     97 static int out_standby(struct audio_stream *stream)
     98 {
     99     // out_standby is a no op
    100     return 0;
    101 }
    102 
    103 static int out_dump(const struct audio_stream *stream, int fd)
    104 {
    105     struct generic_stream_out *out = (struct generic_stream_out *)stream;
    106 
    107     dprintf(fd, "\tout_dump:\n"
    108                 "\t\tsample rate: %u\n"
    109                 "\t\tbuffer size: %u\n"
    110                 "\t\tchannel mask: %08x\n"
    111                 "\t\tformat: %d\n"
    112                 "\t\tdevice: %08x\n"
    113                 "\t\taudio dev: %p\n\n",
    114                 out_get_sample_rate(stream),
    115                 out_get_buffer_size(stream),
    116                 out_get_channels(stream),
    117                 out_get_format(stream),
    118                 out->device,
    119                 out->dev);
    120 
    121     return 0;
    122 }
    123 
    124 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
    125 {
    126     struct generic_stream_out *out = (struct generic_stream_out *)stream;
    127     struct str_parms *parms;
    128     char value[32];
    129     int ret;
    130     long val;
    131     char *end;
    132 
    133     parms = str_parms_create_str(kvpairs);
    134 
    135     ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
    136                             value, sizeof(value));
    137     if (ret >= 0) {
    138         errno = 0;
    139         val = strtol(value, &end, 10);
    140         if (errno == 0 && (end != NULL) && (*end == '\0') && ((int)val == val)) {
    141             out->device = (int)val;
    142         } else {
    143             ret = -EINVAL;
    144         }
    145     }
    146 
    147     str_parms_destroy(parms);
    148     return ret;
    149 }
    150 
    151 static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
    152 {
    153     struct generic_stream_out *out = (struct generic_stream_out *)stream;
    154     struct str_parms *query = str_parms_create_str(keys);
    155     char *str;
    156     char value[256];
    157     struct str_parms *reply = str_parms_create();
    158     int ret;
    159 
    160     ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
    161     if (ret >= 0) {
    162         str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, out->device);
    163         str = strdup(str_parms_to_str(reply));
    164     } else {
    165         str = strdup(keys);
    166     }
    167 
    168     str_parms_destroy(query);
    169     str_parms_destroy(reply);
    170     return str;
    171 }
    172 
    173 static uint32_t out_get_latency(const struct audio_stream_out *stream)
    174 {
    175     return OUT_LATENCY_MS;
    176 }
    177 
    178 static int out_set_volume(struct audio_stream_out *stream, float left,
    179                           float right)
    180 {
    181     return -ENOSYS;
    182 }
    183 
    184 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
    185                          size_t bytes)
    186 {
    187     struct generic_stream_out *out = (struct generic_stream_out *)stream;
    188     struct generic_audio_device *adev = out->dev;
    189 
    190     pthread_mutex_lock(&adev->lock);
    191     if (adev->fd >= 0)
    192         bytes = write(adev->fd, buffer, bytes);
    193     pthread_mutex_unlock(&adev->lock);
    194 
    195     return bytes;
    196 }
    197 
    198 static int out_get_render_position(const struct audio_stream_out *stream,
    199                                    uint32_t *dsp_frames)
    200 {
    201     return -ENOSYS;
    202 }
    203 
    204 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    205 {
    206     // out_add_audio_effect is a no op
    207     return 0;
    208 }
    209 
    210 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    211 {
    212     // out_remove_audio_effect is a no op
    213     return 0;
    214 }
    215 
    216 static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
    217                                         int64_t *timestamp)
    218 {
    219     return -ENOSYS;
    220 }
    221 
    222 /** audio_stream_in implementation **/
    223 static uint32_t in_get_sample_rate(const struct audio_stream *stream)
    224 {
    225     return IN_SAMPLING_RATE;
    226 }
    227 
    228 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
    229 {
    230     return -ENOSYS;
    231 }
    232 
    233 static size_t in_get_buffer_size(const struct audio_stream *stream)
    234 {
    235     return IN_BUFFER_SIZE;
    236 }
    237 
    238 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
    239 {
    240     return AUDIO_CHANNEL_IN_MONO;
    241 }
    242 
    243 static audio_format_t in_get_format(const struct audio_stream *stream)
    244 {
    245     return AUDIO_FORMAT_PCM_16_BIT;
    246 }
    247 
    248 static int in_set_format(struct audio_stream *stream, audio_format_t format)
    249 {
    250     return -ENOSYS;
    251 }
    252 
    253 static int in_standby(struct audio_stream *stream)
    254 {
    255     // in_standby is a no op
    256     return 0;
    257 }
    258 
    259 static int in_dump(const struct audio_stream *stream, int fd)
    260 {
    261     struct generic_stream_in *in = (struct generic_stream_in *)stream;
    262 
    263     dprintf(fd, "\tin_dump:\n"
    264                 "\t\tsample rate: %u\n"
    265                 "\t\tbuffer size: %u\n"
    266                 "\t\tchannel mask: %08x\n"
    267                 "\t\tformat: %d\n"
    268                 "\t\tdevice: %08x\n"
    269                 "\t\taudio dev: %p\n\n",
    270                 in_get_sample_rate(stream),
    271                 in_get_buffer_size(stream),
    272                 in_get_channels(stream),
    273                 in_get_format(stream),
    274                 in->device,
    275                 in->dev);
    276 
    277     return 0;
    278 }
    279 
    280 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
    281 {
    282     struct generic_stream_in *in = (struct generic_stream_in *)stream;
    283     struct str_parms *parms;
    284     char value[32];
    285     int ret;
    286     long val;
    287     char *end;
    288 
    289     parms = str_parms_create_str(kvpairs);
    290 
    291     ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
    292                             value, sizeof(value));
    293     if (ret >= 0) {
    294         errno = 0;
    295         val = strtol(value, &end, 10);
    296         if ((errno == 0) && (end != NULL) && (*end == '\0') && ((int)val == val)) {
    297             in->device = (int)val;
    298         } else {
    299             ret = -EINVAL;
    300         }
    301     }
    302 
    303     str_parms_destroy(parms);
    304     return ret;
    305 }
    306 
    307 static char * in_get_parameters(const struct audio_stream *stream,
    308                                 const char *keys)
    309 {
    310     struct generic_stream_in *in = (struct generic_stream_in *)stream;
    311     struct str_parms *query = str_parms_create_str(keys);
    312     char *str;
    313     char value[256];
    314     struct str_parms *reply = str_parms_create();
    315     int ret;
    316 
    317     ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
    318     if (ret >= 0) {
    319         str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, in->device);
    320         str = strdup(str_parms_to_str(reply));
    321     } else {
    322         str = strdup(keys);
    323     }
    324 
    325     str_parms_destroy(query);
    326     str_parms_destroy(reply);
    327     return str;
    328 }
    329 
    330 static int in_set_gain(struct audio_stream_in *stream, float gain)
    331 {
    332     // in_set_gain is a no op
    333     return 0;
    334 }
    335 
    336 static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
    337                        size_t bytes)
    338 {
    339     struct generic_stream_in *in = (struct generic_stream_in *)stream;
    340     struct generic_audio_device *adev = in->dev;
    341 
    342     pthread_mutex_lock(&adev->lock);
    343     if (adev->fd >= 0)
    344         bytes = read(adev->fd, buffer, bytes);
    345     if (adev->mic_mute && (bytes > 0)) {
    346         memset(buffer, 0, bytes);
    347     }
    348     pthread_mutex_unlock(&adev->lock);
    349 
    350     return bytes;
    351 }
    352 
    353 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
    354 {
    355     return 0;
    356 }
    357 
    358 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    359 {
    360     // in_add_audio_effect is a no op
    361     return 0;
    362 }
    363 
    364 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
    365 {
    366     // in_add_audio_effect is a no op
    367     return 0;
    368 }
    369 
    370 static int adev_open_output_stream(struct audio_hw_device *dev,
    371                                    audio_io_handle_t handle,
    372                                    audio_devices_t devices,
    373                                    audio_output_flags_t flags,
    374                                    struct audio_config *config,
    375                                    struct audio_stream_out **stream_out,
    376                                    const char *address __unused)
    377 {
    378     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    379     struct generic_stream_out *out;
    380     static const uint32_t sample_rates [] = { 44100, 48000 };
    381     static const int sample_rates_count = sizeof(sample_rates)/sizeof(sample_rates[0]);
    382     int ret = 0;
    383 
    384     pthread_mutex_lock(&adev->lock);
    385     if (adev->output != NULL) {
    386         ret = -ENOSYS;
    387         goto error;
    388     }
    389 
    390     if ((config->format != AUDIO_FORMAT_PCM_16_BIT) ||
    391         (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) ) {
    392         ALOGE("Error opening output stream, format %d, channel_mask %04x",
    393               config->format, config->channel_mask);
    394         config->format = AUDIO_FORMAT_PCM_16_BIT;
    395         config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
    396         ret = -EINVAL;
    397     }
    398 
    399     for (int idx = 0; idx < sample_rates_count; idx++) {
    400         if (config->sample_rate < sample_rates[idx]) {
    401             config->sample_rate = sample_rates[idx];
    402             ALOGE("Error opening output stream, sample_rate %u", config->sample_rate);
    403             ret = -EINVAL;
    404             break;
    405         } else if (config->sample_rate == sample_rates[idx]) {
    406             break;
    407         } else if (idx == sample_rates_count-1) {
    408             // Cap it to the highest rate we support
    409             config->sample_rate = sample_rates[idx];
    410             ALOGE("Error opening output stream, sample_rate %u", config->sample_rate);
    411             ret = -EINVAL;
    412         }
    413     }
    414 
    415     if (ret != 0) goto error;
    416 
    417     out = (struct generic_stream_out *)calloc(1, sizeof(struct generic_stream_out));
    418 
    419     out->stream.common.get_sample_rate = out_get_sample_rate;
    420     out->stream.common.set_sample_rate = out_set_sample_rate;
    421     out->stream.common.get_buffer_size = out_get_buffer_size;
    422     out->stream.common.get_channels = out_get_channels;
    423     out->stream.common.get_format = out_get_format;
    424     out->stream.common.set_format = out_set_format;
    425     out->stream.common.standby = out_standby;
    426     out->stream.common.dump = out_dump;
    427     out->stream.common.set_parameters = out_set_parameters;
    428     out->stream.common.get_parameters = out_get_parameters;
    429     out->stream.common.add_audio_effect = out_add_audio_effect;
    430     out->stream.common.remove_audio_effect = out_remove_audio_effect;
    431     out->stream.get_latency = out_get_latency;
    432     out->stream.set_volume = out_set_volume;
    433     out->stream.write = out_write;
    434     out->stream.get_render_position = out_get_render_position;
    435     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
    436     out->sample_rate = config->sample_rate;
    437 
    438     out->dev = adev;
    439     out->device = devices;
    440     adev->output = (struct audio_stream_out *)out;
    441     *stream_out = &out->stream;
    442 
    443 error:
    444     pthread_mutex_unlock(&adev->lock);
    445 
    446     return ret;
    447 }
    448 
    449 static void adev_close_output_stream(struct audio_hw_device *dev,
    450                                      struct audio_stream_out *stream)
    451 {
    452     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    453 
    454     pthread_mutex_lock(&adev->lock);
    455     if (stream == adev->output) {
    456         free(stream);
    457         adev->output = NULL;
    458     }
    459     pthread_mutex_unlock(&adev->lock);
    460 }
    461 
    462 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
    463 {
    464     return 0;
    465 }
    466 
    467 static char * adev_get_parameters(const struct audio_hw_device *dev,
    468                                   const char *keys)
    469 {
    470     return strdup("");
    471 }
    472 
    473 static int adev_init_check(const struct audio_hw_device *dev)
    474 {
    475     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    476 
    477     if (adev->fd >= 0)
    478         return 0;
    479 
    480     return -ENODEV;
    481 }
    482 
    483 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
    484 {
    485     // adev_set_voice_volume is a no op (simulates phones)
    486     return 0;
    487 }
    488 
    489 static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
    490 {
    491     return -ENOSYS;
    492 }
    493 
    494 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
    495 {
    496     return -ENOSYS;
    497 }
    498 
    499 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
    500 {
    501     return -ENOSYS;
    502 }
    503 
    504 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
    505 {
    506     return -ENOSYS;
    507 }
    508 
    509 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
    510 {
    511     // adev_set_mode is a no op (simulates phones)
    512     return 0;
    513 }
    514 
    515 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
    516 {
    517     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    518 
    519     pthread_mutex_lock(&adev->lock);
    520     adev->mic_mute = state;
    521     pthread_mutex_unlock(&adev->lock);
    522     return 0;
    523 }
    524 
    525 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
    526 {
    527     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    528 
    529     pthread_mutex_lock(&adev->lock);
    530     *state = adev->mic_mute;
    531     pthread_mutex_unlock(&adev->lock);
    532 
    533     return 0;
    534 }
    535 
    536 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
    537                                          const struct audio_config *config)
    538 {
    539     return IN_BUFFER_SIZE;
    540 }
    541 
    542 static int adev_open_input_stream(struct audio_hw_device *dev,
    543                                   audio_io_handle_t handle,
    544                                   audio_devices_t devices,
    545                                   struct audio_config *config,
    546                                   struct audio_stream_in **stream_in,
    547                                   audio_input_flags_t flags __unused,
    548                                   const char *address __unused,
    549                                   audio_source_t source __unused)
    550 {
    551     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    552     struct generic_stream_in *in;
    553     int ret = 0;
    554 
    555     pthread_mutex_lock(&adev->lock);
    556     if (adev->input != NULL) {
    557         ret = -ENOSYS;
    558         goto error;
    559     }
    560 
    561     if ((config->format != AUDIO_FORMAT_PCM_16_BIT) ||
    562         (config->channel_mask != AUDIO_CHANNEL_IN_MONO) ||
    563         (config->sample_rate != IN_SAMPLING_RATE)) {
    564         ALOGE("Error opening input stream format %d, channel_mask %04x, sample_rate %u",
    565               config->format, config->channel_mask, config->sample_rate);
    566         config->format = AUDIO_FORMAT_PCM_16_BIT;
    567         config->channel_mask = AUDIO_CHANNEL_IN_MONO;
    568         config->sample_rate = IN_SAMPLING_RATE;
    569         ret = -EINVAL;
    570         goto error;
    571     }
    572 
    573     in = (struct generic_stream_in *)calloc(1, sizeof(struct generic_stream_in));
    574 
    575     in->stream.common.get_sample_rate = in_get_sample_rate;
    576     in->stream.common.set_sample_rate = in_set_sample_rate;
    577     in->stream.common.get_buffer_size = in_get_buffer_size;
    578     in->stream.common.get_channels = in_get_channels;
    579     in->stream.common.get_format = in_get_format;
    580     in->stream.common.set_format = in_set_format;
    581     in->stream.common.standby = in_standby;
    582     in->stream.common.dump = in_dump;
    583     in->stream.common.set_parameters = in_set_parameters;
    584     in->stream.common.get_parameters = in_get_parameters;
    585     in->stream.common.add_audio_effect = in_add_audio_effect;
    586     in->stream.common.remove_audio_effect = in_remove_audio_effect;
    587     in->stream.set_gain = in_set_gain;
    588     in->stream.read = in_read;
    589     in->stream.get_input_frames_lost = in_get_input_frames_lost;
    590 
    591     in->dev = adev;
    592     in->device = devices;
    593     adev->input = (struct audio_stream_in *)in;
    594     *stream_in = &in->stream;
    595 
    596 error:
    597     pthread_mutex_unlock(&adev->lock);
    598 
    599     return ret;
    600 }
    601 
    602 static void adev_close_input_stream(struct audio_hw_device *dev,
    603                                    struct audio_stream_in *stream)
    604 {
    605     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    606 
    607     pthread_mutex_lock(&adev->lock);
    608     if (stream == adev->input) {
    609         free(stream);
    610         adev->input = NULL;
    611     }
    612     pthread_mutex_unlock(&adev->lock);
    613 }
    614 
    615 static int adev_dump(const audio_hw_device_t *dev, int fd)
    616 {
    617     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    618 
    619     const size_t SIZE = 256;
    620     char buffer[SIZE];
    621 
    622     dprintf(fd, "\nadev_dump:\n"
    623                 "\tfd: %d\n"
    624                 "\tmic_mute: %s\n"
    625                 "\toutput: %p\n"
    626                 "\tinput: %p\n\n",
    627                 adev->fd,
    628                 adev->mic_mute ? "true": "false",
    629                 adev->output,
    630                 adev->input);
    631 
    632     if (adev->output != NULL)
    633         out_dump((const struct audio_stream *)adev->output, fd);
    634     if (adev->input != NULL)
    635         in_dump((const struct audio_stream *)adev->input, fd);
    636 
    637     return 0;
    638 }
    639 
    640 static int adev_close(hw_device_t *dev)
    641 {
    642     struct generic_audio_device *adev = (struct generic_audio_device *)dev;
    643 
    644     adev_close_output_stream((struct audio_hw_device *)dev, adev->output);
    645     adev_close_input_stream((struct audio_hw_device *)dev, adev->input);
    646 
    647     if (adev->fd >= 0)
    648         close(adev->fd);
    649 
    650     free(dev);
    651     return 0;
    652 }
    653 
    654 static int adev_open(const hw_module_t* module, const char* name,
    655                      hw_device_t** device)
    656 {
    657     struct generic_audio_device *adev;
    658     int fd;
    659 
    660     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
    661         return -EINVAL;
    662 
    663     fd = open(AUDIO_DEVICE_NAME, O_RDWR);
    664     if (fd < 0)
    665         return -ENOSYS;
    666 
    667     adev = calloc(1, sizeof(struct generic_audio_device));
    668 
    669     adev->fd = fd;
    670 
    671     adev->device.common.tag = HARDWARE_DEVICE_TAG;
    672     adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
    673     adev->device.common.module = (struct hw_module_t *) module;
    674     adev->device.common.close = adev_close;
    675 
    676     adev->device.init_check = adev_init_check;
    677     adev->device.set_voice_volume = adev_set_voice_volume;
    678     adev->device.set_master_volume = adev_set_master_volume;
    679     adev->device.get_master_volume = adev_get_master_volume;
    680     adev->device.set_master_mute = adev_set_master_mute;
    681     adev->device.get_master_mute = adev_get_master_mute;
    682     adev->device.set_mode = adev_set_mode;
    683     adev->device.set_mic_mute = adev_set_mic_mute;
    684     adev->device.get_mic_mute = adev_get_mic_mute;
    685     adev->device.set_parameters = adev_set_parameters;
    686     adev->device.get_parameters = adev_get_parameters;
    687     adev->device.get_input_buffer_size = adev_get_input_buffer_size;
    688     adev->device.open_output_stream = adev_open_output_stream;
    689     adev->device.close_output_stream = adev_close_output_stream;
    690     adev->device.open_input_stream = adev_open_input_stream;
    691     adev->device.close_input_stream = adev_close_input_stream;
    692     adev->device.dump = adev_dump;
    693 
    694     *device = &adev->device.common;
    695 
    696     return 0;
    697 }
    698 
    699 static struct hw_module_methods_t hal_module_methods = {
    700     .open = adev_open,
    701 };
    702 
    703 struct audio_module HAL_MODULE_INFO_SYM = {
    704     .common = {
    705         .tag = HARDWARE_MODULE_TAG,
    706         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
    707         .hal_api_version = HARDWARE_HAL_API_VERSION,
    708         .id = AUDIO_HARDWARE_MODULE_ID,
    709         .name = "Generic audio HW HAL",
    710         .author = "The Android Open Source Project",
    711         .methods = &hal_module_methods,
    712     },
    713 };
    714