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