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