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