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
44struct stub_audio_device {
45    struct audio_hw_device device;
46};
47
48struct 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
57struct 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
66static 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
74static 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
83static 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
93static 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
101static 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
109static 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
118static 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
125static int out_dump(const struct audio_stream *stream, int fd)
126{
127    ALOGV("out_dump");
128    return 0;
129}
130
131static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
132{
133    ALOGV("out_set_parameters");
134    return 0;
135}
136
137static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
138{
139    ALOGV("out_get_parameters");
140    return strdup("");
141}
142
143static 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
149static 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
156static 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
188static 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
196static 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
202static 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
208static 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 **/
217static 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
225static 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
234static 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
244static 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
252static 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
260static 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
269static 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
276static int in_dump(const struct audio_stream *stream, int fd)
277{
278    return 0;
279}
280
281static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
282{
283    return 0;
284}
285
286static char * in_get_parameters(const struct audio_stream *stream,
287                                const char *keys)
288{
289    return strdup("");
290}
291
292static int in_set_gain(struct audio_stream_in *stream, float gain)
293{
294    return 0;
295}
296
297static 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
330static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
331{
332    return 0;
333}
334
335static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
336{
337    return 0;
338}
339
340static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
341{
342    return 0;
343}
344
345static 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
352static 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
405static 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
412static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
413{
414    ALOGV("adev_set_parameters");
415    return -ENOSYS;
416}
417
418static 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
425static int adev_init_check(const struct audio_hw_device *dev)
426{
427    ALOGV("adev_init_check");
428    return 0;
429}
430
431static 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
437static 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
443static 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
449static 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
455static 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
461static 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
467static 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
473static 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
479static 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
499static 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
549static 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
556static int adev_dump(const audio_hw_device_t *device, int fd)
557{
558    ALOGV("adev_dump");
559    return 0;
560}
561
562static int adev_close(hw_device_t *device)
563{
564    ALOGV("adev_close");
565    free(device);
566    return 0;
567}
568
569static 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
611static struct hw_module_methods_t hal_module_methods = {
612    .open = adev_open,
613};
614
615struct 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