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