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