1 /* 2 ** 3 ** Copyright 2007, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #define LOG_TAG "AudioHwDevice" 19 //#define LOG_NDEBUG 0 20 21 #include <system/audio.h> 22 #include <utils/Log.h> 23 24 #include <audio_utils/spdif/SPDIFEncoder.h> 25 26 #include "AudioHwDevice.h" 27 #include "AudioStreamOut.h" 28 #include "SpdifStreamOut.h" 29 30 namespace android { 31 32 // ---------------------------------------------------------------------------- 33 34 status_t AudioHwDevice::openOutputStream( 35 AudioStreamOut **ppStreamOut, 36 audio_io_handle_t handle, 37 audio_devices_t devices, 38 audio_output_flags_t flags, 39 struct audio_config *config, 40 const char *address) 41 { 42 43 struct audio_config originalConfig = *config; 44 AudioStreamOut *outputStream = new AudioStreamOut(this, flags); 45 46 // Try to open the HAL first using the current format. 47 ALOGV("openOutputStream(), try " 48 " sampleRate %d, Format %#x, " 49 "channelMask %#x", 50 config->sample_rate, 51 config->format, 52 config->channel_mask); 53 status_t status = outputStream->open(handle, devices, config, address); 54 55 if (status != NO_ERROR) { 56 delete outputStream; 57 outputStream = NULL; 58 59 // FIXME Look at any modification to the config. 60 // The HAL might modify the config to suggest a wrapped format. 61 // Log this so we can see what the HALs are doing. 62 ALOGI("openOutputStream(), HAL returned" 63 " sampleRate %d, Format %#x, " 64 "channelMask %#x, status %d", 65 config->sample_rate, 66 config->format, 67 config->channel_mask, 68 status); 69 70 // If the data is encoded then try again using wrapped PCM. 71 bool wrapperNeeded = !audio_has_proportional_frames(originalConfig.format) 72 && ((flags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) 73 && ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0); 74 75 if (wrapperNeeded) { 76 if (SPDIFEncoder::isFormatSupported(originalConfig.format)) { 77 outputStream = new SpdifStreamOut(this, flags, originalConfig.format); 78 status = outputStream->open(handle, devices, &originalConfig, address); 79 if (status != NO_ERROR) { 80 ALOGE("ERROR - openOutputStream(), SPDIF open returned %d", 81 status); 82 delete outputStream; 83 outputStream = NULL; 84 } 85 } else { 86 ALOGE("ERROR - openOutputStream(), SPDIFEncoder does not support format 0x%08x", 87 originalConfig.format); 88 } 89 } 90 } 91 92 *ppStreamOut = outputStream; 93 return status; 94 } 95 96 bool AudioHwDevice::supportsAudioPatches() const { 97 bool result; 98 return mHwDevice->supportsAudioPatches(&result) == OK ? result : false; 99 } 100 101 102 }; // namespace android 103