1062e67a26e0553dd142be622821f493df541f0c6Phil Burk/* 2062e67a26e0553dd142be622821f493df541f0c6Phil Burk** 3062e67a26e0553dd142be622821f493df541f0c6Phil Burk** Copyright 2015, The Android Open Source Project 4062e67a26e0553dd142be622821f493df541f0c6Phil Burk** 5062e67a26e0553dd142be622821f493df541f0c6Phil Burk** Licensed under the Apache License, Version 2.0 (the "License"); 6062e67a26e0553dd142be622821f493df541f0c6Phil Burk** you may not use this file except in compliance with the License. 7062e67a26e0553dd142be622821f493df541f0c6Phil Burk** You may obtain a copy of the License at 8062e67a26e0553dd142be622821f493df541f0c6Phil Burk** 9062e67a26e0553dd142be622821f493df541f0c6Phil Burk** http://www.apache.org/licenses/LICENSE-2.0 10062e67a26e0553dd142be622821f493df541f0c6Phil Burk** 11062e67a26e0553dd142be622821f493df541f0c6Phil Burk** Unless required by applicable law or agreed to in writing, software 12062e67a26e0553dd142be622821f493df541f0c6Phil Burk** distributed under the License is distributed on an "AS IS" BASIS, 13062e67a26e0553dd142be622821f493df541f0c6Phil Burk** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14062e67a26e0553dd142be622821f493df541f0c6Phil Burk** See the License for the specific language governing permissions and 15062e67a26e0553dd142be622821f493df541f0c6Phil Burk** limitations under the License. 16062e67a26e0553dd142be622821f493df541f0c6Phil Burk*/ 17062e67a26e0553dd142be622821f493df541f0c6Phil Burk 18062e67a26e0553dd142be622821f493df541f0c6Phil Burk#define LOG_TAG "AudioFlinger" 19062e67a26e0553dd142be622821f493df541f0c6Phil Burk//#define LOG_NDEBUG 0 20062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include <hardware/audio.h> 21062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include <utils/Log.h> 22062e67a26e0553dd142be622821f493df541f0c6Phil Burk 23062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include <audio_utils/spdif/SPDIFEncoder.h> 24062e67a26e0553dd142be622821f493df541f0c6Phil Burk 25062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include "AudioHwDevice.h" 26062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include "AudioStreamOut.h" 27062e67a26e0553dd142be622821f493df541f0c6Phil Burk#include "SpdifStreamOut.h" 28062e67a26e0553dd142be622821f493df541f0c6Phil Burk 29062e67a26e0553dd142be622821f493df541f0c6Phil Burknamespace android { 30062e67a26e0553dd142be622821f493df541f0c6Phil Burk 31062e67a26e0553dd142be622821f493df541f0c6Phil Burk/** 32062e67a26e0553dd142be622821f493df541f0c6Phil Burk * If the AudioFlinger is processing encoded data and the HAL expects 33062e67a26e0553dd142be622821f493df541f0c6Phil Burk * PCM then we need to wrap the data in an SPDIF wrapper. 34062e67a26e0553dd142be622821f493df541f0c6Phil Burk */ 3523d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil BurkSpdifStreamOut::SpdifStreamOut(AudioHwDevice *dev, 3623d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk audio_output_flags_t flags, 3723d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk audio_format_t format) 3841ae1d663d896a9ec22299d95c01940313a9b276Phil Burk // Tell the HAL that the data will be compressed audio wrapped in a data burst. 3941ae1d663d896a9ec22299d95c01940313a9b276Phil Burk : AudioStreamOut(dev, (audio_output_flags_t) (flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)) 4023d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk , mSpdifEncoder(this, format) 41ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk , mApplicationFormat(AUDIO_FORMAT_DEFAULT) 42ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk , mApplicationSampleRate(0) 43ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk , mApplicationChannelMask(0) 44062e67a26e0553dd142be622821f493df541f0c6Phil Burk{ 45062e67a26e0553dd142be622821f493df541f0c6Phil Burk} 46062e67a26e0553dd142be622821f493df541f0c6Phil Burk 47062e67a26e0553dd142be622821f493df541f0c6Phil Burkstatus_t SpdifStreamOut::open( 48062e67a26e0553dd142be622821f493df541f0c6Phil Burk audio_io_handle_t handle, 49062e67a26e0553dd142be622821f493df541f0c6Phil Burk audio_devices_t devices, 50062e67a26e0553dd142be622821f493df541f0c6Phil Burk struct audio_config *config, 51062e67a26e0553dd142be622821f493df541f0c6Phil Burk const char *address) 52062e67a26e0553dd142be622821f493df541f0c6Phil Burk{ 53062e67a26e0553dd142be622821f493df541f0c6Phil Burk struct audio_config customConfig = *config; 54062e67a26e0553dd142be622821f493df541f0c6Phil Burk 55ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mApplicationFormat = config->format; 56ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mApplicationSampleRate = config->sample_rate; 57ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk mApplicationChannelMask = config->channel_mask; 58ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk 59062e67a26e0553dd142be622821f493df541f0c6Phil Burk // Some data bursts run at a higher sample rate. 6023d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk // TODO Move this into the audio_utils as a static method. 61062e67a26e0553dd142be622821f493df541f0c6Phil Burk switch(config->format) { 62062e67a26e0553dd142be622821f493df541f0c6Phil Burk case AUDIO_FORMAT_E_AC3: 63062e67a26e0553dd142be622821f493df541f0c6Phil Burk mRateMultiplier = 4; 64062e67a26e0553dd142be622821f493df541f0c6Phil Burk break; 65062e67a26e0553dd142be622821f493df541f0c6Phil Burk case AUDIO_FORMAT_AC3: 6623d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk case AUDIO_FORMAT_DTS: 6723d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk case AUDIO_FORMAT_DTS_HD: 68062e67a26e0553dd142be622821f493df541f0c6Phil Burk mRateMultiplier = 1; 69062e67a26e0553dd142be622821f493df541f0c6Phil Burk break; 70062e67a26e0553dd142be622821f493df541f0c6Phil Burk default: 71062e67a26e0553dd142be622821f493df541f0c6Phil Burk ALOGE("ERROR SpdifStreamOut::open() unrecognized format 0x%08X\n", 72062e67a26e0553dd142be622821f493df541f0c6Phil Burk config->format); 73062e67a26e0553dd142be622821f493df541f0c6Phil Burk return BAD_VALUE; 74062e67a26e0553dd142be622821f493df541f0c6Phil Burk } 75062e67a26e0553dd142be622821f493df541f0c6Phil Burk customConfig.sample_rate = config->sample_rate * mRateMultiplier; 76062e67a26e0553dd142be622821f493df541f0c6Phil Burk 7723d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk customConfig.format = AUDIO_FORMAT_PCM_16_BIT; 7823d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk customConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO; 7923d8997f58bb9c59fa3a1b9a6b2edbf1b2b0f4c6Phil Burk 80062e67a26e0553dd142be622821f493df541f0c6Phil Burk // Always print this because otherwise it could be very confusing if the 81062e67a26e0553dd142be622821f493df541f0c6Phil Burk // HAL and AudioFlinger are using different formats. 82062e67a26e0553dd142be622821f493df541f0c6Phil Burk // Print before open() because HAL may modify customConfig. 83062e67a26e0553dd142be622821f493df541f0c6Phil Burk ALOGI("SpdifStreamOut::open() AudioFlinger requested" 84062e67a26e0553dd142be622821f493df541f0c6Phil Burk " sampleRate %d, format %#x, channelMask %#x", 85062e67a26e0553dd142be622821f493df541f0c6Phil Burk config->sample_rate, 86062e67a26e0553dd142be622821f493df541f0c6Phil Burk config->format, 87062e67a26e0553dd142be622821f493df541f0c6Phil Burk config->channel_mask); 88062e67a26e0553dd142be622821f493df541f0c6Phil Burk ALOGI("SpdifStreamOut::open() HAL configured for" 89062e67a26e0553dd142be622821f493df541f0c6Phil Burk " sampleRate %d, format %#x, channelMask %#x", 90062e67a26e0553dd142be622821f493df541f0c6Phil Burk customConfig.sample_rate, 91062e67a26e0553dd142be622821f493df541f0c6Phil Burk customConfig.format, 92062e67a26e0553dd142be622821f493df541f0c6Phil Burk customConfig.channel_mask); 93062e67a26e0553dd142be622821f493df541f0c6Phil Burk 94062e67a26e0553dd142be622821f493df541f0c6Phil Burk status_t status = AudioStreamOut::open( 95062e67a26e0553dd142be622821f493df541f0c6Phil Burk handle, 96062e67a26e0553dd142be622821f493df541f0c6Phil Burk devices, 97062e67a26e0553dd142be622821f493df541f0c6Phil Burk &customConfig, 98062e67a26e0553dd142be622821f493df541f0c6Phil Burk address); 99062e67a26e0553dd142be622821f493df541f0c6Phil Burk 100062e67a26e0553dd142be622821f493df541f0c6Phil Burk ALOGI("SpdifStreamOut::open() status = %d", status); 101062e67a26e0553dd142be622821f493df541f0c6Phil Burk 102062e67a26e0553dd142be622821f493df541f0c6Phil Burk return status; 103062e67a26e0553dd142be622821f493df541f0c6Phil Burk} 104062e67a26e0553dd142be622821f493df541f0c6Phil Burk 105062e67a26e0553dd142be622821f493df541f0c6Phil Burkint SpdifStreamOut::flush() 106062e67a26e0553dd142be622821f493df541f0c6Phil Burk{ 10748e6ea95dc23e1c84911f1f907403ac1729c6b78Phil Burk mSpdifEncoder.reset(); 108062e67a26e0553dd142be622821f493df541f0c6Phil Burk return AudioStreamOut::flush(); 109062e67a26e0553dd142be622821f493df541f0c6Phil Burk} 110062e67a26e0553dd142be622821f493df541f0c6Phil Burk 111062e67a26e0553dd142be622821f493df541f0c6Phil Burkint SpdifStreamOut::standby() 112062e67a26e0553dd142be622821f493df541f0c6Phil Burk{ 11348e6ea95dc23e1c84911f1f907403ac1729c6b78Phil Burk mSpdifEncoder.reset(); 114062e67a26e0553dd142be622821f493df541f0c6Phil Burk return AudioStreamOut::standby(); 115062e67a26e0553dd142be622821f493df541f0c6Phil Burk} 116062e67a26e0553dd142be622821f493df541f0c6Phil Burk 117062e67a26e0553dd142be622821f493df541f0c6Phil Burkssize_t SpdifStreamOut::writeDataBurst(const void* buffer, size_t bytes) 118062e67a26e0553dd142be622821f493df541f0c6Phil Burk{ 119062e67a26e0553dd142be622821f493df541f0c6Phil Burk return AudioStreamOut::write(buffer, bytes); 120062e67a26e0553dd142be622821f493df541f0c6Phil Burk} 121062e67a26e0553dd142be622821f493df541f0c6Phil Burk 122ca5e6143740299c877d69e97f7968cd04476d32cPhil Burkssize_t SpdifStreamOut::write(const void* buffer, size_t numBytes) 123062e67a26e0553dd142be622821f493df541f0c6Phil Burk{ 124062e67a26e0553dd142be622821f493df541f0c6Phil Burk // Write to SPDIF wrapper. It will call back to writeDataBurst(). 125ca5e6143740299c877d69e97f7968cd04476d32cPhil Burk return mSpdifEncoder.write(buffer, numBytes); 126062e67a26e0553dd142be622821f493df541f0c6Phil Burk} 127062e67a26e0553dd142be622821f493df541f0c6Phil Burk 128062e67a26e0553dd142be622821f493df541f0c6Phil Burk} // namespace android 129