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 dprintf(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 dprintf(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 const char *address __unused) 376 { 377 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 378 struct generic_stream_out *out; 379 int ret = 0; 380 381 pthread_mutex_lock(&adev->lock); 382 if (adev->output != NULL) { 383 ret = -ENOSYS; 384 goto error; 385 } 386 387 if ((config->format != AUDIO_FORMAT_PCM_16_BIT) || 388 (config->channel_mask != AUDIO_CHANNEL_OUT_STEREO) || 389 (config->sample_rate != OUT_SAMPLING_RATE)) { 390 ALOGE("Error opening output stream format %d, channel_mask %04x, sample_rate %u", 391 config->format, config->channel_mask, config->sample_rate); 392 config->format = AUDIO_FORMAT_PCM_16_BIT; 393 config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; 394 config->sample_rate = OUT_SAMPLING_RATE; 395 ret = -EINVAL; 396 goto error; 397 } 398 399 out = (struct generic_stream_out *)calloc(1, sizeof(struct generic_stream_out)); 400 401 out->stream.common.get_sample_rate = out_get_sample_rate; 402 out->stream.common.set_sample_rate = out_set_sample_rate; 403 out->stream.common.get_buffer_size = out_get_buffer_size; 404 out->stream.common.get_channels = out_get_channels; 405 out->stream.common.get_format = out_get_format; 406 out->stream.common.set_format = out_set_format; 407 out->stream.common.standby = out_standby; 408 out->stream.common.dump = out_dump; 409 out->stream.common.set_parameters = out_set_parameters; 410 out->stream.common.get_parameters = out_get_parameters; 411 out->stream.common.add_audio_effect = out_add_audio_effect; 412 out->stream.common.remove_audio_effect = out_remove_audio_effect; 413 out->stream.get_latency = out_get_latency; 414 out->stream.set_volume = out_set_volume; 415 out->stream.write = out_write; 416 out->stream.get_render_position = out_get_render_position; 417 out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 418 419 out->dev = adev; 420 out->device = devices; 421 adev->output = (struct audio_stream_out *)out; 422 *stream_out = &out->stream; 423 424 error: 425 pthread_mutex_unlock(&adev->lock); 426 427 return ret; 428 } 429 430 static void adev_close_output_stream(struct audio_hw_device *dev, 431 struct audio_stream_out *stream) 432 { 433 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 434 435 pthread_mutex_lock(&adev->lock); 436 if (stream == adev->output) { 437 free(stream); 438 adev->output = NULL; 439 } 440 pthread_mutex_unlock(&adev->lock); 441 } 442 443 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 444 { 445 return 0; 446 } 447 448 static char * adev_get_parameters(const struct audio_hw_device *dev, 449 const char *keys) 450 { 451 return strdup(""); 452 } 453 454 static int adev_init_check(const struct audio_hw_device *dev) 455 { 456 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 457 458 if (adev->fd >= 0) 459 return 0; 460 461 return -ENODEV; 462 } 463 464 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 465 { 466 // adev_set_voice_volume is a no op (simulates phones) 467 return 0; 468 } 469 470 static int adev_set_master_volume(struct audio_hw_device *dev, float volume) 471 { 472 return -ENOSYS; 473 } 474 475 static int adev_get_master_volume(struct audio_hw_device *dev, float *volume) 476 { 477 return -ENOSYS; 478 } 479 480 static int adev_set_master_mute(struct audio_hw_device *dev, bool muted) 481 { 482 return -ENOSYS; 483 } 484 485 static int adev_get_master_mute(struct audio_hw_device *dev, bool *muted) 486 { 487 return -ENOSYS; 488 } 489 490 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 491 { 492 // adev_set_mode is a no op (simulates phones) 493 return 0; 494 } 495 496 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 497 { 498 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 499 500 pthread_mutex_lock(&adev->lock); 501 adev->mic_mute = state; 502 pthread_mutex_unlock(&adev->lock); 503 return 0; 504 } 505 506 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 507 { 508 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 509 510 pthread_mutex_lock(&adev->lock); 511 *state = adev->mic_mute; 512 pthread_mutex_unlock(&adev->lock); 513 514 return 0; 515 } 516 517 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 518 const struct audio_config *config) 519 { 520 return IN_BUFFER_SIZE; 521 } 522 523 static int adev_open_input_stream(struct audio_hw_device *dev, 524 audio_io_handle_t handle, 525 audio_devices_t devices, 526 struct audio_config *config, 527 struct audio_stream_in **stream_in, 528 audio_input_flags_t flags __unused, 529 const char *address __unused, 530 audio_source_t source __unused) 531 { 532 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 533 struct generic_stream_in *in; 534 int ret = 0; 535 536 pthread_mutex_lock(&adev->lock); 537 if (adev->input != NULL) { 538 ret = -ENOSYS; 539 goto error; 540 } 541 542 if ((config->format != AUDIO_FORMAT_PCM_16_BIT) || 543 (config->channel_mask != AUDIO_CHANNEL_IN_MONO) || 544 (config->sample_rate != IN_SAMPLING_RATE)) { 545 ALOGE("Error opening input stream format %d, channel_mask %04x, sample_rate %u", 546 config->format, config->channel_mask, config->sample_rate); 547 config->format = AUDIO_FORMAT_PCM_16_BIT; 548 config->channel_mask = AUDIO_CHANNEL_IN_MONO; 549 config->sample_rate = IN_SAMPLING_RATE; 550 ret = -EINVAL; 551 goto error; 552 } 553 554 in = (struct generic_stream_in *)calloc(1, sizeof(struct generic_stream_in)); 555 556 in->stream.common.get_sample_rate = in_get_sample_rate; 557 in->stream.common.set_sample_rate = in_set_sample_rate; 558 in->stream.common.get_buffer_size = in_get_buffer_size; 559 in->stream.common.get_channels = in_get_channels; 560 in->stream.common.get_format = in_get_format; 561 in->stream.common.set_format = in_set_format; 562 in->stream.common.standby = in_standby; 563 in->stream.common.dump = in_dump; 564 in->stream.common.set_parameters = in_set_parameters; 565 in->stream.common.get_parameters = in_get_parameters; 566 in->stream.common.add_audio_effect = in_add_audio_effect; 567 in->stream.common.remove_audio_effect = in_remove_audio_effect; 568 in->stream.set_gain = in_set_gain; 569 in->stream.read = in_read; 570 in->stream.get_input_frames_lost = in_get_input_frames_lost; 571 572 in->dev = adev; 573 in->device = devices; 574 adev->input = (struct audio_stream_in *)in; 575 *stream_in = &in->stream; 576 577 error: 578 pthread_mutex_unlock(&adev->lock); 579 580 return ret; 581 } 582 583 static void adev_close_input_stream(struct audio_hw_device *dev, 584 struct audio_stream_in *stream) 585 { 586 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 587 588 pthread_mutex_lock(&adev->lock); 589 if (stream == adev->input) { 590 free(stream); 591 adev->input = NULL; 592 } 593 pthread_mutex_unlock(&adev->lock); 594 } 595 596 static int adev_dump(const audio_hw_device_t *dev, int fd) 597 { 598 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 599 600 const size_t SIZE = 256; 601 char buffer[SIZE]; 602 603 dprintf(fd, "\nadev_dump:\n" 604 "\tfd: %d\n" 605 "\tmic_mute: %s\n" 606 "\toutput: %p\n" 607 "\tinput: %p\n\n", 608 adev->fd, 609 adev->mic_mute ? "true": "false", 610 adev->output, 611 adev->input); 612 613 if (adev->output != NULL) 614 out_dump((const struct audio_stream *)adev->output, fd); 615 if (adev->input != NULL) 616 in_dump((const struct audio_stream *)adev->input, fd); 617 618 return 0; 619 } 620 621 static int adev_close(hw_device_t *dev) 622 { 623 struct generic_audio_device *adev = (struct generic_audio_device *)dev; 624 625 adev_close_output_stream((struct audio_hw_device *)dev, adev->output); 626 adev_close_input_stream((struct audio_hw_device *)dev, adev->input); 627 628 if (adev->fd >= 0) 629 close(adev->fd); 630 631 free(dev); 632 return 0; 633 } 634 635 static int adev_open(const hw_module_t* module, const char* name, 636 hw_device_t** device) 637 { 638 struct generic_audio_device *adev; 639 int fd; 640 641 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 642 return -EINVAL; 643 644 fd = open(AUDIO_DEVICE_NAME, O_RDWR); 645 if (fd < 0) 646 return -ENOSYS; 647 648 adev = calloc(1, sizeof(struct generic_audio_device)); 649 650 adev->fd = fd; 651 652 adev->device.common.tag = HARDWARE_DEVICE_TAG; 653 adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; 654 adev->device.common.module = (struct hw_module_t *) module; 655 adev->device.common.close = adev_close; 656 657 adev->device.init_check = adev_init_check; 658 adev->device.set_voice_volume = adev_set_voice_volume; 659 adev->device.set_master_volume = adev_set_master_volume; 660 adev->device.get_master_volume = adev_get_master_volume; 661 adev->device.set_master_mute = adev_set_master_mute; 662 adev->device.get_master_mute = adev_get_master_mute; 663 adev->device.set_mode = adev_set_mode; 664 adev->device.set_mic_mute = adev_set_mic_mute; 665 adev->device.get_mic_mute = adev_get_mic_mute; 666 adev->device.set_parameters = adev_set_parameters; 667 adev->device.get_parameters = adev_get_parameters; 668 adev->device.get_input_buffer_size = adev_get_input_buffer_size; 669 adev->device.open_output_stream = adev_open_output_stream; 670 adev->device.close_output_stream = adev_close_output_stream; 671 adev->device.open_input_stream = adev_open_input_stream; 672 adev->device.close_input_stream = adev_close_input_stream; 673 adev->device.dump = adev_dump; 674 675 *device = &adev->device.common; 676 677 return 0; 678 } 679 680 static struct hw_module_methods_t hal_module_methods = { 681 .open = adev_open, 682 }; 683 684 struct audio_module HAL_MODULE_INFO_SYM = { 685 .common = { 686 .tag = HARDWARE_MODULE_TAG, 687 .module_api_version = AUDIO_MODULE_API_VERSION_0_1, 688 .hal_api_version = HARDWARE_HAL_API_VERSION, 689 .id = AUDIO_HARDWARE_MODULE_ID, 690 .name = "Generic audio HW HAL", 691 .author = "The Android Open Source Project", 692 .methods = &hal_module_methods, 693 }, 694 }; 695