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
42struct 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
52struct 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
59struct generic_stream_in {
60    struct audio_stream_in stream;
61    struct generic_audio_device *dev;
62    audio_devices_t device;
63};
64
65
66static 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
72static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
73{
74    return -ENOSYS;
75}
76
77static size_t out_get_buffer_size(const struct audio_stream *stream)
78{
79    return OUT_BUFFER_SIZE;
80}
81
82static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
83{
84    return AUDIO_CHANNEL_OUT_STEREO;
85}
86
87static audio_format_t out_get_format(const struct audio_stream *stream)
88{
89    return AUDIO_FORMAT_PCM_16_BIT;
90}
91
92static int out_set_format(struct audio_stream *stream, audio_format_t format)
93{
94    return -ENOSYS;
95}
96
97static int out_standby(struct audio_stream *stream)
98{
99    // out_standby is a no op
100    return 0;
101}
102
103static 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
124static 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
151static 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
173static uint32_t out_get_latency(const struct audio_stream_out *stream)
174{
175    return OUT_LATENCY_MS;
176}
177
178static int out_set_volume(struct audio_stream_out *stream, float left,
179                          float right)
180{
181    return -ENOSYS;
182}
183
184static 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
198static int out_get_render_position(const struct audio_stream_out *stream,
199                                   uint32_t *dsp_frames)
200{
201    return -ENOSYS;
202}
203
204static 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
210static 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
216static 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 **/
223static uint32_t in_get_sample_rate(const struct audio_stream *stream)
224{
225    return IN_SAMPLING_RATE;
226}
227
228static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
229{
230    return -ENOSYS;
231}
232
233static size_t in_get_buffer_size(const struct audio_stream *stream)
234{
235    return IN_BUFFER_SIZE;
236}
237
238static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
239{
240    return AUDIO_CHANNEL_IN_MONO;
241}
242
243static audio_format_t in_get_format(const struct audio_stream *stream)
244{
245    return AUDIO_FORMAT_PCM_16_BIT;
246}
247
248static int in_set_format(struct audio_stream *stream, audio_format_t format)
249{
250    return -ENOSYS;
251}
252
253static int in_standby(struct audio_stream *stream)
254{
255    // in_standby is a no op
256    return 0;
257}
258
259static 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
280static 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
307static 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
330static 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
336static 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
353static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
354{
355    return 0;
356}
357
358static 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
364static 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
370static 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
443error:
444    pthread_mutex_unlock(&adev->lock);
445
446    return ret;
447}
448
449static 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
462static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
463{
464    return 0;
465}
466
467static char * adev_get_parameters(const struct audio_hw_device *dev,
468                                  const char *keys)
469{
470    return strdup("");
471}
472
473static 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
483static 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
489static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
490{
491    return -ENOSYS;
492}
493
494static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
495{
496    return -ENOSYS;
497}
498
499static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
500{
501    return -ENOSYS;
502}
503
504static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
505{
506    return -ENOSYS;
507}
508
509static 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
515static 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
525static 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
536static 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
542static 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
596error:
597    pthread_mutex_unlock(&adev->lock);
598
599    return ret;
600}
601
602static 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
615static 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
640static 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
654static 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
699static struct hw_module_methods_t hal_module_methods = {
700    .open = adev_open,
701};
702
703struct 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