xref: /aosp_15_r20/hardware/libhardware/modules/audio/audio_hw.c (revision e01b6f769022e40d0923dee176e8dc7cd1d52984)
1*e01b6f76SAndroid Build Coastguard Worker /*
2*e01b6f76SAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*e01b6f76SAndroid Build Coastguard Worker  *
4*e01b6f76SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e01b6f76SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e01b6f76SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e01b6f76SAndroid Build Coastguard Worker  *
8*e01b6f76SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e01b6f76SAndroid Build Coastguard Worker  *
10*e01b6f76SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e01b6f76SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e01b6f76SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e01b6f76SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e01b6f76SAndroid Build Coastguard Worker  * limitations under the License.
15*e01b6f76SAndroid Build Coastguard Worker  */
16*e01b6f76SAndroid Build Coastguard Worker 
17*e01b6f76SAndroid Build Coastguard Worker #define LOG_TAG "audio_hw_default"
18*e01b6f76SAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*e01b6f76SAndroid Build Coastguard Worker 
20*e01b6f76SAndroid Build Coastguard Worker #include <errno.h>
21*e01b6f76SAndroid Build Coastguard Worker #include <malloc.h>
22*e01b6f76SAndroid Build Coastguard Worker #include <pthread.h>
23*e01b6f76SAndroid Build Coastguard Worker #include <stdint.h>
24*e01b6f76SAndroid Build Coastguard Worker #include <stdlib.h>
25*e01b6f76SAndroid Build Coastguard Worker #include <string.h>
26*e01b6f76SAndroid Build Coastguard Worker #include <time.h>
27*e01b6f76SAndroid Build Coastguard Worker #include <unistd.h>
28*e01b6f76SAndroid Build Coastguard Worker 
29*e01b6f76SAndroid Build Coastguard Worker #include <log/log.h>
30*e01b6f76SAndroid Build Coastguard Worker 
31*e01b6f76SAndroid Build Coastguard Worker #include <hardware/audio.h>
32*e01b6f76SAndroid Build Coastguard Worker #include <hardware/hardware.h>
33*e01b6f76SAndroid Build Coastguard Worker #include <system/audio.h>
34*e01b6f76SAndroid Build Coastguard Worker 
35*e01b6f76SAndroid Build Coastguard Worker #define STUB_DEFAULT_SAMPLE_RATE   48000
36*e01b6f76SAndroid Build Coastguard Worker #define STUB_DEFAULT_AUDIO_FORMAT  AUDIO_FORMAT_PCM_16_BIT
37*e01b6f76SAndroid Build Coastguard Worker 
38*e01b6f76SAndroid Build Coastguard Worker #define STUB_INPUT_BUFFER_MILLISECONDS  20
39*e01b6f76SAndroid Build Coastguard Worker #define STUB_INPUT_DEFAULT_CHANNEL_MASK AUDIO_CHANNEL_IN_STEREO
40*e01b6f76SAndroid Build Coastguard Worker 
41*e01b6f76SAndroid Build Coastguard Worker #define STUB_OUTPUT_BUFFER_MILLISECONDS  10
42*e01b6f76SAndroid Build Coastguard Worker #define STUB_OUTPUT_DEFAULT_CHANNEL_MASK AUDIO_CHANNEL_OUT_STEREO
43*e01b6f76SAndroid Build Coastguard Worker 
44*e01b6f76SAndroid Build Coastguard Worker struct stub_audio_device {
45*e01b6f76SAndroid Build Coastguard Worker     struct audio_hw_device device;
46*e01b6f76SAndroid Build Coastguard Worker };
47*e01b6f76SAndroid Build Coastguard Worker 
48*e01b6f76SAndroid Build Coastguard Worker struct stub_stream_out {
49*e01b6f76SAndroid Build Coastguard Worker     struct audio_stream_out stream;
50*e01b6f76SAndroid Build Coastguard Worker     int64_t last_write_time_us;
51*e01b6f76SAndroid Build Coastguard Worker     uint32_t sample_rate;
52*e01b6f76SAndroid Build Coastguard Worker     audio_channel_mask_t channel_mask;
53*e01b6f76SAndroid Build Coastguard Worker     audio_format_t format;
54*e01b6f76SAndroid Build Coastguard Worker     size_t frame_count;
55*e01b6f76SAndroid Build Coastguard Worker };
56*e01b6f76SAndroid Build Coastguard Worker 
57*e01b6f76SAndroid Build Coastguard Worker struct stub_stream_in {
58*e01b6f76SAndroid Build Coastguard Worker     struct audio_stream_in stream;
59*e01b6f76SAndroid Build Coastguard Worker     int64_t last_read_time_us;
60*e01b6f76SAndroid Build Coastguard Worker     uint32_t sample_rate;
61*e01b6f76SAndroid Build Coastguard Worker     audio_channel_mask_t channel_mask;
62*e01b6f76SAndroid Build Coastguard Worker     audio_format_t format;
63*e01b6f76SAndroid Build Coastguard Worker     size_t frame_count;
64*e01b6f76SAndroid Build Coastguard Worker };
65*e01b6f76SAndroid Build Coastguard Worker 
out_get_sample_rate(const struct audio_stream * stream)66*e01b6f76SAndroid Build Coastguard Worker static uint32_t out_get_sample_rate(const struct audio_stream *stream)
67*e01b6f76SAndroid Build Coastguard Worker {
68*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
69*e01b6f76SAndroid Build Coastguard Worker 
70*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_sample_rate: %u", out->sample_rate);
71*e01b6f76SAndroid Build Coastguard Worker     return out->sample_rate;
72*e01b6f76SAndroid Build Coastguard Worker }
73*e01b6f76SAndroid Build Coastguard Worker 
out_set_sample_rate(struct audio_stream * stream,uint32_t rate)74*e01b6f76SAndroid Build Coastguard Worker static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
75*e01b6f76SAndroid Build Coastguard Worker {
76*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_out *out = (struct stub_stream_out *)stream;
77*e01b6f76SAndroid Build Coastguard Worker 
78*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_set_sample_rate: %d", rate);
79*e01b6f76SAndroid Build Coastguard Worker     out->sample_rate = rate;
80*e01b6f76SAndroid Build Coastguard Worker     return 0;
81*e01b6f76SAndroid Build Coastguard Worker }
82*e01b6f76SAndroid Build Coastguard Worker 
out_get_buffer_size(const struct audio_stream * stream)83*e01b6f76SAndroid Build Coastguard Worker static size_t out_get_buffer_size(const struct audio_stream *stream)
84*e01b6f76SAndroid Build Coastguard Worker {
85*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
86*e01b6f76SAndroid Build Coastguard Worker     size_t buffer_size = out->frame_count *
87*e01b6f76SAndroid Build Coastguard Worker                          audio_stream_out_frame_size(&out->stream);
88*e01b6f76SAndroid Build Coastguard Worker 
89*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_buffer_size: %zu", buffer_size);
90*e01b6f76SAndroid Build Coastguard Worker     return buffer_size;
91*e01b6f76SAndroid Build Coastguard Worker }
92*e01b6f76SAndroid Build Coastguard Worker 
out_get_channels(const struct audio_stream * stream)93*e01b6f76SAndroid Build Coastguard Worker static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
94*e01b6f76SAndroid Build Coastguard Worker {
95*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
96*e01b6f76SAndroid Build Coastguard Worker 
97*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_channels: %x", out->channel_mask);
98*e01b6f76SAndroid Build Coastguard Worker     return out->channel_mask;
99*e01b6f76SAndroid Build Coastguard Worker }
100*e01b6f76SAndroid Build Coastguard Worker 
out_get_format(const struct audio_stream * stream)101*e01b6f76SAndroid Build Coastguard Worker static audio_format_t out_get_format(const struct audio_stream *stream)
102*e01b6f76SAndroid Build Coastguard Worker {
103*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_out *out = (const struct stub_stream_out *)stream;
104*e01b6f76SAndroid Build Coastguard Worker 
105*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_format: %d", out->format);
106*e01b6f76SAndroid Build Coastguard Worker     return out->format;
107*e01b6f76SAndroid Build Coastguard Worker }
108*e01b6f76SAndroid Build Coastguard Worker 
out_set_format(struct audio_stream * stream,audio_format_t format)109*e01b6f76SAndroid Build Coastguard Worker static int out_set_format(struct audio_stream *stream, audio_format_t format)
110*e01b6f76SAndroid Build Coastguard Worker {
111*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_out *out = (struct stub_stream_out *)stream;
112*e01b6f76SAndroid Build Coastguard Worker 
113*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_set_format: %d", format);
114*e01b6f76SAndroid Build Coastguard Worker     out->format = format;
115*e01b6f76SAndroid Build Coastguard Worker     return 0;
116*e01b6f76SAndroid Build Coastguard Worker }
117*e01b6f76SAndroid Build Coastguard Worker 
out_standby(struct audio_stream * stream)118*e01b6f76SAndroid Build Coastguard Worker static int out_standby(struct audio_stream *stream)
119*e01b6f76SAndroid Build Coastguard Worker {
120*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_standby");
121*e01b6f76SAndroid Build Coastguard Worker     // out->last_write_time_us = 0; unnecessary as a stale write time has same effect
122*e01b6f76SAndroid Build Coastguard Worker     return 0;
123*e01b6f76SAndroid Build Coastguard Worker }
124*e01b6f76SAndroid Build Coastguard Worker 
out_dump(const struct audio_stream * stream,int fd)125*e01b6f76SAndroid Build Coastguard Worker static int out_dump(const struct audio_stream *stream, int fd)
126*e01b6f76SAndroid Build Coastguard Worker {
127*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_dump");
128*e01b6f76SAndroid Build Coastguard Worker     return 0;
129*e01b6f76SAndroid Build Coastguard Worker }
130*e01b6f76SAndroid Build Coastguard Worker 
out_set_parameters(struct audio_stream * stream,const char * kvpairs)131*e01b6f76SAndroid Build Coastguard Worker static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
132*e01b6f76SAndroid Build Coastguard Worker {
133*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_set_parameters");
134*e01b6f76SAndroid Build Coastguard Worker     return 0;
135*e01b6f76SAndroid Build Coastguard Worker }
136*e01b6f76SAndroid Build Coastguard Worker 
out_get_parameters(const struct audio_stream * stream,const char * keys)137*e01b6f76SAndroid Build Coastguard Worker static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
138*e01b6f76SAndroid Build Coastguard Worker {
139*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_parameters");
140*e01b6f76SAndroid Build Coastguard Worker     return strdup("");
141*e01b6f76SAndroid Build Coastguard Worker }
142*e01b6f76SAndroid Build Coastguard Worker 
out_get_latency(const struct audio_stream_out * stream)143*e01b6f76SAndroid Build Coastguard Worker static uint32_t out_get_latency(const struct audio_stream_out *stream)
144*e01b6f76SAndroid Build Coastguard Worker {
145*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_latency");
146*e01b6f76SAndroid Build Coastguard Worker     return STUB_OUTPUT_BUFFER_MILLISECONDS;
147*e01b6f76SAndroid Build Coastguard Worker }
148*e01b6f76SAndroid Build Coastguard Worker 
out_set_volume(struct audio_stream_out * stream,float left,float right)149*e01b6f76SAndroid Build Coastguard Worker static int out_set_volume(struct audio_stream_out *stream, float left,
150*e01b6f76SAndroid Build Coastguard Worker                           float right)
151*e01b6f76SAndroid Build Coastguard Worker {
152*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_set_volume: Left:%f Right:%f", left, right);
153*e01b6f76SAndroid Build Coastguard Worker     return 0;
154*e01b6f76SAndroid Build Coastguard Worker }
155*e01b6f76SAndroid Build Coastguard Worker 
out_write(struct audio_stream_out * stream,const void * buffer,size_t bytes)156*e01b6f76SAndroid Build Coastguard Worker static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
157*e01b6f76SAndroid Build Coastguard Worker                          size_t bytes)
158*e01b6f76SAndroid Build Coastguard Worker {
159*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_write: bytes: %zu", bytes);
160*e01b6f76SAndroid Build Coastguard Worker 
161*e01b6f76SAndroid Build Coastguard Worker     /* XXX: fake timing for audio output */
162*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_out *out = (struct stub_stream_out *)stream;
163*e01b6f76SAndroid Build Coastguard Worker     struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
164*e01b6f76SAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &t);
165*e01b6f76SAndroid Build Coastguard Worker     const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
166*e01b6f76SAndroid Build Coastguard Worker     const int64_t elapsed_time_since_last_write = now - out->last_write_time_us;
167*e01b6f76SAndroid Build Coastguard Worker     int64_t sleep_time = bytes * 1000000LL / audio_stream_out_frame_size(stream) /
168*e01b6f76SAndroid Build Coastguard Worker                out_get_sample_rate(&stream->common) - elapsed_time_since_last_write;
169*e01b6f76SAndroid Build Coastguard Worker     if (sleep_time > 0) {
170*e01b6f76SAndroid Build Coastguard Worker         usleep(sleep_time);
171*e01b6f76SAndroid Build Coastguard Worker     } else {
172*e01b6f76SAndroid Build Coastguard Worker         // we don't sleep when we exit standby (this is typical for a real alsa buffer).
173*e01b6f76SAndroid Build Coastguard Worker         sleep_time = 0;
174*e01b6f76SAndroid Build Coastguard Worker     }
175*e01b6f76SAndroid Build Coastguard Worker     out->last_write_time_us = now + sleep_time;
176*e01b6f76SAndroid Build Coastguard Worker     // last_write_time_us is an approximation of when the (simulated) alsa
177*e01b6f76SAndroid Build Coastguard Worker     // buffer is believed completely full. The usleep above waits for more space
178*e01b6f76SAndroid Build Coastguard Worker     // in the buffer, but by the end of the sleep the buffer is considered
179*e01b6f76SAndroid Build Coastguard Worker     // topped-off.
180*e01b6f76SAndroid Build Coastguard Worker     //
181*e01b6f76SAndroid Build Coastguard Worker     // On the subsequent out_write(), we measure the elapsed time spent in
182*e01b6f76SAndroid Build Coastguard Worker     // the mixer. This is subtracted from the sleep estimate based on frames,
183*e01b6f76SAndroid Build Coastguard Worker     // thereby accounting for drain in the alsa buffer during mixing.
184*e01b6f76SAndroid Build Coastguard Worker     // This is a crude approximation; we don't handle underruns precisely.
185*e01b6f76SAndroid Build Coastguard Worker     return bytes;
186*e01b6f76SAndroid Build Coastguard Worker }
187*e01b6f76SAndroid Build Coastguard Worker 
out_get_render_position(const struct audio_stream_out * stream,uint32_t * dsp_frames)188*e01b6f76SAndroid Build Coastguard Worker static int out_get_render_position(const struct audio_stream_out *stream,
189*e01b6f76SAndroid Build Coastguard Worker                                    uint32_t *dsp_frames)
190*e01b6f76SAndroid Build Coastguard Worker {
191*e01b6f76SAndroid Build Coastguard Worker     *dsp_frames = 0;
192*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_render_position: dsp_frames: %p", dsp_frames);
193*e01b6f76SAndroid Build Coastguard Worker     return -EINVAL;
194*e01b6f76SAndroid Build Coastguard Worker }
195*e01b6f76SAndroid Build Coastguard Worker 
out_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)196*e01b6f76SAndroid Build Coastguard Worker static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
197*e01b6f76SAndroid Build Coastguard Worker {
198*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_add_audio_effect: %p", effect);
199*e01b6f76SAndroid Build Coastguard Worker     return 0;
200*e01b6f76SAndroid Build Coastguard Worker }
201*e01b6f76SAndroid Build Coastguard Worker 
out_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)202*e01b6f76SAndroid Build Coastguard Worker static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
203*e01b6f76SAndroid Build Coastguard Worker {
204*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_remove_audio_effect: %p", effect);
205*e01b6f76SAndroid Build Coastguard Worker     return 0;
206*e01b6f76SAndroid Build Coastguard Worker }
207*e01b6f76SAndroid Build Coastguard Worker 
out_get_next_write_timestamp(const struct audio_stream_out * stream,int64_t * timestamp)208*e01b6f76SAndroid Build Coastguard Worker static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
209*e01b6f76SAndroid Build Coastguard Worker                                         int64_t *timestamp)
210*e01b6f76SAndroid Build Coastguard Worker {
211*e01b6f76SAndroid Build Coastguard Worker     *timestamp = 0;
212*e01b6f76SAndroid Build Coastguard Worker     ALOGV("out_get_next_write_timestamp: %ld", (long int)(*timestamp));
213*e01b6f76SAndroid Build Coastguard Worker     return -EINVAL;
214*e01b6f76SAndroid Build Coastguard Worker }
215*e01b6f76SAndroid Build Coastguard Worker 
216*e01b6f76SAndroid Build Coastguard Worker /** audio_stream_in implementation **/
in_get_sample_rate(const struct audio_stream * stream)217*e01b6f76SAndroid Build Coastguard Worker static uint32_t in_get_sample_rate(const struct audio_stream *stream)
218*e01b6f76SAndroid Build Coastguard Worker {
219*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
220*e01b6f76SAndroid Build Coastguard Worker 
221*e01b6f76SAndroid Build Coastguard Worker     ALOGV("in_get_sample_rate: %u", in->sample_rate);
222*e01b6f76SAndroid Build Coastguard Worker     return in->sample_rate;
223*e01b6f76SAndroid Build Coastguard Worker }
224*e01b6f76SAndroid Build Coastguard Worker 
in_set_sample_rate(struct audio_stream * stream,uint32_t rate)225*e01b6f76SAndroid Build Coastguard Worker static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
226*e01b6f76SAndroid Build Coastguard Worker {
227*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_in *in = (struct stub_stream_in *)stream;
228*e01b6f76SAndroid Build Coastguard Worker 
229*e01b6f76SAndroid Build Coastguard Worker     ALOGV("in_set_sample_rate: %u", rate);
230*e01b6f76SAndroid Build Coastguard Worker     in->sample_rate = rate;
231*e01b6f76SAndroid Build Coastguard Worker     return 0;
232*e01b6f76SAndroid Build Coastguard Worker }
233*e01b6f76SAndroid Build Coastguard Worker 
in_get_buffer_size(const struct audio_stream * stream)234*e01b6f76SAndroid Build Coastguard Worker static size_t in_get_buffer_size(const struct audio_stream *stream)
235*e01b6f76SAndroid Build Coastguard Worker {
236*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
237*e01b6f76SAndroid Build Coastguard Worker     size_t buffer_size = in->frame_count *
238*e01b6f76SAndroid Build Coastguard Worker                          audio_stream_in_frame_size(&in->stream);
239*e01b6f76SAndroid Build Coastguard Worker 
240*e01b6f76SAndroid Build Coastguard Worker     ALOGV("in_get_buffer_size: %zu", buffer_size);
241*e01b6f76SAndroid Build Coastguard Worker     return buffer_size;
242*e01b6f76SAndroid Build Coastguard Worker }
243*e01b6f76SAndroid Build Coastguard Worker 
in_get_channels(const struct audio_stream * stream)244*e01b6f76SAndroid Build Coastguard Worker static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
245*e01b6f76SAndroid Build Coastguard Worker {
246*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
247*e01b6f76SAndroid Build Coastguard Worker 
248*e01b6f76SAndroid Build Coastguard Worker     ALOGV("in_get_channels: %x", in->channel_mask);
249*e01b6f76SAndroid Build Coastguard Worker     return in->channel_mask;
250*e01b6f76SAndroid Build Coastguard Worker }
251*e01b6f76SAndroid Build Coastguard Worker 
in_get_format(const struct audio_stream * stream)252*e01b6f76SAndroid Build Coastguard Worker static audio_format_t in_get_format(const struct audio_stream *stream)
253*e01b6f76SAndroid Build Coastguard Worker {
254*e01b6f76SAndroid Build Coastguard Worker     const struct stub_stream_in *in = (const struct stub_stream_in *)stream;
255*e01b6f76SAndroid Build Coastguard Worker 
256*e01b6f76SAndroid Build Coastguard Worker     ALOGV("in_get_format: %d", in->format);
257*e01b6f76SAndroid Build Coastguard Worker     return in->format;
258*e01b6f76SAndroid Build Coastguard Worker }
259*e01b6f76SAndroid Build Coastguard Worker 
in_set_format(struct audio_stream * stream,audio_format_t format)260*e01b6f76SAndroid Build Coastguard Worker static int in_set_format(struct audio_stream *stream, audio_format_t format)
261*e01b6f76SAndroid Build Coastguard Worker {
262*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_in *in = (struct stub_stream_in *)stream;
263*e01b6f76SAndroid Build Coastguard Worker 
264*e01b6f76SAndroid Build Coastguard Worker     ALOGV("in_set_format: %d", format);
265*e01b6f76SAndroid Build Coastguard Worker     in->format = format;
266*e01b6f76SAndroid Build Coastguard Worker     return 0;
267*e01b6f76SAndroid Build Coastguard Worker }
268*e01b6f76SAndroid Build Coastguard Worker 
in_standby(struct audio_stream * stream)269*e01b6f76SAndroid Build Coastguard Worker static int in_standby(struct audio_stream *stream)
270*e01b6f76SAndroid Build Coastguard Worker {
271*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_in *in = (struct stub_stream_in *)stream;
272*e01b6f76SAndroid Build Coastguard Worker     in->last_read_time_us = 0;
273*e01b6f76SAndroid Build Coastguard Worker     return 0;
274*e01b6f76SAndroid Build Coastguard Worker }
275*e01b6f76SAndroid Build Coastguard Worker 
in_dump(const struct audio_stream * stream,int fd)276*e01b6f76SAndroid Build Coastguard Worker static int in_dump(const struct audio_stream *stream, int fd)
277*e01b6f76SAndroid Build Coastguard Worker {
278*e01b6f76SAndroid Build Coastguard Worker     return 0;
279*e01b6f76SAndroid Build Coastguard Worker }
280*e01b6f76SAndroid Build Coastguard Worker 
in_set_parameters(struct audio_stream * stream,const char * kvpairs)281*e01b6f76SAndroid Build Coastguard Worker static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
282*e01b6f76SAndroid Build Coastguard Worker {
283*e01b6f76SAndroid Build Coastguard Worker     return 0;
284*e01b6f76SAndroid Build Coastguard Worker }
285*e01b6f76SAndroid Build Coastguard Worker 
in_get_parameters(const struct audio_stream * stream,const char * keys)286*e01b6f76SAndroid Build Coastguard Worker static char * in_get_parameters(const struct audio_stream *stream,
287*e01b6f76SAndroid Build Coastguard Worker                                 const char *keys)
288*e01b6f76SAndroid Build Coastguard Worker {
289*e01b6f76SAndroid Build Coastguard Worker     return strdup("");
290*e01b6f76SAndroid Build Coastguard Worker }
291*e01b6f76SAndroid Build Coastguard Worker 
in_set_gain(struct audio_stream_in * stream,float gain)292*e01b6f76SAndroid Build Coastguard Worker static int in_set_gain(struct audio_stream_in *stream, float gain)
293*e01b6f76SAndroid Build Coastguard Worker {
294*e01b6f76SAndroid Build Coastguard Worker     return 0;
295*e01b6f76SAndroid Build Coastguard Worker }
296*e01b6f76SAndroid Build Coastguard Worker 
in_read(struct audio_stream_in * stream,void * buffer,size_t bytes)297*e01b6f76SAndroid Build Coastguard Worker static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
298*e01b6f76SAndroid Build Coastguard Worker                        size_t bytes)
299*e01b6f76SAndroid Build Coastguard Worker {
300*e01b6f76SAndroid Build Coastguard Worker     ALOGV("in_read: bytes %zu", bytes);
301*e01b6f76SAndroid Build Coastguard Worker 
302*e01b6f76SAndroid Build Coastguard Worker     /* XXX: fake timing for audio input */
303*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_in *in = (struct stub_stream_in *)stream;
304*e01b6f76SAndroid Build Coastguard Worker     struct timespec t = { .tv_sec = 0, .tv_nsec = 0 };
305*e01b6f76SAndroid Build Coastguard Worker     clock_gettime(CLOCK_MONOTONIC, &t);
306*e01b6f76SAndroid Build Coastguard Worker     const int64_t now = (t.tv_sec * 1000000000LL + t.tv_nsec) / 1000;
307*e01b6f76SAndroid Build Coastguard Worker 
308*e01b6f76SAndroid Build Coastguard Worker     // we do a full sleep when exiting standby.
309*e01b6f76SAndroid Build Coastguard Worker     const bool standby = in->last_read_time_us == 0;
310*e01b6f76SAndroid Build Coastguard Worker     const int64_t elapsed_time_since_last_read = standby ?
311*e01b6f76SAndroid Build Coastguard Worker             0 : now - in->last_read_time_us;
312*e01b6f76SAndroid Build Coastguard Worker     int64_t sleep_time = bytes * 1000000LL / audio_stream_in_frame_size(stream) /
313*e01b6f76SAndroid Build Coastguard Worker             in_get_sample_rate(&stream->common) - elapsed_time_since_last_read;
314*e01b6f76SAndroid Build Coastguard Worker     if (sleep_time > 0) {
315*e01b6f76SAndroid Build Coastguard Worker         usleep(sleep_time);
316*e01b6f76SAndroid Build Coastguard Worker     } else {
317*e01b6f76SAndroid Build Coastguard Worker         sleep_time = 0;
318*e01b6f76SAndroid Build Coastguard Worker     }
319*e01b6f76SAndroid Build Coastguard Worker     in->last_read_time_us = now + sleep_time;
320*e01b6f76SAndroid Build Coastguard Worker     // last_read_time_us is an approximation of when the (simulated) alsa
321*e01b6f76SAndroid Build Coastguard Worker     // buffer is drained by the read, and is empty.
322*e01b6f76SAndroid Build Coastguard Worker     //
323*e01b6f76SAndroid Build Coastguard Worker     // On the subsequent in_read(), we measure the elapsed time spent in
324*e01b6f76SAndroid Build Coastguard Worker     // the recording thread. This is subtracted from the sleep estimate based on frames,
325*e01b6f76SAndroid Build Coastguard Worker     // thereby accounting for fill in the alsa buffer during the interim.
326*e01b6f76SAndroid Build Coastguard Worker     memset(buffer, 0, bytes);
327*e01b6f76SAndroid Build Coastguard Worker     return bytes;
328*e01b6f76SAndroid Build Coastguard Worker }
329*e01b6f76SAndroid Build Coastguard Worker 
in_get_input_frames_lost(struct audio_stream_in * stream)330*e01b6f76SAndroid Build Coastguard Worker static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
331*e01b6f76SAndroid Build Coastguard Worker {
332*e01b6f76SAndroid Build Coastguard Worker     return 0;
333*e01b6f76SAndroid Build Coastguard Worker }
334*e01b6f76SAndroid Build Coastguard Worker 
in_add_audio_effect(const struct audio_stream * stream,effect_handle_t effect)335*e01b6f76SAndroid Build Coastguard Worker static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
336*e01b6f76SAndroid Build Coastguard Worker {
337*e01b6f76SAndroid Build Coastguard Worker     return 0;
338*e01b6f76SAndroid Build Coastguard Worker }
339*e01b6f76SAndroid Build Coastguard Worker 
in_remove_audio_effect(const struct audio_stream * stream,effect_handle_t effect)340*e01b6f76SAndroid Build Coastguard Worker static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
341*e01b6f76SAndroid Build Coastguard Worker {
342*e01b6f76SAndroid Build Coastguard Worker     return 0;
343*e01b6f76SAndroid Build Coastguard Worker }
344*e01b6f76SAndroid Build Coastguard Worker 
samples_per_milliseconds(size_t milliseconds,uint32_t sample_rate,size_t channel_count)345*e01b6f76SAndroid Build Coastguard Worker static size_t samples_per_milliseconds(size_t milliseconds,
346*e01b6f76SAndroid Build Coastguard Worker                                        uint32_t sample_rate,
347*e01b6f76SAndroid Build Coastguard Worker                                        size_t channel_count)
348*e01b6f76SAndroid Build Coastguard Worker {
349*e01b6f76SAndroid Build Coastguard Worker     return milliseconds * sample_rate * channel_count / 1000;
350*e01b6f76SAndroid Build Coastguard Worker }
351*e01b6f76SAndroid Build Coastguard Worker 
adev_open_output_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,struct audio_stream_out ** stream_out,const char * address __unused)352*e01b6f76SAndroid Build Coastguard Worker static int adev_open_output_stream(struct audio_hw_device *dev,
353*e01b6f76SAndroid Build Coastguard Worker                                    audio_io_handle_t handle,
354*e01b6f76SAndroid Build Coastguard Worker                                    audio_devices_t devices,
355*e01b6f76SAndroid Build Coastguard Worker                                    audio_output_flags_t flags,
356*e01b6f76SAndroid Build Coastguard Worker                                    struct audio_config *config,
357*e01b6f76SAndroid Build Coastguard Worker                                    struct audio_stream_out **stream_out,
358*e01b6f76SAndroid Build Coastguard Worker                                    const char *address __unused)
359*e01b6f76SAndroid Build Coastguard Worker {
360*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_open_output_stream...");
361*e01b6f76SAndroid Build Coastguard Worker 
362*e01b6f76SAndroid Build Coastguard Worker     *stream_out = NULL;
363*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_out *out =
364*e01b6f76SAndroid Build Coastguard Worker             (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
365*e01b6f76SAndroid Build Coastguard Worker     if (!out)
366*e01b6f76SAndroid Build Coastguard Worker         return -ENOMEM;
367*e01b6f76SAndroid Build Coastguard Worker 
368*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.get_sample_rate = out_get_sample_rate;
369*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.set_sample_rate = out_set_sample_rate;
370*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.get_buffer_size = out_get_buffer_size;
371*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.get_channels = out_get_channels;
372*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.get_format = out_get_format;
373*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.set_format = out_set_format;
374*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.standby = out_standby;
375*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.dump = out_dump;
376*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.set_parameters = out_set_parameters;
377*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.get_parameters = out_get_parameters;
378*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.add_audio_effect = out_add_audio_effect;
379*e01b6f76SAndroid Build Coastguard Worker     out->stream.common.remove_audio_effect = out_remove_audio_effect;
380*e01b6f76SAndroid Build Coastguard Worker     out->stream.get_latency = out_get_latency;
381*e01b6f76SAndroid Build Coastguard Worker     out->stream.set_volume = out_set_volume;
382*e01b6f76SAndroid Build Coastguard Worker     out->stream.write = out_write;
383*e01b6f76SAndroid Build Coastguard Worker     out->stream.get_render_position = out_get_render_position;
384*e01b6f76SAndroid Build Coastguard Worker     out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
385*e01b6f76SAndroid Build Coastguard Worker     out->sample_rate = config->sample_rate;
386*e01b6f76SAndroid Build Coastguard Worker     if (out->sample_rate == 0)
387*e01b6f76SAndroid Build Coastguard Worker         out->sample_rate = STUB_DEFAULT_SAMPLE_RATE;
388*e01b6f76SAndroid Build Coastguard Worker     out->channel_mask = config->channel_mask;
389*e01b6f76SAndroid Build Coastguard Worker     if (out->channel_mask == AUDIO_CHANNEL_NONE)
390*e01b6f76SAndroid Build Coastguard Worker         out->channel_mask = STUB_OUTPUT_DEFAULT_CHANNEL_MASK;
391*e01b6f76SAndroid Build Coastguard Worker     out->format = config->format;
392*e01b6f76SAndroid Build Coastguard Worker     if (out->format == AUDIO_FORMAT_DEFAULT)
393*e01b6f76SAndroid Build Coastguard Worker         out->format = STUB_DEFAULT_AUDIO_FORMAT;
394*e01b6f76SAndroid Build Coastguard Worker     out->frame_count = samples_per_milliseconds(
395*e01b6f76SAndroid Build Coastguard Worker                            STUB_OUTPUT_BUFFER_MILLISECONDS,
396*e01b6f76SAndroid Build Coastguard Worker                            out->sample_rate, 1);
397*e01b6f76SAndroid Build Coastguard Worker 
398*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_open_output_stream: sample_rate: %u, channels: %x, format: %d,"
399*e01b6f76SAndroid Build Coastguard Worker           " frames: %zu", out->sample_rate, out->channel_mask, out->format,
400*e01b6f76SAndroid Build Coastguard Worker           out->frame_count);
401*e01b6f76SAndroid Build Coastguard Worker     *stream_out = &out->stream;
402*e01b6f76SAndroid Build Coastguard Worker     return 0;
403*e01b6f76SAndroid Build Coastguard Worker }
404*e01b6f76SAndroid Build Coastguard Worker 
adev_close_output_stream(struct audio_hw_device * dev,struct audio_stream_out * stream)405*e01b6f76SAndroid Build Coastguard Worker static void adev_close_output_stream(struct audio_hw_device *dev,
406*e01b6f76SAndroid Build Coastguard Worker                                      struct audio_stream_out *stream)
407*e01b6f76SAndroid Build Coastguard Worker {
408*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_close_output_stream...");
409*e01b6f76SAndroid Build Coastguard Worker     free(stream);
410*e01b6f76SAndroid Build Coastguard Worker }
411*e01b6f76SAndroid Build Coastguard Worker 
adev_set_parameters(struct audio_hw_device * dev,const char * kvpairs)412*e01b6f76SAndroid Build Coastguard Worker static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
413*e01b6f76SAndroid Build Coastguard Worker {
414*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_set_parameters");
415*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
416*e01b6f76SAndroid Build Coastguard Worker }
417*e01b6f76SAndroid Build Coastguard Worker 
adev_get_parameters(const struct audio_hw_device * dev,const char * keys)418*e01b6f76SAndroid Build Coastguard Worker static char * adev_get_parameters(const struct audio_hw_device *dev,
419*e01b6f76SAndroid Build Coastguard Worker                                   const char *keys)
420*e01b6f76SAndroid Build Coastguard Worker {
421*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_get_parameters");
422*e01b6f76SAndroid Build Coastguard Worker     return strdup("");
423*e01b6f76SAndroid Build Coastguard Worker }
424*e01b6f76SAndroid Build Coastguard Worker 
adev_init_check(const struct audio_hw_device * dev)425*e01b6f76SAndroid Build Coastguard Worker static int adev_init_check(const struct audio_hw_device *dev)
426*e01b6f76SAndroid Build Coastguard Worker {
427*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_init_check");
428*e01b6f76SAndroid Build Coastguard Worker     return 0;
429*e01b6f76SAndroid Build Coastguard Worker }
430*e01b6f76SAndroid Build Coastguard Worker 
adev_set_voice_volume(struct audio_hw_device * dev,float volume)431*e01b6f76SAndroid Build Coastguard Worker static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
432*e01b6f76SAndroid Build Coastguard Worker {
433*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_set_voice_volume: %f", volume);
434*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
435*e01b6f76SAndroid Build Coastguard Worker }
436*e01b6f76SAndroid Build Coastguard Worker 
adev_set_master_volume(struct audio_hw_device * dev,float volume)437*e01b6f76SAndroid Build Coastguard Worker static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
438*e01b6f76SAndroid Build Coastguard Worker {
439*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_set_master_volume: %f", volume);
440*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
441*e01b6f76SAndroid Build Coastguard Worker }
442*e01b6f76SAndroid Build Coastguard Worker 
adev_get_master_volume(struct audio_hw_device * dev,float * volume)443*e01b6f76SAndroid Build Coastguard Worker static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
444*e01b6f76SAndroid Build Coastguard Worker {
445*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_get_master_volume: %f", *volume);
446*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
447*e01b6f76SAndroid Build Coastguard Worker }
448*e01b6f76SAndroid Build Coastguard Worker 
adev_set_master_mute(struct audio_hw_device * dev,bool muted)449*e01b6f76SAndroid Build Coastguard Worker static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
450*e01b6f76SAndroid Build Coastguard Worker {
451*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_set_master_mute: %d", muted);
452*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
453*e01b6f76SAndroid Build Coastguard Worker }
454*e01b6f76SAndroid Build Coastguard Worker 
adev_get_master_mute(struct audio_hw_device * dev,bool * muted)455*e01b6f76SAndroid Build Coastguard Worker static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
456*e01b6f76SAndroid Build Coastguard Worker {
457*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_get_master_mute: %d", *muted);
458*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
459*e01b6f76SAndroid Build Coastguard Worker }
460*e01b6f76SAndroid Build Coastguard Worker 
adev_set_mode(struct audio_hw_device * dev,audio_mode_t mode)461*e01b6f76SAndroid Build Coastguard Worker static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
462*e01b6f76SAndroid Build Coastguard Worker {
463*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_set_mode: %d", mode);
464*e01b6f76SAndroid Build Coastguard Worker     return 0;
465*e01b6f76SAndroid Build Coastguard Worker }
466*e01b6f76SAndroid Build Coastguard Worker 
adev_set_mic_mute(struct audio_hw_device * dev,bool state)467*e01b6f76SAndroid Build Coastguard Worker static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
468*e01b6f76SAndroid Build Coastguard Worker {
469*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_set_mic_mute: %d",state);
470*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
471*e01b6f76SAndroid Build Coastguard Worker }
472*e01b6f76SAndroid Build Coastguard Worker 
adev_get_mic_mute(const struct audio_hw_device * dev,bool * state)473*e01b6f76SAndroid Build Coastguard Worker static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
474*e01b6f76SAndroid Build Coastguard Worker {
475*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_get_mic_mute");
476*e01b6f76SAndroid Build Coastguard Worker     return -ENOSYS;
477*e01b6f76SAndroid Build Coastguard Worker }
478*e01b6f76SAndroid Build Coastguard Worker 
adev_get_input_buffer_size(const struct audio_hw_device * dev,const struct audio_config * config)479*e01b6f76SAndroid Build Coastguard Worker static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
480*e01b6f76SAndroid Build Coastguard Worker                                          const struct audio_config *config)
481*e01b6f76SAndroid Build Coastguard Worker {
482*e01b6f76SAndroid Build Coastguard Worker     size_t buffer_size = samples_per_milliseconds(
483*e01b6f76SAndroid Build Coastguard Worker                              STUB_INPUT_BUFFER_MILLISECONDS,
484*e01b6f76SAndroid Build Coastguard Worker                              config->sample_rate,
485*e01b6f76SAndroid Build Coastguard Worker                              audio_channel_count_from_in_mask(
486*e01b6f76SAndroid Build Coastguard Worker                                  config->channel_mask));
487*e01b6f76SAndroid Build Coastguard Worker 
488*e01b6f76SAndroid Build Coastguard Worker     if (!audio_has_proportional_frames(config->format)) {
489*e01b6f76SAndroid Build Coastguard Worker         // Since the audio data is not proportional choose an arbitrary size for
490*e01b6f76SAndroid Build Coastguard Worker         // the buffer.
491*e01b6f76SAndroid Build Coastguard Worker         buffer_size *= 4;
492*e01b6f76SAndroid Build Coastguard Worker     } else {
493*e01b6f76SAndroid Build Coastguard Worker         buffer_size *= audio_bytes_per_sample(config->format);
494*e01b6f76SAndroid Build Coastguard Worker     }
495*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_get_input_buffer_size: %zu", buffer_size);
496*e01b6f76SAndroid Build Coastguard Worker     return buffer_size;
497*e01b6f76SAndroid Build Coastguard Worker }
498*e01b6f76SAndroid Build Coastguard Worker 
adev_open_input_stream(struct audio_hw_device * dev,audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,struct audio_stream_in ** stream_in,audio_input_flags_t flags __unused,const char * address __unused,audio_source_t source __unused)499*e01b6f76SAndroid Build Coastguard Worker static int adev_open_input_stream(struct audio_hw_device *dev,
500*e01b6f76SAndroid Build Coastguard Worker                                   audio_io_handle_t handle,
501*e01b6f76SAndroid Build Coastguard Worker                                   audio_devices_t devices,
502*e01b6f76SAndroid Build Coastguard Worker                                   struct audio_config *config,
503*e01b6f76SAndroid Build Coastguard Worker                                   struct audio_stream_in **stream_in,
504*e01b6f76SAndroid Build Coastguard Worker                                   audio_input_flags_t flags __unused,
505*e01b6f76SAndroid Build Coastguard Worker                                   const char *address __unused,
506*e01b6f76SAndroid Build Coastguard Worker                                   audio_source_t source __unused)
507*e01b6f76SAndroid Build Coastguard Worker {
508*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_open_input_stream...");
509*e01b6f76SAndroid Build Coastguard Worker 
510*e01b6f76SAndroid Build Coastguard Worker     *stream_in = NULL;
511*e01b6f76SAndroid Build Coastguard Worker     struct stub_stream_in *in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
512*e01b6f76SAndroid Build Coastguard Worker     if (!in)
513*e01b6f76SAndroid Build Coastguard Worker         return -ENOMEM;
514*e01b6f76SAndroid Build Coastguard Worker 
515*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.get_sample_rate = in_get_sample_rate;
516*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.set_sample_rate = in_set_sample_rate;
517*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.get_buffer_size = in_get_buffer_size;
518*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.get_channels = in_get_channels;
519*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.get_format = in_get_format;
520*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.set_format = in_set_format;
521*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.standby = in_standby;
522*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.dump = in_dump;
523*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.set_parameters = in_set_parameters;
524*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.get_parameters = in_get_parameters;
525*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.add_audio_effect = in_add_audio_effect;
526*e01b6f76SAndroid Build Coastguard Worker     in->stream.common.remove_audio_effect = in_remove_audio_effect;
527*e01b6f76SAndroid Build Coastguard Worker     in->stream.set_gain = in_set_gain;
528*e01b6f76SAndroid Build Coastguard Worker     in->stream.read = in_read;
529*e01b6f76SAndroid Build Coastguard Worker     in->stream.get_input_frames_lost = in_get_input_frames_lost;
530*e01b6f76SAndroid Build Coastguard Worker     in->sample_rate = config->sample_rate;
531*e01b6f76SAndroid Build Coastguard Worker     if (in->sample_rate == 0)
532*e01b6f76SAndroid Build Coastguard Worker         in->sample_rate = STUB_DEFAULT_SAMPLE_RATE;
533*e01b6f76SAndroid Build Coastguard Worker     in->channel_mask = config->channel_mask;
534*e01b6f76SAndroid Build Coastguard Worker     if (in->channel_mask == AUDIO_CHANNEL_NONE)
535*e01b6f76SAndroid Build Coastguard Worker         in->channel_mask = STUB_INPUT_DEFAULT_CHANNEL_MASK;
536*e01b6f76SAndroid Build Coastguard Worker     in->format = config->format;
537*e01b6f76SAndroid Build Coastguard Worker     if (in->format == AUDIO_FORMAT_DEFAULT)
538*e01b6f76SAndroid Build Coastguard Worker         in->format = STUB_DEFAULT_AUDIO_FORMAT;
539*e01b6f76SAndroid Build Coastguard Worker     in->frame_count = samples_per_milliseconds(
540*e01b6f76SAndroid Build Coastguard Worker                           STUB_INPUT_BUFFER_MILLISECONDS, in->sample_rate, 1);
541*e01b6f76SAndroid Build Coastguard Worker 
542*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_open_input_stream: sample_rate: %u, channels: %x, format: %d,"
543*e01b6f76SAndroid Build Coastguard Worker           "frames: %zu", in->sample_rate, in->channel_mask, in->format,
544*e01b6f76SAndroid Build Coastguard Worker           in->frame_count);
545*e01b6f76SAndroid Build Coastguard Worker     *stream_in = &in->stream;
546*e01b6f76SAndroid Build Coastguard Worker     return 0;
547*e01b6f76SAndroid Build Coastguard Worker }
548*e01b6f76SAndroid Build Coastguard Worker 
adev_close_input_stream(struct audio_hw_device * dev,struct audio_stream_in * in)549*e01b6f76SAndroid Build Coastguard Worker static void adev_close_input_stream(struct audio_hw_device *dev,
550*e01b6f76SAndroid Build Coastguard Worker                                    struct audio_stream_in *in)
551*e01b6f76SAndroid Build Coastguard Worker {
552*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_close_input_stream...");
553*e01b6f76SAndroid Build Coastguard Worker     return;
554*e01b6f76SAndroid Build Coastguard Worker }
555*e01b6f76SAndroid Build Coastguard Worker 
adev_dump(const audio_hw_device_t * device,int fd)556*e01b6f76SAndroid Build Coastguard Worker static int adev_dump(const audio_hw_device_t *device, int fd)
557*e01b6f76SAndroid Build Coastguard Worker {
558*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_dump");
559*e01b6f76SAndroid Build Coastguard Worker     return 0;
560*e01b6f76SAndroid Build Coastguard Worker }
561*e01b6f76SAndroid Build Coastguard Worker 
adev_close(hw_device_t * device)562*e01b6f76SAndroid Build Coastguard Worker static int adev_close(hw_device_t *device)
563*e01b6f76SAndroid Build Coastguard Worker {
564*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_close");
565*e01b6f76SAndroid Build Coastguard Worker     free(device);
566*e01b6f76SAndroid Build Coastguard Worker     return 0;
567*e01b6f76SAndroid Build Coastguard Worker }
568*e01b6f76SAndroid Build Coastguard Worker 
adev_open(const hw_module_t * module,const char * name,hw_device_t ** device)569*e01b6f76SAndroid Build Coastguard Worker static int adev_open(const hw_module_t* module, const char* name,
570*e01b6f76SAndroid Build Coastguard Worker                      hw_device_t** device)
571*e01b6f76SAndroid Build Coastguard Worker {
572*e01b6f76SAndroid Build Coastguard Worker     ALOGV("adev_open: %s", name);
573*e01b6f76SAndroid Build Coastguard Worker 
574*e01b6f76SAndroid Build Coastguard Worker     struct stub_audio_device *adev;
575*e01b6f76SAndroid Build Coastguard Worker 
576*e01b6f76SAndroid Build Coastguard Worker     if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
577*e01b6f76SAndroid Build Coastguard Worker         return -EINVAL;
578*e01b6f76SAndroid Build Coastguard Worker 
579*e01b6f76SAndroid Build Coastguard Worker     adev = calloc(1, sizeof(struct stub_audio_device));
580*e01b6f76SAndroid Build Coastguard Worker     if (!adev)
581*e01b6f76SAndroid Build Coastguard Worker         return -ENOMEM;
582*e01b6f76SAndroid Build Coastguard Worker 
583*e01b6f76SAndroid Build Coastguard Worker     adev->device.common.tag = HARDWARE_DEVICE_TAG;
584*e01b6f76SAndroid Build Coastguard Worker     adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
585*e01b6f76SAndroid Build Coastguard Worker     adev->device.common.module = (struct hw_module_t *) module;
586*e01b6f76SAndroid Build Coastguard Worker     adev->device.common.close = adev_close;
587*e01b6f76SAndroid Build Coastguard Worker 
588*e01b6f76SAndroid Build Coastguard Worker     adev->device.init_check = adev_init_check;
589*e01b6f76SAndroid Build Coastguard Worker     adev->device.set_voice_volume = adev_set_voice_volume;
590*e01b6f76SAndroid Build Coastguard Worker     adev->device.set_master_volume = adev_set_master_volume;
591*e01b6f76SAndroid Build Coastguard Worker     adev->device.get_master_volume = adev_get_master_volume;
592*e01b6f76SAndroid Build Coastguard Worker     adev->device.set_master_mute = adev_set_master_mute;
593*e01b6f76SAndroid Build Coastguard Worker     adev->device.get_master_mute = adev_get_master_mute;
594*e01b6f76SAndroid Build Coastguard Worker     adev->device.set_mode = adev_set_mode;
595*e01b6f76SAndroid Build Coastguard Worker     adev->device.set_mic_mute = adev_set_mic_mute;
596*e01b6f76SAndroid Build Coastguard Worker     adev->device.get_mic_mute = adev_get_mic_mute;
597*e01b6f76SAndroid Build Coastguard Worker     adev->device.set_parameters = adev_set_parameters;
598*e01b6f76SAndroid Build Coastguard Worker     adev->device.get_parameters = adev_get_parameters;
599*e01b6f76SAndroid Build Coastguard Worker     adev->device.get_input_buffer_size = adev_get_input_buffer_size;
600*e01b6f76SAndroid Build Coastguard Worker     adev->device.open_output_stream = adev_open_output_stream;
601*e01b6f76SAndroid Build Coastguard Worker     adev->device.close_output_stream = adev_close_output_stream;
602*e01b6f76SAndroid Build Coastguard Worker     adev->device.open_input_stream = adev_open_input_stream;
603*e01b6f76SAndroid Build Coastguard Worker     adev->device.close_input_stream = adev_close_input_stream;
604*e01b6f76SAndroid Build Coastguard Worker     adev->device.dump = adev_dump;
605*e01b6f76SAndroid Build Coastguard Worker 
606*e01b6f76SAndroid Build Coastguard Worker     *device = &adev->device.common;
607*e01b6f76SAndroid Build Coastguard Worker 
608*e01b6f76SAndroid Build Coastguard Worker     return 0;
609*e01b6f76SAndroid Build Coastguard Worker }
610*e01b6f76SAndroid Build Coastguard Worker 
611*e01b6f76SAndroid Build Coastguard Worker static struct hw_module_methods_t hal_module_methods = {
612*e01b6f76SAndroid Build Coastguard Worker     .open = adev_open,
613*e01b6f76SAndroid Build Coastguard Worker };
614*e01b6f76SAndroid Build Coastguard Worker 
615*e01b6f76SAndroid Build Coastguard Worker struct audio_module HAL_MODULE_INFO_SYM = {
616*e01b6f76SAndroid Build Coastguard Worker     .common = {
617*e01b6f76SAndroid Build Coastguard Worker         .tag = HARDWARE_MODULE_TAG,
618*e01b6f76SAndroid Build Coastguard Worker         .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
619*e01b6f76SAndroid Build Coastguard Worker         .hal_api_version = HARDWARE_HAL_API_VERSION,
620*e01b6f76SAndroid Build Coastguard Worker         .id = AUDIO_HARDWARE_MODULE_ID,
621*e01b6f76SAndroid Build Coastguard Worker         .name = "Default audio HW HAL",
622*e01b6f76SAndroid Build Coastguard Worker         .author = "The Android Open Source Project",
623*e01b6f76SAndroid Build Coastguard Worker         .methods = &hal_module_methods,
624*e01b6f76SAndroid Build Coastguard Worker     },
625*e01b6f76SAndroid Build Coastguard Worker };
626