18cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin/*
28cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * Copyright (C) 2011 The Android Open Source Project
38cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin *
48cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * Licensed under the Apache License, Version 2.0 (the "License");
58cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * you may not use this file except in compliance with the License.
68cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * You may obtain a copy of the License at
78cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin *
88cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin *      http://www.apache.org/licenses/LICENSE-2.0
98cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin *
108cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * Unless required by applicable law or agreed to in writing, software
118cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * distributed under the License is distributed on an "AS IS" BASIS,
128cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * See the License for the specific language governing permissions and
148cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin * limitations under the License.
158cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin */
168cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
178cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin#define LOG_TAG "audio_hw_default"
188cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin//#define LOG_NDEBUG 0
198cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
208cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin#include <errno.h>
2107c085565a3b24bb658d05b8aa08fb7420725602Elliott Hughes#include <malloc.h>
228cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin#include <pthread.h>
238cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin#include <stdint.h>
248cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin#include <sys/time.h>
258cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2602b5d168f2c2427489a54ea58defd6d602c46968Steven Moreland#include <log/log.h>
278cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
288cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin#include <hardware/hardware.h>
29aa21172bcd4c332eec78d34ffdafd8cc0178ea95Dima Zavin#include <system/audio.h>
303bc15860a9d8eea076dc19128373631bf1e162caDima Zavin#include <hardware/audio.h>
318cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
328cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstruct stub_audio_device {
338cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    struct audio_hw_device device;
348cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin};
358cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
368cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstruct stub_stream_out {
378cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    struct audio_stream_out stream;
380caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    int64_t last_write_time_us;
398cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin};
408cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
418cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstruct stub_stream_in {
428cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    struct audio_stream_in stream;
430caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    int64_t last_read_time_us;
448cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin};
458cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
468cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic uint32_t out_get_sample_rate(const struct audio_stream *stream)
478cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
488cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 44100;
498cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
508cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
518cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
528cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
5337cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_set_sample_rate: %d", 0);
5437cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    return -ENOSYS;
558cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
568cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
578cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic size_t out_get_buffer_size(const struct audio_stream *stream)
588cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
5937cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_get_buffer_size: %d", 4096);
608cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 4096;
618cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
628cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
63a635449697a2df5de98e72cfc24e926b641d5544Glenn Kastenstatic audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
648cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
6537cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_get_channels");
668cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return AUDIO_CHANNEL_OUT_STEREO;
678cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
688cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
69fe79eb3f06967f863a637e546eb4421d0da2283bGlenn Kastenstatic audio_format_t out_get_format(const struct audio_stream *stream)
708cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
7137cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_get_format");
728cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return AUDIO_FORMAT_PCM_16_BIT;
738cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
748cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
75fe79eb3f06967f863a637e546eb4421d0da2283bGlenn Kastenstatic int out_set_format(struct audio_stream *stream, audio_format_t format)
768cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
7737cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_set_format: %d",format);
7837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    return -ENOSYS;
798cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
808cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
818cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int out_standby(struct audio_stream *stream)
828cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
8337cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_standby");
840caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
858cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
868cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
878cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
888cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int out_dump(const struct audio_stream *stream, int fd)
898cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
9037cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_dump");
918cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
928cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
938cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
948cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
958cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
9637cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_set_parameters");
978cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
988cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
998cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
1008cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic char * out_get_parameters(const struct audio_stream *stream, const char *keys)
1018cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
10237cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_get_parameters");
1038cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return strdup("");
1048cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1058cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
1068cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic uint32_t out_get_latency(const struct audio_stream_out *stream)
1078cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
10837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_get_latency");
1098cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
1108cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1118cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
1128cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int out_set_volume(struct audio_stream_out *stream, float left,
1138cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                          float right)
1148cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
11537cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_set_volume: Left:%f Right:%f", left, right);
1168cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
1178cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1188cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
1198cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
1208cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                         size_t bytes)
1218cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
1226c59aadad93e98e221b6bcd897c9f51795f9e711Greg Kaiser    ALOGV("out_write: bytes: %zu", bytes);
1230caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung
1248cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    /* XXX: fake timing for audio output */
1250caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    struct stub_stream_out *out = (struct stub_stream_out *)stream;
1260caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
1270caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    clock_gettime(CLOCK_MONOTONIC, &t);
1280caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
1290caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
1300caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
1310caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung               out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
1320caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    if (sleep_time > 0) {
1330caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung        usleep(sleep_time);
1340caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    } else {
1350caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung        // we don't sleep when we exit standby (this is typical for a real alsa buffer).
1360caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung        sleep_time = 0;
1370caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    }
1380caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    out->last_write_time_us = now + sleep_time;
1390caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // last_write_time_us is an approximation of when the (simulated) alsa
1400caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // buffer is believed completely full. The usleep above waits for more space
1410caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // in the buffer, but by the end of the sleep the buffer is considered
1420caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // topped-off.
1430caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    //
1440caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // On the subsequent out_write(), we measure the elapsed time spent in
1450caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // the mixer. This is subtracted from the sleep estimate based on frames,
1460caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // thereby accounting for drain in the alsa buffer during mixing.
1470caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // This is a crude approximation; we don't handle underruns precisely.
1488cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return bytes;
1498cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1508cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
1518cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int out_get_render_position(const struct audio_stream_out *stream,
1528cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                                   uint32_t *dsp_frames)
1538cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
15437cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    *dsp_frames = 0;
155e03bfa4f5ce895cf7389daa5f74419c05da471c0Glenn Kasten    ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
1568cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return -EINVAL;
1578cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1588cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
159f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurentstatic int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
160f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent{
161e03bfa4f5ce895cf7389daa5f74419c05da471c0Glenn Kasten    ALOGV("out_add_audio_effect: %p", effect);
162f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    return 0;
163f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent}
164f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent
165f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurentstatic int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
166f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent{
167e03bfa4f5ce895cf7389daa5f74419c05da471c0Glenn Kasten    ALOGV("out_remove_audio_effect: %p", effect);
168f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    return 0;
169f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent}
170f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent
1715ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chenstatic int out_get_next_write_timestamp(const struct audio_stream_out *stream,
1725ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen                                        int64_t *timestamp)
1735ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen{
17437cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    *timestamp = 0;
17537cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
1765ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen    return -EINVAL;
1775ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen}
1785ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen
1798cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin/** audio_stream_in implementation **/
1808cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic uint32_t in_get_sample_rate(const struct audio_stream *stream)
1818cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
18237cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("in_get_sample_rate");
1838cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 8000;
1848cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1858cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
1868cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
1878cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
18837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("in_set_sample_rate: %d", rate);
18937cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    return -ENOSYS;
1908cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1918cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
1928cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic size_t in_get_buffer_size(const struct audio_stream *stream)
1938cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
19437cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("in_get_buffer_size: %d", 320);
1958cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 320;
1968cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
1978cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
198a635449697a2df5de98e72cfc24e926b641d5544Glenn Kastenstatic audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
1998cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
20037cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("in_get_channels: %d", AUDIO_CHANNEL_IN_MONO);
2018cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return AUDIO_CHANNEL_IN_MONO;
2028cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2038cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
204fe79eb3f06967f863a637e546eb4421d0da2283bGlenn Kastenstatic audio_format_t in_get_format(const struct audio_stream *stream)
2058cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2068cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return AUDIO_FORMAT_PCM_16_BIT;
2078cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2088cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
209fe79eb3f06967f863a637e546eb4421d0da2283bGlenn Kastenstatic int in_set_format(struct audio_stream *stream, audio_format_t format)
2108cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
21137cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    return -ENOSYS;
2128cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2138cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2148cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int in_standby(struct audio_stream *stream)
2158cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2160caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    struct stub_stream_in *in = (struct stub_stream_in *)stream;
2170caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    in->last_read_time_us = 0;
2188cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
2198cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2208cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2218cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int in_dump(const struct audio_stream *stream, int fd)
2228cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2238cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
2248cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2258cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2268cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
2278cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2288cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
2298cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2308cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2318cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic char * in_get_parameters(const struct audio_stream *stream,
2328cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                                const char *keys)
2338cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2348cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return strdup("");
2358cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2368cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2378cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int in_set_gain(struct audio_stream_in *stream, float gain)
2388cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2398cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
2408cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2418cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2428cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic ssize_t in_read(struct audio_stream_in *stream, void* buffer,
2438cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                       size_t bytes)
2448cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2456c59aadad93e98e221b6bcd897c9f51795f9e711Greg Kaiser    ALOGV("in_read: bytes %zu", bytes);
2460caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung
2478cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    /* XXX: fake timing for audio input */
2480caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    struct stub_stream_in *in = (struct stub_stream_in *)stream;
2490caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
2500caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    clock_gettime(CLOCK_MONOTONIC, &t);
2510caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
2520caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung
2530caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // we do a full sleep when exiting standby.
2540caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    const bool standby = in->last_read_time_us == 0;
2550caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    const int64_t elapsed_time_since_last_read = standby ?
2560caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung            0 : now - in->last_read_time_us;
2570caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
2580caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung            in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
2590caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    if (sleep_time > 0) {
2600caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung        usleep(sleep_time);
2610caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    } else {
2620caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung        sleep_time = 0;
2630caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    }
2640caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    in->last_read_time_us = now + sleep_time;
2650caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // last_read_time_us is an approximation of when the (simulated) alsa
2660caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // buffer is drained by the read, and is empty.
2670caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    //
2680caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // On the subsequent in_read(), we measure the elapsed time spent in
2690caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // the recording thread. This is subtracted from the sleep estimate based on frames,
2700caeee8ac429dd8098e97b2cd8ad3751031a5b67Andy Hung    // thereby accounting for fill in the alsa buffer during the interim.
27137cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    memset(buffer, 0, bytes);
2728cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return bytes;
2738cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2748cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2758cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
2768cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
2778cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
2788cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
2798cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
280f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurentstatic int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
281f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent{
282f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    return 0;
283f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent}
284f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent
285f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurentstatic int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
286f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent{
287f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    return 0;
288f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent}
2898cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
2908cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_open_output_stream(struct audio_hw_device *dev,
29155786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                   audio_io_handle_t handle,
29255786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                   audio_devices_t devices,
29355786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                   audio_output_flags_t flags,
29455786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                   struct audio_config *config,
295f5e2469c02825f018df6336125882812003b8e64Eric Laurent                                   struct audio_stream_out **stream_out,
296f5e2469c02825f018df6336125882812003b8e64Eric Laurent                                   const char *address __unused)
2978cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
29837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_open_output_stream...");
29937cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia
3002494caec3659f9e324e5d453fe1d2494f7138251Glenn Kasten    *stream_out = NULL;
3012494caec3659f9e324e5d453fe1d2494f7138251Glenn Kasten    struct stub_stream_out *out =
3022494caec3659f9e324e5d453fe1d2494f7138251Glenn Kasten            (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
3038cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    if (!out)
3048cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        return -ENOMEM;
3058cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3068cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.get_sample_rate = out_get_sample_rate;
3078cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.set_sample_rate = out_set_sample_rate;
3088cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.get_buffer_size = out_get_buffer_size;
3098cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.get_channels = out_get_channels;
3108cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.get_format = out_get_format;
3118cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.set_format = out_set_format;
3128cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.standby = out_standby;
3138cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.dump = out_dump;
3148cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.set_parameters = out_set_parameters;
3158cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.common.get_parameters = out_get_parameters;
316f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    out->stream.common.add_audio_effect = out_add_audio_effect;
317f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    out->stream.common.remove_audio_effect = out_remove_audio_effect;
3188cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.get_latency = out_get_latency;
3198cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.set_volume = out_set_volume;
3208cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.write = out_write;
3218cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    out->stream.get_render_position = out_get_render_position;
3225ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen    out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
3238cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3248cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    *stream_out = &out->stream;
3258cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
3268cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3278cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3288cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic void adev_close_output_stream(struct audio_hw_device *dev,
3298cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                                     struct audio_stream_out *stream)
3308cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
33137cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_close_output_stream...");
3328cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    free(stream);
3338cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3348cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3358cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
3368cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
33737cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_set_parameters");
3388cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return -ENOSYS;
3398cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3408cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3418cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic char * adev_get_parameters(const struct audio_hw_device *dev,
3428cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                                  const char *keys)
3438cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
34437cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_get_parameters");
34537cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    return strdup("");
3468cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3478cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3488cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_init_check(const struct audio_hw_device *dev)
3498cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
35037cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_init_check");
3518cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
3528cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3538cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3548cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
3558cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
35637cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_set_voice_volume: %f", volume);
3578cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return -ENOSYS;
3588cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3598cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3608cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_set_master_volume(struct audio_hw_device *dev, float volume)
3618cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
36237cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_set_master_volume: %f", volume);
3638cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return -ENOSYS;
3648cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3658cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
36647bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossmanstatic int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
36747bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman{
36837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_get_master_volume: %f", *volume);
36947bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman    return -ENOSYS;
37047bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman}
37147bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman
37247bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossmanstatic int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
37347bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman{
37437cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_set_master_mute: %d", muted);
37547bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman    return -ENOSYS;
37647bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman}
37747bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman
37847bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossmanstatic int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
3795ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen{
38037cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_get_master_mute: %d", *muted);
3815ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen    return -ENOSYS;
3825ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen}
3835ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen
3846df641e269639dbb81bb1c19f47d3b9e5e3ff7d7Glenn Kastenstatic int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
3858cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
38637cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_set_mode: %d", mode);
3878cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
3888cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3898cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3908cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
3918cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
39237cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_set_mic_mute: %d",state);
3938cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return -ENOSYS;
3948cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
3958cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
3968cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
3978cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
39837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_get_mic_mute");
3998cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return -ENOSYS;
4008cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
4018cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4028cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
40355786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                         const struct audio_config *config)
4048cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
40537cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_get_input_buffer_size: %d", 320);
4068cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 320;
4078cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
4088cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
40955786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurentstatic int adev_open_input_stream(struct audio_hw_device *dev,
41055786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                  audio_io_handle_t handle,
41155786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                  audio_devices_t devices,
41255786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent                                  struct audio_config *config,
4137d973adff4c9b344b530dd7c585f789d02c605daGlenn Kasten                                  struct audio_stream_in **stream_in,
414f5e2469c02825f018df6336125882812003b8e64Eric Laurent                                  audio_input_flags_t flags __unused,
415f5e2469c02825f018df6336125882812003b8e64Eric Laurent                                  const char *address __unused,
416f5e2469c02825f018df6336125882812003b8e64Eric Laurent                                  audio_source_t source __unused)
4178cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
41837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_open_input_stream...");
41937cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia
4202494caec3659f9e324e5d453fe1d2494f7138251Glenn Kasten    *stream_in = NULL;
4212494caec3659f9e324e5d453fe1d2494f7138251Glenn Kasten    struct stub_stream_in *in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
4228cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    if (!in)
4238cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        return -ENOMEM;
4248cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4258cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.get_sample_rate = in_get_sample_rate;
4268cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.set_sample_rate = in_set_sample_rate;
4278cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.get_buffer_size = in_get_buffer_size;
4288cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.get_channels = in_get_channels;
4298cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.get_format = in_get_format;
4308cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.set_format = in_set_format;
4318cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.standby = in_standby;
4328cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.dump = in_dump;
4338cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.set_parameters = in_set_parameters;
4348cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.common.get_parameters = in_get_parameters;
435f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    in->stream.common.add_audio_effect = in_add_audio_effect;
436f3008aa707c1c302e8c8f9c8b759f170d972ddceEric Laurent    in->stream.common.remove_audio_effect = in_remove_audio_effect;
4378cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.set_gain = in_set_gain;
4388cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.read = in_read;
4398cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    in->stream.get_input_frames_lost = in_get_input_frames_lost;
4408cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4418cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    *stream_in = &in->stream;
4428cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
4438cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
4448cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4458cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic void adev_close_input_stream(struct audio_hw_device *dev,
4468cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                                   struct audio_stream_in *in)
4478cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
44837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_close_input_stream...");
4498cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return;
4508cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
4518cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4528cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_dump(const audio_hw_device_t *device, int fd)
4538cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
45437cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_dump");
4558cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
4568cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
4578cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4588cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_close(hw_device_t *device)
4598cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
46037cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_close");
4618cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    free(device);
4628cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
4638cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
4648cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4658cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic int adev_open(const hw_module_t* module, const char* name,
4668cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin                     hw_device_t** device)
4678cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin{
46837cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia    ALOGV("adev_open: %s", name);
46937cd77257b07d6f078763e9435487698dfb353c4Ricardo Garcia
4708cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    struct stub_audio_device *adev;
4718cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4728cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
4738cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        return -EINVAL;
4748cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4758cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev = calloc(1, sizeof(struct stub_audio_device));
4768cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    if (!adev)
4778cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        return -ENOMEM;
4788cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4798cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.common.tag = HARDWARE_DEVICE_TAG;
48085e08e26258711f2fd672d9a920d88bf91410f6bEric Laurent    adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
4818cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.common.module = (struct hw_module_t *) module;
4828cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.common.close = adev_close;
4838cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
4848cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.init_check = adev_init_check;
4858cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.set_voice_volume = adev_set_voice_volume;
4868cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.set_master_volume = adev_set_master_volume;
4875ad38a901dcca2961f3ed35ae0b206c13bc515cdMike J. Chen    adev->device.get_master_volume = adev_get_master_volume;
48847bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman    adev->device.set_master_mute = adev_set_master_mute;
48947bf3d7ea5f6c98e615e0a1f93497d241c79cc05John Grossman    adev->device.get_master_mute = adev_get_master_mute;
4908cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.set_mode = adev_set_mode;
4918cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.set_mic_mute = adev_set_mic_mute;
4928cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.get_mic_mute = adev_get_mic_mute;
4938cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.set_parameters = adev_set_parameters;
4948cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.get_parameters = adev_get_parameters;
4958cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.get_input_buffer_size = adev_get_input_buffer_size;
4968cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.open_output_stream = adev_open_output_stream;
4978cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.close_output_stream = adev_close_output_stream;
4988cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.open_input_stream = adev_open_input_stream;
4998cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.close_input_stream = adev_close_input_stream;
5008cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    adev->device.dump = adev_dump;
5018cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
5028cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    *device = &adev->device.common;
5038cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
5048cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    return 0;
5058cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin}
5068cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
5078cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstatic struct hw_module_methods_t hal_module_methods = {
5088cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    .open = adev_open,
5098cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin};
5108cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin
5118cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavinstruct audio_module HAL_MODULE_INFO_SYM = {
5128cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    .common = {
5138cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        .tag = HARDWARE_MODULE_TAG,
51455786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent        .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
51555786bcf3ced97dea8fa7ce79df2889d4d06e8a7Eric Laurent        .hal_api_version = HARDWARE_HAL_API_VERSION,
5168cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        .id = AUDIO_HARDWARE_MODULE_ID,
5178cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        .name = "Default audio HW HAL",
5188cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        .author = "The Android Open Source Project",
5198cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin        .methods = &hal_module_methods,
5208cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin    },
5218cc353abc94a557dcff0f2989f7ca6351fcfdb08Dima Zavin};
522