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 "legacy_audio_hw_hal" 18 //#define LOG_NDEBUG 0 19 20 #include <stdint.h> 21 22 #include <hardware/hardware.h> 23 #include <system/audio.h> 24 #include <hardware/audio.h> 25 26 #include <hardware_legacy/AudioHardwareInterface.h> 27 #include <hardware_legacy/AudioSystemLegacy.h> 28 29 namespace android_audio_legacy { 30 31 extern "C" { 32 33 struct legacy_audio_module { 34 struct audio_module module; 35 }; 36 37 struct legacy_audio_device { 38 struct audio_hw_device device; 39 40 struct AudioHardwareInterface *hwif; 41 }; 42 43 struct legacy_stream_out { 44 struct audio_stream_out stream; 45 46 AudioStreamOut *legacy_out; 47 }; 48 49 struct legacy_stream_in { 50 struct audio_stream_in stream; 51 52 AudioStreamIn *legacy_in; 53 }; 54 55 /** audio_stream_out implementation **/ 56 static uint32_t out_get_sample_rate(const struct audio_stream *stream) 57 { 58 const struct legacy_stream_out *out = 59 reinterpret_cast<const struct legacy_stream_out *>(stream); 60 return out->legacy_out->sampleRate(); 61 } 62 63 static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) 64 { 65 struct legacy_stream_out *out = 66 reinterpret_cast<struct legacy_stream_out *>(stream); 67 68 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 69 /* TODO: implement this */ 70 return 0; 71 } 72 73 static size_t out_get_buffer_size(const struct audio_stream *stream) 74 { 75 const struct legacy_stream_out *out = 76 reinterpret_cast<const struct legacy_stream_out *>(stream); 77 return out->legacy_out->bufferSize(); 78 } 79 80 static uint32_t out_get_channels(const struct audio_stream *stream) 81 { 82 const struct legacy_stream_out *out = 83 reinterpret_cast<const struct legacy_stream_out *>(stream); 84 return out->legacy_out->channels(); 85 } 86 87 static audio_format_t out_get_format(const struct audio_stream *stream) 88 { 89 const struct legacy_stream_out *out = 90 reinterpret_cast<const struct legacy_stream_out *>(stream); 91 // legacy API, don't change return type 92 return (audio_format_t) out->legacy_out->format(); 93 } 94 95 static int out_set_format(struct audio_stream *stream, audio_format_t format) 96 { 97 struct legacy_stream_out *out = 98 reinterpret_cast<struct legacy_stream_out *>(stream); 99 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 100 /* TODO: implement me */ 101 return 0; 102 } 103 104 static int out_standby(struct audio_stream *stream) 105 { 106 struct legacy_stream_out *out = 107 reinterpret_cast<struct legacy_stream_out *>(stream); 108 return out->legacy_out->standby(); 109 } 110 111 static int out_dump(const struct audio_stream *stream, int fd) 112 { 113 const struct legacy_stream_out *out = 114 reinterpret_cast<const struct legacy_stream_out *>(stream); 115 Vector<String16> args; 116 return out->legacy_out->dump(fd, args); 117 } 118 119 static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) 120 { 121 struct legacy_stream_out *out = 122 reinterpret_cast<struct legacy_stream_out *>(stream); 123 return out->legacy_out->setParameters(String8(kvpairs)); 124 } 125 126 static char * out_get_parameters(const struct audio_stream *stream, const char *keys) 127 { 128 const struct legacy_stream_out *out = 129 reinterpret_cast<const struct legacy_stream_out *>(stream); 130 String8 s8; 131 s8 = out->legacy_out->getParameters(String8(keys)); 132 return strdup(s8.string()); 133 } 134 135 static uint32_t out_get_latency(const struct audio_stream_out *stream) 136 { 137 const struct legacy_stream_out *out = 138 reinterpret_cast<const struct legacy_stream_out *>(stream); 139 return out->legacy_out->latency(); 140 } 141 142 static int out_set_volume(struct audio_stream_out *stream, float left, 143 float right) 144 { 145 struct legacy_stream_out *out = 146 reinterpret_cast<struct legacy_stream_out *>(stream); 147 return out->legacy_out->setVolume(left, right); 148 } 149 150 static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, 151 size_t bytes) 152 { 153 struct legacy_stream_out *out = 154 reinterpret_cast<struct legacy_stream_out *>(stream); 155 return out->legacy_out->write(buffer, bytes); 156 } 157 158 static int out_get_render_position(const struct audio_stream_out *stream, 159 uint32_t *dsp_frames) 160 { 161 const struct legacy_stream_out *out = 162 reinterpret_cast<const struct legacy_stream_out *>(stream); 163 return out->legacy_out->getRenderPosition(dsp_frames); 164 } 165 166 static int out_get_next_write_timestamp(const struct audio_stream_out *stream, 167 int64_t *timestamp) 168 { 169 const struct legacy_stream_out *out = 170 reinterpret_cast<const struct legacy_stream_out *>(stream); 171 return out->legacy_out->getNextWriteTimestamp(timestamp); 172 } 173 174 static int out_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 175 { 176 return 0; 177 } 178 179 static int out_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 180 { 181 return 0; 182 } 183 184 /** audio_stream_in implementation **/ 185 static uint32_t in_get_sample_rate(const struct audio_stream *stream) 186 { 187 const struct legacy_stream_in *in = 188 reinterpret_cast<const struct legacy_stream_in *>(stream); 189 return in->legacy_in->sampleRate(); 190 } 191 192 static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) 193 { 194 struct legacy_stream_in *in = 195 reinterpret_cast<struct legacy_stream_in *>(stream); 196 197 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 198 /* TODO: implement this */ 199 return 0; 200 } 201 202 static size_t in_get_buffer_size(const struct audio_stream *stream) 203 { 204 const struct legacy_stream_in *in = 205 reinterpret_cast<const struct legacy_stream_in *>(stream); 206 return in->legacy_in->bufferSize(); 207 } 208 209 static uint32_t in_get_channels(const struct audio_stream *stream) 210 { 211 const struct legacy_stream_in *in = 212 reinterpret_cast<const struct legacy_stream_in *>(stream); 213 return in->legacy_in->channels(); 214 } 215 216 static audio_format_t in_get_format(const struct audio_stream *stream) 217 { 218 const struct legacy_stream_in *in = 219 reinterpret_cast<const struct legacy_stream_in *>(stream); 220 // legacy API, don't change return type 221 return (audio_format_t) in->legacy_in->format(); 222 } 223 224 static int in_set_format(struct audio_stream *stream, audio_format_t format) 225 { 226 struct legacy_stream_in *in = 227 reinterpret_cast<struct legacy_stream_in *>(stream); 228 ALOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); 229 /* TODO: implement me */ 230 return 0; 231 } 232 233 static int in_standby(struct audio_stream *stream) 234 { 235 struct legacy_stream_in *in = reinterpret_cast<struct legacy_stream_in *>(stream); 236 return in->legacy_in->standby(); 237 } 238 239 static int in_dump(const struct audio_stream *stream, int fd) 240 { 241 const struct legacy_stream_in *in = 242 reinterpret_cast<const struct legacy_stream_in *>(stream); 243 Vector<String16> args; 244 return in->legacy_in->dump(fd, args); 245 } 246 247 static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 248 { 249 struct legacy_stream_in *in = 250 reinterpret_cast<struct legacy_stream_in *>(stream); 251 return in->legacy_in->setParameters(String8(kvpairs)); 252 } 253 254 static char * in_get_parameters(const struct audio_stream *stream, 255 const char *keys) 256 { 257 const struct legacy_stream_in *in = 258 reinterpret_cast<const struct legacy_stream_in *>(stream); 259 String8 s8; 260 s8 = in->legacy_in->getParameters(String8(keys)); 261 return strdup(s8.string()); 262 } 263 264 static int in_set_gain(struct audio_stream_in *stream, float gain) 265 { 266 struct legacy_stream_in *in = 267 reinterpret_cast<struct legacy_stream_in *>(stream); 268 return in->legacy_in->setGain(gain); 269 } 270 271 static ssize_t in_read(struct audio_stream_in *stream, void* buffer, 272 size_t bytes) 273 { 274 struct legacy_stream_in *in = 275 reinterpret_cast<struct legacy_stream_in *>(stream); 276 return in->legacy_in->read(buffer, bytes); 277 } 278 279 static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) 280 { 281 struct legacy_stream_in *in = 282 reinterpret_cast<struct legacy_stream_in *>(stream); 283 return in->legacy_in->getInputFramesLost(); 284 } 285 286 static int in_add_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 287 { 288 const struct legacy_stream_in *in = 289 reinterpret_cast<const struct legacy_stream_in *>(stream); 290 return in->legacy_in->addAudioEffect(effect); 291 } 292 293 static int in_remove_audio_effect(const struct audio_stream *stream, effect_handle_t effect) 294 { 295 const struct legacy_stream_in *in = 296 reinterpret_cast<const struct legacy_stream_in *>(stream); 297 return in->legacy_in->removeAudioEffect(effect); 298 } 299 300 /** audio_hw_device implementation **/ 301 static inline struct legacy_audio_device * to_ladev(struct audio_hw_device *dev) 302 { 303 return reinterpret_cast<struct legacy_audio_device *>(dev); 304 } 305 306 static inline const struct legacy_audio_device * to_cladev(const struct audio_hw_device *dev) 307 { 308 return reinterpret_cast<const struct legacy_audio_device *>(dev); 309 } 310 311 static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev) 312 { 313 /* XXX: The old AudioHardwareInterface interface is not smart enough to 314 * tell us this, so we'll lie and basically tell AF that we support the 315 * below input/output devices and cross our fingers. To do things properly, 316 * audio hardware interfaces that need advanced features (like this) should 317 * convert to the new HAL interface and not use this wrapper. */ 318 319 return (/* OUT */ 320 AUDIO_DEVICE_OUT_EARPIECE | 321 AUDIO_DEVICE_OUT_SPEAKER | 322 AUDIO_DEVICE_OUT_WIRED_HEADSET | 323 AUDIO_DEVICE_OUT_WIRED_HEADPHONE | 324 AUDIO_DEVICE_OUT_AUX_DIGITAL | 325 AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | 326 AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | 327 AUDIO_DEVICE_OUT_ALL_SCO | 328 AUDIO_DEVICE_OUT_DEFAULT | 329 /* IN */ 330 AUDIO_DEVICE_IN_COMMUNICATION | 331 AUDIO_DEVICE_IN_AMBIENT | 332 AUDIO_DEVICE_IN_BUILTIN_MIC | 333 AUDIO_DEVICE_IN_WIRED_HEADSET | 334 AUDIO_DEVICE_IN_AUX_DIGITAL | 335 AUDIO_DEVICE_IN_BACK_MIC | 336 AUDIO_DEVICE_IN_ALL_SCO | 337 AUDIO_DEVICE_IN_DEFAULT); 338 } 339 340 static int adev_init_check(const struct audio_hw_device *dev) 341 { 342 const struct legacy_audio_device *ladev = to_cladev(dev); 343 344 return ladev->hwif->initCheck(); 345 } 346 347 static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) 348 { 349 struct legacy_audio_device *ladev = to_ladev(dev); 350 return ladev->hwif->setVoiceVolume(volume); 351 } 352 353 static int adev_set_master_volume(struct audio_hw_device *dev, float volume) 354 { 355 struct legacy_audio_device *ladev = to_ladev(dev); 356 return ladev->hwif->setMasterVolume(volume); 357 } 358 359 static int adev_get_master_volume(struct audio_hw_device *dev, float* volume) 360 { 361 struct legacy_audio_device *ladev = to_ladev(dev); 362 return ladev->hwif->getMasterVolume(volume); 363 } 364 365 static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) 366 { 367 struct legacy_audio_device *ladev = to_ladev(dev); 368 // as this is the legacy API, don't change it to use audio_mode_t instead of int 369 return ladev->hwif->setMode((int) mode); 370 } 371 372 static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) 373 { 374 struct legacy_audio_device *ladev = to_ladev(dev); 375 return ladev->hwif->setMicMute(state); 376 } 377 378 static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) 379 { 380 const struct legacy_audio_device *ladev = to_cladev(dev); 381 return ladev->hwif->getMicMute(state); 382 } 383 384 static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) 385 { 386 struct legacy_audio_device *ladev = to_ladev(dev); 387 return ladev->hwif->setParameters(String8(kvpairs)); 388 } 389 390 static char * adev_get_parameters(const struct audio_hw_device *dev, 391 const char *keys) 392 { 393 const struct legacy_audio_device *ladev = to_cladev(dev); 394 String8 s8; 395 396 s8 = ladev->hwif->getParameters(String8(keys)); 397 return strdup(s8.string()); 398 } 399 400 static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, 401 const struct audio_config *config) 402 { 403 const struct legacy_audio_device *ladev = to_cladev(dev); 404 return ladev->hwif->getInputBufferSize(config->sample_rate, (int) config->format, 405 popcount(config->channel_mask)); 406 } 407 408 static int adev_open_output_stream(struct audio_hw_device *dev, 409 audio_io_handle_t handle, 410 audio_devices_t devices, 411 audio_output_flags_t flags, 412 struct audio_config *config, 413 struct audio_stream_out **stream_out) 414 { 415 struct legacy_audio_device *ladev = to_ladev(dev); 416 status_t status; 417 struct legacy_stream_out *out; 418 int ret; 419 420 out = (struct legacy_stream_out *)calloc(1, sizeof(*out)); 421 if (!out) 422 return -ENOMEM; 423 424 out->legacy_out = ladev->hwif->openOutputStream(devices, (int *) &config->format, 425 &config->channel_mask, 426 &config->sample_rate, &status); 427 if (!out->legacy_out) { 428 ret = status; 429 goto err_open; 430 } 431 432 out->stream.common.get_sample_rate = out_get_sample_rate; 433 out->stream.common.set_sample_rate = out_set_sample_rate; 434 out->stream.common.get_buffer_size = out_get_buffer_size; 435 out->stream.common.get_channels = out_get_channels; 436 out->stream.common.get_format = out_get_format; 437 out->stream.common.set_format = out_set_format; 438 out->stream.common.standby = out_standby; 439 out->stream.common.dump = out_dump; 440 out->stream.common.set_parameters = out_set_parameters; 441 out->stream.common.get_parameters = out_get_parameters; 442 out->stream.common.add_audio_effect = out_add_audio_effect; 443 out->stream.common.remove_audio_effect = out_remove_audio_effect; 444 out->stream.get_latency = out_get_latency; 445 out->stream.set_volume = out_set_volume; 446 out->stream.write = out_write; 447 out->stream.get_render_position = out_get_render_position; 448 out->stream.get_next_write_timestamp = out_get_next_write_timestamp; 449 450 *stream_out = &out->stream; 451 return 0; 452 453 err_open: 454 free(out); 455 *stream_out = NULL; 456 return ret; 457 } 458 459 static void adev_close_output_stream(struct audio_hw_device *dev, 460 struct audio_stream_out* stream) 461 { 462 struct legacy_audio_device *ladev = to_ladev(dev); 463 struct legacy_stream_out *out = reinterpret_cast<struct legacy_stream_out *>(stream); 464 465 ladev->hwif->closeOutputStream(out->legacy_out); 466 free(out); 467 } 468 469 /** This method creates and opens the audio hardware input stream */ 470 static int adev_open_input_stream(struct audio_hw_device *dev, 471 audio_io_handle_t handle, 472 audio_devices_t devices, 473 struct audio_config *config, 474 struct audio_stream_in **stream_in) 475 { 476 struct legacy_audio_device *ladev = to_ladev(dev); 477 status_t status; 478 struct legacy_stream_in *in; 479 int ret; 480 481 in = (struct legacy_stream_in *)calloc(1, sizeof(*in)); 482 if (!in) 483 return -ENOMEM; 484 485 in->legacy_in = ladev->hwif->openInputStream(devices, (int *) &config->format, 486 &config->channel_mask, &config->sample_rate, 487 &status, (AudioSystem::audio_in_acoustics)0); 488 if (!in->legacy_in) { 489 ret = status; 490 goto err_open; 491 } 492 493 in->stream.common.get_sample_rate = in_get_sample_rate; 494 in->stream.common.set_sample_rate = in_set_sample_rate; 495 in->stream.common.get_buffer_size = in_get_buffer_size; 496 in->stream.common.get_channels = in_get_channels; 497 in->stream.common.get_format = in_get_format; 498 in->stream.common.set_format = in_set_format; 499 in->stream.common.standby = in_standby; 500 in->stream.common.dump = in_dump; 501 in->stream.common.set_parameters = in_set_parameters; 502 in->stream.common.get_parameters = in_get_parameters; 503 in->stream.common.add_audio_effect = in_add_audio_effect; 504 in->stream.common.remove_audio_effect = in_remove_audio_effect; 505 in->stream.set_gain = in_set_gain; 506 in->stream.read = in_read; 507 in->stream.get_input_frames_lost = in_get_input_frames_lost; 508 509 *stream_in = &in->stream; 510 return 0; 511 512 err_open: 513 free(in); 514 *stream_in = NULL; 515 return ret; 516 } 517 518 static void adev_close_input_stream(struct audio_hw_device *dev, 519 struct audio_stream_in *stream) 520 { 521 struct legacy_audio_device *ladev = to_ladev(dev); 522 struct legacy_stream_in *in = 523 reinterpret_cast<struct legacy_stream_in *>(stream); 524 525 ladev->hwif->closeInputStream(in->legacy_in); 526 free(in); 527 } 528 529 static int adev_dump(const struct audio_hw_device *dev, int fd) 530 { 531 const struct legacy_audio_device *ladev = to_cladev(dev); 532 Vector<String16> args; 533 534 return ladev->hwif->dumpState(fd, args); 535 } 536 537 static int legacy_adev_close(hw_device_t* device) 538 { 539 struct audio_hw_device *hwdev = 540 reinterpret_cast<struct audio_hw_device *>(device); 541 struct legacy_audio_device *ladev = to_ladev(hwdev); 542 543 if (!ladev) 544 return 0; 545 546 if (ladev->hwif) 547 delete ladev->hwif; 548 549 free(ladev); 550 return 0; 551 } 552 553 static int legacy_adev_open(const hw_module_t* module, const char* name, 554 hw_device_t** device) 555 { 556 struct legacy_audio_device *ladev; 557 int ret; 558 559 if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) 560 return -EINVAL; 561 562 ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev)); 563 if (!ladev) 564 return -ENOMEM; 565 566 ladev->device.common.tag = HARDWARE_DEVICE_TAG; 567 ladev->device.common.version = AUDIO_DEVICE_API_VERSION_1_0; 568 ladev->device.common.module = const_cast<hw_module_t*>(module); 569 ladev->device.common.close = legacy_adev_close; 570 571 ladev->device.get_supported_devices = adev_get_supported_devices; 572 ladev->device.init_check = adev_init_check; 573 ladev->device.set_voice_volume = adev_set_voice_volume; 574 ladev->device.set_master_volume = adev_set_master_volume; 575 ladev->device.get_master_volume = adev_get_master_volume; 576 ladev->device.set_mode = adev_set_mode; 577 ladev->device.set_mic_mute = adev_set_mic_mute; 578 ladev->device.get_mic_mute = adev_get_mic_mute; 579 ladev->device.set_parameters = adev_set_parameters; 580 ladev->device.get_parameters = adev_get_parameters; 581 ladev->device.get_input_buffer_size = adev_get_input_buffer_size; 582 ladev->device.open_output_stream = adev_open_output_stream; 583 ladev->device.close_output_stream = adev_close_output_stream; 584 ladev->device.open_input_stream = adev_open_input_stream; 585 ladev->device.close_input_stream = adev_close_input_stream; 586 ladev->device.dump = adev_dump; 587 588 ladev->hwif = createAudioHardware(); 589 if (!ladev->hwif) { 590 ret = -EIO; 591 goto err_create_audio_hw; 592 } 593 594 *device = &ladev->device.common; 595 596 return 0; 597 598 err_create_audio_hw: 599 free(ladev); 600 return ret; 601 } 602 603 static struct hw_module_methods_t legacy_audio_module_methods = { 604 open: legacy_adev_open 605 }; 606 607 struct legacy_audio_module HAL_MODULE_INFO_SYM = { 608 module: { 609 common: { 610 tag: HARDWARE_MODULE_TAG, 611 module_api_version: AUDIO_MODULE_API_VERSION_0_1, 612 hal_api_version: HARDWARE_HAL_API_VERSION, 613 id: AUDIO_HARDWARE_MODULE_ID, 614 name: "LEGACY Audio HW HAL", 615 author: "The Android Open Source Project", 616 methods: &legacy_audio_module_methods, 617 dso : NULL, 618 reserved : {0}, 619 }, 620 }, 621 }; 622 623 }; // extern "C" 624 625 }; // namespace android_audio_legacy 626