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