blob: 637e3f4b5f7070b52b2e4250b90ebd02e3682f99 [file] [log] [blame]
Dima Zavin8cc353a2011-04-20 16:38:05 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "audio_hw_default"
18//#define LOG_NDEBUG 0
19
20#include <errno.h>
Elliott Hughes07c08552015-01-29 21:19:10 -080021#include <malloc.h>
Dima Zavin8cc353a2011-04-20 16:38:05 -070022#include <pthread.h>
23#include <stdint.h>
24#include <sys/time.h>
25
26#include <cutils/log.h>
27
28#include <hardware/hardware.h>
Dima Zavinaa211722011-05-11 14:15:53 -070029#include <system/audio.h>
Dima Zavin3bc15862011-06-13 17:59:54 -070030#include <hardware/audio.h>
Dima Zavin8cc353a2011-04-20 16:38:05 -070031
32struct stub_audio_device {
33 struct audio_hw_device device;
34};
35
36struct stub_stream_out {
37 struct audio_stream_out stream;
38};
39
40struct stub_stream_in {
41 struct audio_stream_in stream;
42};
43
44static uint32_t out_get_sample_rate(const struct audio_stream *stream)
45{
46 return 44100;
47}
48
49static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate)
50{
51 return 0;
52}
53
54static size_t out_get_buffer_size(const struct audio_stream *stream)
55{
56 return 4096;
57}
58
Glenn Kastena6354492012-06-19 12:16:04 -070059static audio_channel_mask_t out_get_channels(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -070060{
61 return AUDIO_CHANNEL_OUT_STEREO;
62}
63
Glenn Kastenfe79eb32012-01-12 14:55:57 -080064static audio_format_t out_get_format(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -070065{
66 return AUDIO_FORMAT_PCM_16_BIT;
67}
68
Glenn Kastenfe79eb32012-01-12 14:55:57 -080069static int out_set_format(struct audio_stream *stream, audio_format_t format)
Dima Zavin8cc353a2011-04-20 16:38:05 -070070{
71 return 0;
72}
73
74static int out_standby(struct audio_stream *stream)
75{
76 return 0;
77}
78
79static int out_dump(const struct audio_stream *stream, int fd)
80{
81 return 0;
82}
83
84static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
85{
86 return 0;
87}
88
89static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
90{
91 return strdup("");
92}
93
94static uint32_t out_get_latency(const struct audio_stream_out *stream)
95{
96 return 0;
97}
98
99static int out_set_volume(struct audio_stream_out *stream, float left,
100 float right)
101{
102 return 0;
103}
104
105static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
106 size_t bytes)
107{
108 /* XXX: fake timing for audio output */
Eric Laurentc5ae6a02014-07-02 13:45:32 -0700109 usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
Dima Zavin8cc353a2011-04-20 16:38:05 -0700110 out_get_sample_rate(&stream->common));
111 return bytes;
112}
113
114static int out_get_render_position(const struct audio_stream_out *stream,
115 uint32_t *dsp_frames)
116{
117 return -EINVAL;
118}
119
Eric Laurentf3008aa2011-06-17 16:53:12 -0700120static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
121{
122 return 0;
123}
124
125static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
126{
127 return 0;
128}
129
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700130static int out_get_next_write_timestamp(const struct audio_stream_out *stream,
131 int64_t *timestamp)
132{
133 return -EINVAL;
134}
135
Dima Zavin8cc353a2011-04-20 16:38:05 -0700136/** audio_stream_in implementation **/
137static uint32_t in_get_sample_rate(const struct audio_stream *stream)
138{
139 return 8000;
140}
141
142static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate)
143{
144 return 0;
145}
146
147static size_t in_get_buffer_size(const struct audio_stream *stream)
148{
149 return 320;
150}
151
Glenn Kastena6354492012-06-19 12:16:04 -0700152static audio_channel_mask_t in_get_channels(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700153{
154 return AUDIO_CHANNEL_IN_MONO;
155}
156
Glenn Kastenfe79eb32012-01-12 14:55:57 -0800157static audio_format_t in_get_format(const struct audio_stream *stream)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700158{
159 return AUDIO_FORMAT_PCM_16_BIT;
160}
161
Glenn Kastenfe79eb32012-01-12 14:55:57 -0800162static int in_set_format(struct audio_stream *stream, audio_format_t format)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700163{
164 return 0;
165}
166
167static int in_standby(struct audio_stream *stream)
168{
169 return 0;
170}
171
172static int in_dump(const struct audio_stream *stream, int fd)
173{
174 return 0;
175}
176
177static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
178{
179 return 0;
180}
181
182static char * in_get_parameters(const struct audio_stream *stream,
183 const char *keys)
184{
185 return strdup("");
186}
187
188static int in_set_gain(struct audio_stream_in *stream, float gain)
189{
190 return 0;
191}
192
193static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
194 size_t bytes)
195{
196 /* XXX: fake timing for audio input */
Eric Laurentc5ae6a02014-07-02 13:45:32 -0700197 usleep(bytes * 1000000 / audio_stream_in_frame_size(stream) /
Dima Zavin8cc353a2011-04-20 16:38:05 -0700198 in_get_sample_rate(&stream->common));
199 return bytes;
200}
201
202static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream)
203{
204 return 0;
205}
206
Eric Laurentf3008aa2011-06-17 16:53:12 -0700207static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
208{
209 return 0;
210}
211
212static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect)
213{
214 return 0;
215}
Dima Zavin8cc353a2011-04-20 16:38:05 -0700216
217static int adev_open_output_stream(struct audio_hw_device *dev,
Eric Laurent55786bc2012-04-10 16:56:32 -0700218 audio_io_handle_t handle,
219 audio_devices_t devices,
220 audio_output_flags_t flags,
221 struct audio_config *config,
Eric Laurentf5e24692014-07-27 16:14:57 -0700222 struct audio_stream_out **stream_out,
223 const char *address __unused)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700224{
225 struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
226 struct stub_stream_out *out;
227 int ret;
228
229 out = (struct stub_stream_out *)calloc(1, sizeof(struct stub_stream_out));
230 if (!out)
231 return -ENOMEM;
232
233 out->stream.common.get_sample_rate = out_get_sample_rate;
234 out->stream.common.set_sample_rate = out_set_sample_rate;
235 out->stream.common.get_buffer_size = out_get_buffer_size;
236 out->stream.common.get_channels = out_get_channels;
237 out->stream.common.get_format = out_get_format;
238 out->stream.common.set_format = out_set_format;
239 out->stream.common.standby = out_standby;
240 out->stream.common.dump = out_dump;
241 out->stream.common.set_parameters = out_set_parameters;
242 out->stream.common.get_parameters = out_get_parameters;
Eric Laurentf3008aa2011-06-17 16:53:12 -0700243 out->stream.common.add_audio_effect = out_add_audio_effect;
244 out->stream.common.remove_audio_effect = out_remove_audio_effect;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700245 out->stream.get_latency = out_get_latency;
246 out->stream.set_volume = out_set_volume;
247 out->stream.write = out_write;
248 out->stream.get_render_position = out_get_render_position;
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700249 out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700250
251 *stream_out = &out->stream;
252 return 0;
253
254err_open:
255 free(out);
256 *stream_out = NULL;
257 return ret;
258}
259
260static void adev_close_output_stream(struct audio_hw_device *dev,
261 struct audio_stream_out *stream)
262{
263 free(stream);
264}
265
266static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
267{
268 return -ENOSYS;
269}
270
271static char * adev_get_parameters(const struct audio_hw_device *dev,
272 const char *keys)
273{
274 return NULL;
275}
276
277static int adev_init_check(const struct audio_hw_device *dev)
278{
279 return 0;
280}
281
282static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
283{
284 return -ENOSYS;
285}
286
287static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
288{
289 return -ENOSYS;
290}
291
John Grossman47bf3d72012-07-17 11:54:04 -0700292static int adev_get_master_volume(struct audio_hw_device *dev, float *volume)
293{
294 return -ENOSYS;
295}
296
297static int adev_set_master_mute(struct audio_hw_device *dev, bool muted)
298{
299 return -ENOSYS;
300}
301
302static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted)
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700303{
304 return -ENOSYS;
305}
306
Glenn Kasten6df641e2012-01-09 10:41:30 -0800307static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700308{
309 return 0;
310}
311
312static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
313{
314 return -ENOSYS;
315}
316
317static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
318{
319 return -ENOSYS;
320}
321
322static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
Eric Laurent55786bc2012-04-10 16:56:32 -0700323 const struct audio_config *config)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700324{
325 return 320;
326}
327
Eric Laurent55786bc2012-04-10 16:56:32 -0700328static int adev_open_input_stream(struct audio_hw_device *dev,
329 audio_io_handle_t handle,
330 audio_devices_t devices,
331 struct audio_config *config,
Glenn Kasten7d973ad2014-07-15 11:10:38 -0700332 struct audio_stream_in **stream_in,
Eric Laurentf5e24692014-07-27 16:14:57 -0700333 audio_input_flags_t flags __unused,
334 const char *address __unused,
335 audio_source_t source __unused)
Dima Zavin8cc353a2011-04-20 16:38:05 -0700336{
337 struct stub_audio_device *ladev = (struct stub_audio_device *)dev;
338 struct stub_stream_in *in;
339 int ret;
340
341 in = (struct stub_stream_in *)calloc(1, sizeof(struct stub_stream_in));
342 if (!in)
343 return -ENOMEM;
344
345 in->stream.common.get_sample_rate = in_get_sample_rate;
346 in->stream.common.set_sample_rate = in_set_sample_rate;
347 in->stream.common.get_buffer_size = in_get_buffer_size;
348 in->stream.common.get_channels = in_get_channels;
349 in->stream.common.get_format = in_get_format;
350 in->stream.common.set_format = in_set_format;
351 in->stream.common.standby = in_standby;
352 in->stream.common.dump = in_dump;
353 in->stream.common.set_parameters = in_set_parameters;
354 in->stream.common.get_parameters = in_get_parameters;
Eric Laurentf3008aa2011-06-17 16:53:12 -0700355 in->stream.common.add_audio_effect = in_add_audio_effect;
356 in->stream.common.remove_audio_effect = in_remove_audio_effect;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700357 in->stream.set_gain = in_set_gain;
358 in->stream.read = in_read;
359 in->stream.get_input_frames_lost = in_get_input_frames_lost;
360
361 *stream_in = &in->stream;
362 return 0;
363
364err_open:
365 free(in);
366 *stream_in = NULL;
367 return ret;
368}
369
370static void adev_close_input_stream(struct audio_hw_device *dev,
371 struct audio_stream_in *in)
372{
373 return;
374}
375
376static int adev_dump(const audio_hw_device_t *device, int fd)
377{
378 return 0;
379}
380
381static int adev_close(hw_device_t *device)
382{
383 free(device);
384 return 0;
385}
386
Dima Zavin8cc353a2011-04-20 16:38:05 -0700387static int adev_open(const hw_module_t* module, const char* name,
388 hw_device_t** device)
389{
390 struct stub_audio_device *adev;
391 int ret;
392
393 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
394 return -EINVAL;
395
396 adev = calloc(1, sizeof(struct stub_audio_device));
397 if (!adev)
398 return -ENOMEM;
399
400 adev->device.common.tag = HARDWARE_DEVICE_TAG;
Eric Laurent85e08e22012-08-28 14:30:35 -0700401 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700402 adev->device.common.module = (struct hw_module_t *) module;
403 adev->device.common.close = adev_close;
404
Dima Zavin8cc353a2011-04-20 16:38:05 -0700405 adev->device.init_check = adev_init_check;
406 adev->device.set_voice_volume = adev_set_voice_volume;
407 adev->device.set_master_volume = adev_set_master_volume;
Mike J. Chen5ad38a92011-08-15 12:05:00 -0700408 adev->device.get_master_volume = adev_get_master_volume;
John Grossman47bf3d72012-07-17 11:54:04 -0700409 adev->device.set_master_mute = adev_set_master_mute;
410 adev->device.get_master_mute = adev_get_master_mute;
Dima Zavin8cc353a2011-04-20 16:38:05 -0700411 adev->device.set_mode = adev_set_mode;
412 adev->device.set_mic_mute = adev_set_mic_mute;
413 adev->device.get_mic_mute = adev_get_mic_mute;
414 adev->device.set_parameters = adev_set_parameters;
415 adev->device.get_parameters = adev_get_parameters;
416 adev->device.get_input_buffer_size = adev_get_input_buffer_size;
417 adev->device.open_output_stream = adev_open_output_stream;
418 adev->device.close_output_stream = adev_close_output_stream;
419 adev->device.open_input_stream = adev_open_input_stream;
420 adev->device.close_input_stream = adev_close_input_stream;
421 adev->device.dump = adev_dump;
422
423 *device = &adev->device.common;
424
425 return 0;
426}
427
428static struct hw_module_methods_t hal_module_methods = {
429 .open = adev_open,
430};
431
432struct audio_module HAL_MODULE_INFO_SYM = {
433 .common = {
434 .tag = HARDWARE_MODULE_TAG,
Eric Laurent55786bc2012-04-10 16:56:32 -0700435 .module_api_version = AUDIO_MODULE_API_VERSION_0_1,
436 .hal_api_version = HARDWARE_HAL_API_VERSION,
Dima Zavin8cc353a2011-04-20 16:38:05 -0700437 .id = AUDIO_HARDWARE_MODULE_ID,
438 .name = "Default audio HW HAL",
439 .author = "The Android Open Source Project",
440 .methods = &hal_module_methods,
441 },
442};