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