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 <hardware/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 30namespace android { 31 32// ---------------------------------------------------------------------------- 33 34status_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 97}; // namespace android 98