1010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten/* 2010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Copyright (C) 2012 The Android Open Source Project 3010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 4010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * you may not use this file except in compliance with the License. 6010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * You may obtain a copy of the License at 7010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 8010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * 10010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * Unless required by applicable law or agreed to in writing, software 11010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * See the License for the specific language governing permissions and 14010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten * limitations under the License. 15010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten */ 16010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 17010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#define LOG_TAG "AudioStreamInSource" 18010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten//#define LOG_NDEBUG 0 19010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 20010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <cutils/compiler.h> 21010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <utils/Log.h> 22a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov#include <media/audiohal/StreamHalInterface.h> 232dd4bdd715f586d4d30cf90cc6fc2bbfbce60fe0Glenn Kasten#include <media/nbaio/AudioStreamInSource.h> 24010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 25010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastennamespace android { 26010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 27a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail NaganovAudioStreamInSource::AudioStreamInSource(sp<StreamInHalInterface> stream) : 28010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten NBAIO_Source(), 29010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten mStream(stream), 30010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten mStreamBufferSizeBytes(0), 31010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten mFramesOverrun(0), 32010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten mOverruns(0) 33010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 34a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov ALOG_ASSERT(stream != 0); 35010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 36010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 37010662326b9c43c703725f933e95e0897f8a6bddGlenn KastenAudioStreamInSource::~AudioStreamInSource() 38010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 39a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov mStream.clear(); 40010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 41010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 42010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenssize_t AudioStreamInSource::negotiate(const NBAIO_Format offers[], size_t numOffers, 43010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten NBAIO_Format counterOffers[], size_t& numCounterOffers) 44010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 456e0d67d7b496ce17c0970a4ffd3a6f808860949cGlenn Kasten if (!Format_isValid(mFormat)) { 46a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov status_t result; 47a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov result = mStream->getBufferSize(&mStreamBufferSizeBytes); 48a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov if (result != OK) return result; 49a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov audio_format_t streamFormat; 50a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov uint32_t sampleRate; 51a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov audio_channel_mask_t channelMask; 52a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov result = mStream->getAudioProperties(&sampleRate, &channelMask, &streamFormat); 53a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov if (result != OK) return result; 54e541269be94f3a1072932d51537905b120ef4733Andy Hung mFormat = Format_from_SR_C(sampleRate, 55e541269be94f3a1072932d51537905b120ef4733Andy Hung audio_channel_count_from_in_mask(channelMask), streamFormat); 5643d9b8706b3916ee0f1d745a2832f792c3406ca8Glenn Kasten mFrameSize = Format_frameSize(mFormat); 57010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 58010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return NBAIO_Source::negotiate(offers, numOffers, counterOffers, numCounterOffers); 59010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 60010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 61818e7a32ce3633980138aff2c2bfcc5158b3cfccAndy Hungint64_t AudioStreamInSource::framesOverrun() 62010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 63a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov uint32_t framesOverrun; 64a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov status_t result = mStream->getInputFramesLost(&framesOverrun); 65a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov if (result == OK && framesOverrun > 0) { 66010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten mFramesOverrun += framesOverrun; 67010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // FIXME only increment for contiguous ranges 68010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ++mOverruns; 69a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov } else if (result != OK) { 70a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov ALOGE("Error when retrieving lost frames count from HAL: %d", result); 71010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 72010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return mFramesOverrun; 73010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 74010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 75d79072e9dff59f767cce2cda1caab80ce5a0815bGlenn Kastenssize_t AudioStreamInSource::read(void *buffer, size_t count) 76010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 776e0d67d7b496ce17c0970a4ffd3a6f808860949cGlenn Kasten if (CC_UNLIKELY(!Format_isValid(mFormat))) { 78010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return NEGOTIATE; 79010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 80a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov size_t bytesRead; 81a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov status_t result = mStream->read(buffer, count * mFrameSize, &bytesRead); 82a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov if (result == OK && bytesRead > 0) { 834d693d6b8cc1283f92f5301daf19a07abc772a2bGlenn Kasten size_t framesRead = bytesRead / mFrameSize; 84010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten mFramesRead += framesRead; 85010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return framesRead; 86010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } else { 87a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov ALOGE_IF(result != OK, "Error while reading data from HAL: %d", result); 88010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return bytesRead; 89010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 90010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 91010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 92010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} // namespace android 93