1 /* 2 * Copyright (C) 2012 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_generic" 18 /*#define LOG_NDEBUG 0*/ 19 20 #include <errno.h> 21 #include <pthread.h> 22 #include <stdint.h> 23 #include <stdlib.h> 24 #include <sys/time.h> 25 #include <fcntl.h> 26 27 #include <cutils/log.h> 28 #include <cutils/str_parms.h> 29 30 #include <hardware/hardware.h> 31 #include <system/audio.h> 32 #include <hardware/audio.h> 33 34 35 #define AUDIO_DEVICE_NAME "/dev/eac" 36 #define OUT_SAMPLING_RATE 44100 37 #define OUT_BUFFER_SIZE 4096 38 #define OUT_LATENCY_MS 20 39 #define IN_SAMPLING_RATE 8000 40 #define IN_BUFFER_SIZE 320 41 42 43 struct generic_audio_device { 44 struct audio_hw_device device; 45 pthread_mutex_t lock; 46 struct audio_stream_out *output; 47 struct audio_stream_in *input; 48 int fd; 49 bool mic_mute; 50 }; 51 52 53 struct generic_stream_out { 54 struct audio_stream_out stream; 55 struct generic_audio_device *dev; 56 audio_devices_t device; 57 }; 58 59 struct generic_stream_in { 60 struct audio_stream_in stream; 61 struct generic_audio_device *dev; 62 audio_devices_t device; 63 }; 64 65 66 static uint32_t out_get_sample_rate(const struct audio_stream *stream) 67 { 68 return OUT_SAMPLING_RATE; 69 } 70 71 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 72 { 73 return -ENOSYS; 74 } 75 76 static size_t out_get_buffer_size(const struct audio_stream *stream) 77 { 78 return OUT_BUFFER_SIZE; 79 } 80 81 static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) 82 { 83 return AUDIO_CHANNEL_OUT_STEREO; 84 } 85 86 static audio_format_t out_get_format(const struct audio_stream *stream) 87 { 88 return AUDIO_FORMAT_PCM_16_BIT; 89 } 90 91 static int out_set_format(struct audio_stream *stream, audio_format_t format) 92 { 93 return -ENOSYS; 94 } 95 96 static int out_standby(struct audio_stream *stream) 97 { 98 // out_standby is a no op 99 return 0; 100 } 101 102 static int out_dump(const struct audio_stream *stream, int fd) 103 { 104 struct generic_stream_out *out = (struct generic_stream_out *)stream; 105 106 fdprintf(fd, "\tout_dump:\n" 107 "\t\tsample rate: %u\n" 108 "\t\tbuffer size: %u\n" 109 "\t\tchannel mask: %08x\n" 110 "\t\tformat: %d\n" 111 "\t\tdevice: %08x\n" 112 "\t\taudio dev: %p\n\n", 113 out_get_sample_rate(stream), 114 out_get_buffer_size(stream), 115 out_get_channels(stream), 116 out_get_format(stream), 117 out->device, 118 out->dev); 119 120 return 0; 121 } 122 123 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 124 { 125 struct generic_stream_out *out = (struct generic_stream_out *)stream; 126 struct str_parms *parms; 127 char value[32]; 128 int ret; 129 long val; 130 char *end; 131 132 parms = str_parms_create_str(kvpairs); 133 134 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, 135 value, sizeof(value)); 136 if (ret >= 0) { 137 errno = 0; 138 val = strtol(value, &end, 10); 139 if (errno == 0 && (end != NULL) && (*end == '\0') && ((int)val == val)) { 140 out->device = (int)val; 141 } else { 142 ret = -EINVAL; 143 } 144 } 145 146 str_parms_destroy(parms); 147 return ret; 148 } 149 150 static char * out_get_parameters(const struct audio_stream *stream, const char *keys) 151 { 152 struct generic_stream_out *out = (struct generic_stream_out *)stream; 153 struct str_parms *query = str_parms_create_str(keys); 154 char *str; 155 char value[256]; 156 struct str_parms *reply = str_parms_create(); 157 int ret; 158 159 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); 160 if (ret >= 0) { 161 str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, out->device); 162 str = strdup(str_parms_to_str(reply)); 163 } else { 164 str = strdup(keys); 165 } 166 167 str_parms_destroy(query); 168 str_parms_destroy(reply); 169 return str; 170 } 171 172 static uint32_t out_get_latency(const struct audio_stream_out *stream) 173 { 174 return OUT_LATENCY_MS; 175 } 176 177 static int out_set_volume(struct audio_stream_out *stream, float left, 178 float right) 179 { 180 return -ENOSYS; 181 } 182 183 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 184 size_t bytes) 185 { 186 struct generic_stream_out *out = (struct generic_stream_out *)stream; 187 struct generic_audio_device *adev = out->dev; 188 189 pthread_mutex_lock(&adev->lock); 190 if (adev->fd >= 0) 191 bytes = write(adev->fd, buffer, bytes); 192 pthread_mutex_unlock(&adev->lock); 193 194 return bytes; 195 } 196 197 static int out_get_render_position(const struct audio_stream_out *stream, 198 uint32_t *dsp_frames) 199 { 200 return -ENOSYS; 201 } 202 203 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 204 { 205 // out_add_audio_effect is a no op 206 return 0; 207 } 208 209 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 210 { 211 // out_remove_audio_effect is a no op 212 return 0; 213 } 214 215 static int out_get_next_write_timestamp(const struct audio_stream_out *stream, 216 int64_t *timestamp) 217 { 218 return -ENOSYS; 219 } 220 221 /** audio_stream_in implementation **/ 222 static uint32_t in_get_sample_rate(const struct audio_stream *stream) 223 { 224 return IN_SAMPLING_RATE; 225 } 226 227 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) 228 { 229 return -ENOSYS; 230 } 231 232 static size_t in_get_buffer_size(const struct audio_stream *stream) 233 { 234 return IN_BUFFER_SIZE; 235 } 236 237 static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) 238 { 239 return AUDIO_CHANNEL_IN_MONO; 240 } 241 242 static audio_format_t in_get_format(const struct audio_stream *stream) 243 { 244 return AUDIO_FORMAT_PCM_16_BIT; 245 } 246 247 static int in_set_format(struct audio_stream *stream, audio_format_t format) 248 { 249 return -ENOSYS; 250 } 251 252 static int in_standby(struct audio_stream *stream) 253 { 254 // in_standby is a no op 255 return 0; 256 } 257 258 static int in_dump(const struct audio_stream *stream, int fd) 259 { 260 struct generic_stream_in *in = (struct generic_stream_in *)stream; 261 262 fdprintf(fd, "\tin_dump:\n" 263 "\t\tsample rate: %u\n" 264 "\t\tbuffer size: %u\n" 265 "\t\tchannel mask: %08x\n" 266 "\t\tformat: %d\n" 267 "\t\tdevice: %08x\n" 268 "\t\taudio dev: %p\n\n", 269 in_get_sample_rate(stream), 270 in_get_buffer_size(stream), 271 in_get_channels(stream), 272 in_get_format(stream), 273 in->device, 274 in->dev); 275 276 return 0; 277 } 278 279 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 280 { 281 struct generic_stream_in *in = (struct generic_stream_in *)stream; 282 struct str_parms *parms; 283 char value[32]; 284 int ret; 285 long val; 286 char *end; 287 288 parms = str_parms_create_str(kvpairs); 289 290 ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, 291 value, sizeof(value)); 292 if (ret >= 0) { 293 errno = 0; 294 val = strtol(value, &end, 10); 295 if ((errno == 0) && (end != NULL) && (*end == '\0') && ((int)val == val)) { 296 in->device = (int)val; 297 } else { 298 ret = -EINVAL; 299 } 300 } 301 302 str_parms_destroy(parms); 303 return ret; 304 } 305 306 static char * in_get_parameters(const struct audio_stream *stream, 307 const char *keys) 308 { 309 struct generic_stream_in *in = (struct generic_stream_in *)stream; 310 struct str_parms *query = str_parms_create_str(keys); 311 char *str; 312 char value[256]; 313 struct str_parms *reply = str_parms_create(); 314 int ret; 315 316 ret = str_parms_get_str(query, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value)); 317 if (ret >= 0) { 318 str_parms_add_int(reply, AUDIO_PARAMETER_STREAM_ROUTING, in->device); 319 str = strdup(str_parms_to_str(reply)); 320 } else { 321 str = strdup(keys); 322 } 323 324 str_parms_destroy(query); 325 str_parms_destroy(reply); 326 return str; 327 } 328 329 static int in_set_gain(struct audio_stream_in *stream, float gain) 330 { 331 // in_set_gain is a no op 332 return 0; 333 } 334 335 static ssize_t in_read(struct audio_stream_in *stream, void* buffer, 336 size_t bytes) 337 { 338 struct generic_stream_in *in = (struct generic_stream_in *)stream; 339 struct generic_audio_device *adev = in->dev; 340 341 pthread_mutex_lock(&adev->lock); 342 if (adev->fd >= 0) 343 bytes = read(adev->fd, buffer, bytes); 344 if (adev->mic_mute && (bytes > 0)) { 345 memset(buffer, 0, bytes); 346 } 347 pthread_mutex_unlock(&adev->lock); 348 349 return bytes; 350 } 351 352 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) 353 { 354 return 0; 355 } 356 357 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 358 { 359 // in_add_audio_effect is a no op 360 return 0; 361 } 362 363 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 364 { 365 // in_add_audio_effect is a no op 366 return 0; 367 } 368 369 static int adev_open_output_stream(struct audio_hw_device *dev, 370 audio_io_handle_t handle, 371 audio_devices_t devices, 372 audio_output_flags_t flags, 373 struct audio_config *config, 374 struct audio_stream_out **stream_out) 375 { 376 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 377 struct generic_stream_out *out; 378 int ret = 0; 379 380 pthread_mutex_lock(&adev->lock); 381 if (adev->output != NULL) { 382 ret = -ENOSYS; 383 goto error; 384 } 385 386 if ((config->format != AUDIO_FORMAT_PCM_16_BIT) || 387 (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) || 388 (config->sample_rate != OUT_SAMPLING_RATE)) { 389 ALOGE("Error opening output stream format %d, channel_mask %04x, sample_rate %u", 390 config->format, config->channel_mask, config->sample_rate); 391 config->format = AUDIO_FORMAT_PCM_16_BIT; 392 config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; 393 config->sample_rate = OUT_SAMPLING_RATE; 394 ret = -EINVAL; 395 goto error; 396 } 397 398 out = (struct generic_stream_out *)calloc(1, sizeof(struct generic_stream_out)); 399 400 out->stream.common.get_sample_rate = out_get_sample_rate; 401 out->stream.common.set_sample_rate = out_set_sample_rate; 402 out->stream.common.get_buffer_size = out_get_buffer_size; 403 out->stream.common.get_channels = out_get_channels; 404 out->stream.common.get_format = out_get_format; 405 out->stream.common.set_format = out_set_format; 406 out->stream.common.standby = out_standby; 407 out->stream.common.dump = out_dump; 408 out->stream.common.set_parameters = out_set_parameters; 409 out->stream.common.get_parameters = out_get_parameters; 410 out->stream.common.add_audio_effect = out_add_audio_effect; 411 out->stream.common.remove_audio_effect = out_remove_audio_effect; 412 out->stream.get_latency = out_get_latency; 413 out->stream.set_volume = out_set_volume; 414 out->stream.write = out_write; 415 out->stream.get_render_position = out_get_render_position; 416 out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 417 418 out->dev = adev; 419 out->device = devices; 420 adev->output = (struct audio_stream_out *)out; 421 *stream_out = &out->stream; 422 423 error: 424 pthread_mutex_unlock(&adev->lock); 425 426 return ret; 427 } 428 429 static void adev_close_output_stream(struct audio_hw_device *dev, 430 struct audio_stream_out *stream) 431 { 432 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 433 434 pthread_mutex_lock(&adev->lock); 435 if (stream == adev->output) { 436 free(stream); 437 adev->output = NULL; 438 } 439 pthread_mutex_unlock(&adev->lock); 440 } 441 442 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 443 { 444 return 0; 445 } 446 447 static char * adev_get_parameters(const struct audio_hw_device *dev, 448 const char *keys) 449 { 450 return strdup(""); 451 } 452 453 static int adev_init_check(const struct audio_hw_device *dev) 454 { 455 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 456 457 if (adev->fd >= 0) 458 return 0; 459 460 return -ENODEV; 461 } 462 463 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 464 { 465 // adev_set_voice_volume is a no op (simulates phones) 466 return 0; 467 } 468 469 static int adev_set_master_volume(struct audio_hw_device *dev, float volume) 470 { 471 return -ENOSYS; 472 } 473 474 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) 475 { 476 return -ENOSYS; 477 } 478 479 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted) 480 { 481 return -ENOSYS; 482 } 483 484 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted) 485 { 486 return -ENOSYS; 487 } 488 489 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 490 { 491 // adev_set_mode is a no op (simulates phones) 492 return 0; 493 } 494 495 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 496 { 497 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 498 499 pthread_mutex_lock(&adev->lock); 500 adev->mic_mute = state; 501 pthread_mutex_unlock(&adev->lock); 502 return 0; 503 } 504 505 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 506 { 507 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 508 509 pthread_mutex_lock(&adev->lock); 510 *state = adev->mic_mute; 511 pthread_mutex_unlock(&adev->lock); 512 513 return 0; 514 } 515 516 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 517 const struct audio_config *config) 518 { 519 return IN_BUFFER_SIZE; 520 } 521 522 static int adev_open_input_stream(struct audio_hw_device *dev, 523 audio_io_handle_t handle, 524 audio_devices_t devices, 525 struct audio_config *config, 526 struct audio_stream_in **stream_in) 527 { 528 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 529 struct generic_stream_in *in; 530 int ret = 0; 531 532 pthread_mutex_lock(&adev->lock); 533 if (adev->input != NULL) { 534 ret = -ENOSYS; 535 goto error; 536 } 537 538 if ((config->format != AUDIO_FORMAT_PCM_16_BIT) || 539 (config->channel_mask != AUDIO_CHANNEL_IN_MONO) || 540 (config->sample_rate != IN_SAMPLING_RATE)) { 541 ALOGE("Error opening input stream format %d, channel_mask %04x, sample_rate %u", 542 config->format, config->channel_mask, config->sample_rate); 543 config->format = AUDIO_FORMAT_PCM_16_BIT; 544 config->channel_mask = AUDIO_CHANNEL_IN_MONO; 545 config->sample_rate = IN_SAMPLING_RATE; 546 ret = -EINVAL; 547 goto error; 548 } 549 550 in = (struct generic_stream_in *)calloc(1, sizeof(struct generic_stream_in)); 551 552 in->stream.common.get_sample_rate = in_get_sample_rate; 553 in->stream.common.set_sample_rate = in_set_sample_rate; 554 in->stream.common.get_buffer_size = in_get_buffer_size; 555 in->stream.common.get_channels = in_get_channels; 556 in->stream.common.get_format = in_get_format; 557 in->stream.common.set_format = in_set_format; 558 in->stream.common.standby = in_standby; 559 in->stream.common.dump = in_dump; 560 in->stream.common.set_parameters = in_set_parameters; 561 in->stream.common.get_parameters = in_get_parameters; 562 in->stream.common.add_audio_effect = in_add_audio_effect; 563 in->stream.common.remove_audio_effect = in_remove_audio_effect; 564 in->stream.set_gain = in_set_gain; 565 in->stream.read = in_read; 566 in->stream.get_input_frames_lost = in_get_input_frames_lost; 567 568 in->dev = adev; 569 in->device = devices; 570 adev->input = (struct audio_stream_in *)in; 571 *stream_in = &in->stream; 572 573 error: 574 pthread_mutex_unlock(&adev->lock); 575 576 return ret; 577 } 578 579 static void adev_close_input_stream(struct audio_hw_device *dev, 580 struct audio_stream_in *stream) 581 { 582 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 583 584 pthread_mutex_lock(&adev->lock); 585 if (stream == adev->input) { 586 free(stream); 587 adev->input = NULL; 588 } 589 pthread_mutex_unlock(&adev->lock); 590 } 591 592 static int adev_dump(const audio_hw_device_t *dev, int fd) 593 { 594 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 595 596 const size_t SIZE = 256; 597 char buffer[SIZE]; 598 599 fdprintf(fd, "\nadev_dump:\n" 600 "\tfd: %d\n" 601 "\tmic_mute: %s\n" 602 "\toutput: %p\n" 603 "\tinput: %p\n\n", 604 adev->fd, 605 adev->mic_mute ? "true": "false", 606 adev->output, 607 adev->input); 608 609 if (adev->output != NULL) 610 out_dump((const struct audio_stream *)adev->output, fd); 611 if (adev->input != NULL) 612 in_dump((const struct audio_stream *)adev->input, fd); 613 614 return 0; 615 } 616 617 static int adev_close(hw_device_t *dev) 618 { 619 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 620 621 adev_close_output_stream((struct audio_hw_device *)dev, adev->output); 622 adev_close_input_stream((struct audio_hw_device *)dev, adev->input); 623 624 if (adev->fd >= 0) 625 close(adev->fd); 626 627 free(dev); 628 return 0; 629 } 630 631 static int adev_open(const hw_module_t* module, const char* name, 632 hw_device_t** device) 633 { 634 struct generic_audio_device *adev; 635 int fd; 636 637 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 638 return -EINVAL; 639 640 fd = open(AUDIO_DEVICE_NAME, O_RDWR); 641 if (fd < 0) 642 return -ENOSYS; 643 644 adev = calloc(1, sizeof(struct generic_audio_device)); 645 646 adev->fd = fd; 647 648 adev->device.common.tag = HARDWARE_DEVICE_TAG; 649 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 650 adev->device.common.module = (struct hw_module_t *) module; 651 adev->device.common.close = adev_close; 652 653 adev->device.init_check = adev_init_check; 654 adev->device.set_voice_volume = adev_set_voice_volume; 655 adev->device.set_master_volume = adev_set_master_volume; 656 adev->device.get_master_volume = adev_get_master_volume; 657 adev->device.set_master_mute = adev_set_master_mute; 658 adev->device.get_master_mute = adev_get_master_mute; 659 adev->device.set_mode = adev_set_mode; 660 adev->device.set_mic_mute = adev_set_mic_mute; 661 adev->device.get_mic_mute = adev_get_mic_mute; 662 adev->device.set_parameters = adev_set_parameters; 663 adev->device.get_parameters = adev_get_parameters; 664 adev->device.get_input_buffer_size = adev_get_input_buffer_size; 665 adev->device.open_output_stream = adev_open_output_stream; 666 adev->device.close_output_stream = adev_close_output_stream; 667 adev->device.open_input_stream = adev_open_input_stream; 668 adev->device.close_input_stream = adev_close_input_stream; 669 adev->device.dump = adev_dump; 670 671 *device = &adev->device.common; 672 673 return 0; 674 } 675 676 static struct hw_module_methods_t hal_module_methods = { 677 .open = adev_open, 678 }; 679 680 struct audio_module HAL_MODULE_INFO_SYM = { 681 .common = { 682 .tag = HARDWARE_MODULE_TAG, 683 .module_api_version = AUDIO_MODULE_API_VERSION_0_1, 684 .hal_api_version = HARDWARE_HAL_API_VERSION, 685 .id = AUDIO_HARDWARE_MODULE_ID, 686 .name = "Generic audio HW HAL", 687 .author = "The Android Open Source Project", 688 .methods = &hal_module_methods, 689 }, 690 }; 691