NBAIO.cpp revision 2c3b2da3049627264b7c6b449a1622f002210f03
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 "NBAIO" 18010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten//#define LOG_NDEBUG 0 19010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 20010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include <utils/Log.h> 21010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten#include "NBAIO.h" 22010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 23010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastennamespace android { 24010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 25010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastensize_t Format_frameSize(NBAIO_Format format) 26010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 27010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten switch (format) { 28010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C2_I16: 29010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C2_I16: 30010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 2 * sizeof(short); 31010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C1_I16: 32010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C1_I16: 33010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 1 * sizeof(short); 34010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_Invalid: 35010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten default: 36010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 0; 37010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 38010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 39010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 40010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastensize_t Format_frameBitShift(NBAIO_Format format) 41010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 42010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten switch (format) { 43010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C2_I16: 44010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C2_I16: 45010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 2; // 1 << 2 == 2 * sizeof(short) 46010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C1_I16: 47010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C1_I16: 48010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 1; // 1 << 1 == 1 * sizeof(short) 49010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_Invalid: 50010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten default: 51010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 0; 52010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 53010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 54010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 55010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenunsigned Format_sampleRate(NBAIO_Format format) 56010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 57010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten switch (format) { 58010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C1_I16: 59010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C2_I16: 60010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 44100; 61010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C1_I16: 62010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C2_I16: 63010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 48000; 64010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_Invalid: 65010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten default: 66010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 0; 67010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 68010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 69010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 70010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenunsigned Format_channelCount(NBAIO_Format format) 71010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 72010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten switch (format) { 73010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C1_I16: 74010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C1_I16: 75010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 1; 76010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR44_1_C2_I16: 77010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_SR48_C2_I16: 78010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 2; 79010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten case Format_Invalid: 80010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten default: 81010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return 0; 82010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 83010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 84010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 85010662326b9c43c703725f933e95e0897f8a6bddGlenn KastenNBAIO_Format Format_from_SR_C(unsigned sampleRate, unsigned channelCount) 86010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 87010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (sampleRate == 44100 && channelCount == 2) return Format_SR44_1_C2_I16; 88010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (sampleRate == 48000 && channelCount == 2) return Format_SR48_C2_I16; 89010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (sampleRate == 44100 && channelCount == 1) return Format_SR44_1_C1_I16; 90010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (sampleRate == 48000 && channelCount == 1) return Format_SR48_C1_I16; 91010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return Format_Invalid; 92010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 93010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 94010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// This is a default implementation; it is expected that subclasses will optimize this. 95010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenssize_t NBAIO_Sink::writeVia(writeVia_t via, size_t total, void *user, size_t block) 96010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 97010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (!mNegotiated) { 98010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return (ssize_t) NEGOTIATE; 99010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 100010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten static const size_t maxBlock = 32; 101010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t frameSize = Format_frameSize(mFormat); 102010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ALOG_ASSERT(frameSize > 0 && frameSize <= 8); 103010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // double guarantees alignment for stack similar to what malloc() gives for heap 104010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (block == 0 || block > maxBlock) { 105010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten block = maxBlock; 106010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 107010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten double buffer[((frameSize * block) + sizeof(double) - 1) / sizeof(double)]; 108010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t accumulator = 0; 109010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten while (accumulator < total) { 110010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t count = total - accumulator; 111010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (count > block) { 112010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten count = block; 113010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 114010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ssize_t ret = via(user, buffer, count); 115010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (ret > 0) { 116010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ALOG_ASSERT((size_t) ret <= count); 117010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t maxRet = ret; 118010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ret = write(buffer, maxRet); 119010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (ret > 0) { 120010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ALOG_ASSERT((size_t) ret <= maxRet); 121010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten accumulator += ret; 122010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten continue; 123010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 124010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 125010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return accumulator > 0 ? accumulator : ret; 126010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 127010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return accumulator; 128010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 129010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 130010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// This is a default implementation; it is expected that subclasses will optimize this. 1312c3b2da3049627264b7c6b449a1622f002210f03John Grossmanssize_t NBAIO_Source::readVia(readVia_t via, size_t total, void *user, 1322c3b2da3049627264b7c6b449a1622f002210f03John Grossman int64_t readPTS, size_t block) 133010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 134010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (!mNegotiated) { 135010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return (ssize_t) NEGOTIATE; 136010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 137010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten static const size_t maxBlock = 32; 138010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t frameSize = Format_frameSize(mFormat); 139010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ALOG_ASSERT(frameSize > 0 && frameSize <= 8); 140010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten // double guarantees alignment for stack similar to what malloc() gives for heap 141010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (block == 0 || block > maxBlock) { 142010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten block = maxBlock; 143010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 144010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten double buffer[((frameSize * block) + sizeof(double) - 1) / sizeof(double)]; 145010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t accumulator = 0; 146010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten while (accumulator < total) { 147010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t count = total - accumulator; 148010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (count > block) { 149010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten count = block; 150010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 1512c3b2da3049627264b7c6b449a1622f002210f03John Grossman ssize_t ret = read(buffer, count, readPTS); 152010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (ret > 0) { 153010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ALOG_ASSERT((size_t) ret <= count); 154010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten size_t maxRet = ret; 1552c3b2da3049627264b7c6b449a1622f002210f03John Grossman ret = via(user, buffer, maxRet, readPTS); 156010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (ret > 0) { 157010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ALOG_ASSERT((size_t) ret <= maxRet); 158010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten accumulator += ret; 159010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten continue; 160010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 161010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 162010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return accumulator > 0 ? accumulator : ret; 163010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 164010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return accumulator; 165010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 166010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 167010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten// Default implementation that only accepts my mFormat 168010662326b9c43c703725f933e95e0897f8a6bddGlenn Kastenssize_t NBAIO_Port::negotiate(const NBAIO_Format offers[], size_t numOffers, 169010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten NBAIO_Format counterOffers[], size_t& numCounterOffers) 170010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten{ 171010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten ALOGV("negotiate offers=%p numOffers=%u countersOffers=%p numCounterOffers=%u", 172010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten offers, numOffers, counterOffers, numCounterOffers); 173010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (mFormat != Format_Invalid) { 174010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten for (size_t i = 0; i < numOffers; ++i) { 175010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (offers[i] == mFormat) { 176010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten mNegotiated = true; 177010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return i; 178010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 179010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 180010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten if (numCounterOffers > 0) { 181010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten counterOffers[0] = mFormat; 182010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 183010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten numCounterOffers = 1; 184010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } else { 185010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten numCounterOffers = 0; 186010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten } 187010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten return (ssize_t) NEGOTIATE; 188010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} 189010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten 190010662326b9c43c703725f933e95e0897f8a6bddGlenn Kasten} // namespace android 191