1/*
2 * Copyright 2014, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdint.h>
18#include <string.h>
19
20#define LOG_TAG "AudioSPDIF"
21#include <utils/Log.h>
22#include <audio_utils/spdif/SPDIFEncoder.h>
23
24#include "AC3FrameScanner.h"
25#include "DTSFrameScanner.h"
26
27namespace android {
28
29// Burst Preamble defined in IEC61937-1
30const unsigned short SPDIFEncoder::kSPDIFSync1 = 0xF872; // Pa
31const unsigned short SPDIFEncoder::kSPDIFSync2 = 0x4E1F; // Pb
32
33static int32_t sEndianDetector = 1;
34#define isLittleEndian()  (*((uint8_t *)&sEndianDetector))
35
36SPDIFEncoder::SPDIFEncoder(audio_format_t format)
37  : mFramer(NULL)
38  , mSampleRate(48000)
39  , mBurstBuffer(NULL)
40  , mBurstBufferSizeBytes(0)
41  , mRateMultiplier(1)
42  , mBurstFrames(0)
43  , mByteCursor(0)
44  , mBitstreamNumber(0)
45  , mPayloadBytesPending(0)
46  , mScanning(true)
47{
48    switch(format) {
49        case AUDIO_FORMAT_AC3:
50        case AUDIO_FORMAT_E_AC3:
51            mFramer = new AC3FrameScanner();
52            break;
53        case AUDIO_FORMAT_DTS:
54        case AUDIO_FORMAT_DTS_HD:
55            mFramer = new DTSFrameScanner();
56            break;
57        default:
58            break;
59    }
60
61    // This a programmer error. Call isFormatSupported() first.
62    LOG_ALWAYS_FATAL_IF((mFramer == NULL),
63        "SPDIFEncoder: invalid audio format = 0x%08X", format);
64
65    mBurstBufferSizeBytes = sizeof(uint16_t)
66            * SPDIF_ENCODED_CHANNEL_COUNT
67            * mFramer->getMaxSampleFramesPerSyncFrame();
68
69    ALOGI("SPDIFEncoder: mBurstBufferSizeBytes = %zu, littleEndian = %d",
70            mBurstBufferSizeBytes, isLittleEndian());
71    mBurstBuffer = new uint16_t[mBurstBufferSizeBytes >> 1];
72    clearBurstBuffer();
73}
74
75SPDIFEncoder::SPDIFEncoder()
76    : SPDIFEncoder(AUDIO_FORMAT_AC3)
77{
78}
79
80SPDIFEncoder::~SPDIFEncoder()
81{
82    delete[] mBurstBuffer;
83    delete mFramer;
84}
85
86bool SPDIFEncoder::isFormatSupported(audio_format_t format)
87{
88    switch(format) {
89        case AUDIO_FORMAT_AC3:
90        case AUDIO_FORMAT_E_AC3:
91        case AUDIO_FORMAT_DTS:
92        case AUDIO_FORMAT_DTS_HD:
93            return true;
94        default:
95            return false;
96    }
97}
98
99int SPDIFEncoder::getBytesPerOutputFrame()
100{
101    return SPDIF_ENCODED_CHANNEL_COUNT * sizeof(int16_t);
102}
103
104void SPDIFEncoder::writeBurstBufferShorts(const uint16_t *buffer, size_t numShorts)
105{
106    // avoid static analyser warning
107    LOG_ALWAYS_FATAL_IF((mBurstBuffer == NULL), "mBurstBuffer never allocated");
108    mByteCursor = (mByteCursor + 1) & ~1; // round up to even byte
109    size_t bytesToWrite = numShorts * sizeof(uint16_t);
110    if ((mByteCursor + bytesToWrite) > mBurstBufferSizeBytes) {
111        ALOGE("SPDIFEncoder: Burst buffer overflow!");
112        reset();
113        return;
114    }
115    memcpy(&mBurstBuffer[mByteCursor >> 1], buffer, bytesToWrite);
116    mByteCursor += bytesToWrite;
117}
118
119// Pack the bytes into the short buffer in the order:
120//   byte[0] -> short[0] MSB
121//   byte[1] -> short[0] LSB
122//   byte[2] -> short[1] MSB
123//   byte[3] -> short[1] LSB
124//   etcetera
125// This way they should come out in the correct order for SPDIF on both
126// Big and Little Endian CPUs.
127void SPDIFEncoder::writeBurstBufferBytes(const uint8_t *buffer, size_t numBytes)
128{
129    size_t bytesToWrite = numBytes;
130    if ((mByteCursor + bytesToWrite) > mBurstBufferSizeBytes) {
131        ALOGE("SPDIFEncoder: Burst buffer overflow!");
132        clearBurstBuffer();
133        return;
134    }
135    uint16_t pad = mBurstBuffer[mByteCursor >> 1];
136    for (size_t i = 0; i < bytesToWrite; i++) {
137        if (mByteCursor & 1 ) {
138            pad |= *buffer++; // put second byte in LSB
139            mBurstBuffer[mByteCursor >> 1] = pad;
140            pad = 0;
141        } else {
142            pad |= (*buffer++) << 8; // put first byte in MSB
143        }
144        mByteCursor++;
145    }
146    // Save partially filled short.
147    if (mByteCursor & 1 ){
148        mBurstBuffer[mByteCursor >> 1] = pad;
149    }
150}
151
152void SPDIFEncoder::sendZeroPad()
153{
154    // Pad remainder of burst with zeros.
155    size_t burstSize = mFramer->getSampleFramesPerSyncFrame() * sizeof(uint16_t)
156            * SPDIF_ENCODED_CHANNEL_COUNT;
157    if (mByteCursor > burstSize) {
158        ALOGE("SPDIFEncoder: Burst buffer, contents too large!");
159        clearBurstBuffer();
160    } else {
161        // We don't have to write zeros because buffer already set to zero
162        // by clearBurstBuffer(). Just pretend we wrote zeros by
163        // incrementing cursor.
164        mByteCursor = burstSize;
165    }
166}
167
168void SPDIFEncoder::reset()
169{
170    ALOGV("SPDIFEncoder: reset()");
171    clearBurstBuffer();
172    if (mFramer != NULL) {
173        mFramer->resetBurst();
174    }
175    mPayloadBytesPending = 0;
176    mScanning = true;
177}
178
179void SPDIFEncoder::flushBurstBuffer()
180{
181    const int preambleSize = 4 * sizeof(uint16_t);
182    if (mByteCursor > preambleSize) {
183        // Set lengthCode for valid payload before zeroPad.
184        uint16_t numBytes = (mByteCursor - preambleSize);
185        mBurstBuffer[3] = mFramer->convertBytesToLengthCode(numBytes);
186
187        sendZeroPad();
188        writeOutput(mBurstBuffer, mByteCursor);
189    }
190    reset();
191}
192
193void SPDIFEncoder::clearBurstBuffer()
194{
195    if (mBurstBuffer) {
196        memset(mBurstBuffer, 0, mBurstBufferSizeBytes);
197    }
198    mByteCursor = 0;
199}
200
201void SPDIFEncoder::startDataBurst()
202{
203    // Encode IEC61937-1 Burst Preamble
204    uint16_t preamble[4];
205
206    uint16_t burstInfo = (mBitstreamNumber << 13)
207        | (mFramer->getDataTypeInfo() << 8)
208        | mFramer->getDataType();
209
210    mRateMultiplier = mFramer->getRateMultiplier();
211
212    preamble[0] = kSPDIFSync1;
213    preamble[1] = kSPDIFSync2;
214    preamble[2] = burstInfo;
215    preamble[3] = 0; // lengthCode - This will get set after the buffer is full.
216    writeBurstBufferShorts(preamble, 4);
217}
218
219size_t SPDIFEncoder::startSyncFrame()
220{
221    // Write start of encoded frame that was buffered in frame detector.
222    size_t syncSize = mFramer->getHeaderSizeBytes();
223    writeBurstBufferBytes(mFramer->getHeaderAddress(), syncSize);
224    return mFramer->getFrameSizeBytes() - syncSize;
225}
226
227// Wraps raw encoded data into a data burst.
228ssize_t SPDIFEncoder::write( const void *buffer, size_t numBytes )
229{
230    size_t bytesLeft = numBytes;
231    const uint8_t *data = (const uint8_t *)buffer;
232    ALOGV("SPDIFEncoder: mScanning = %d, write(buffer[0] = 0x%02X, numBytes = %zu)",
233        mScanning, (uint) *data, numBytes);
234    while (bytesLeft > 0) {
235        if (mScanning) {
236        // Look for beginning of next encoded frame.
237            if (mFramer->scan(*data)) {
238                if (mByteCursor == 0) {
239                    startDataBurst();
240                } else if (mFramer->isFirstInBurst()) {
241                    // Make sure that this frame is at the beginning of the data burst.
242                    flushBurstBuffer();
243                    startDataBurst();
244                }
245                mPayloadBytesPending = startSyncFrame();
246                mScanning = false;
247            }
248            data++;
249            bytesLeft--;
250        } else {
251            // Write payload until we hit end of frame.
252            size_t bytesToWrite = bytesLeft;
253            // Only write as many as we need to finish the frame.
254            if (bytesToWrite > mPayloadBytesPending) {
255                bytesToWrite = mPayloadBytesPending;
256            }
257            writeBurstBufferBytes(data, bytesToWrite);
258
259            data += bytesToWrite;
260            bytesLeft -= bytesToWrite;
261            mPayloadBytesPending -= bytesToWrite;
262
263            // If we have all the payload then send a data burst.
264            if (mPayloadBytesPending == 0) {
265                if (mFramer->isLastInBurst()) {
266                    flushBurstBuffer();
267                }
268                mScanning = true;
269            }
270        }
271    }
272    return numBytes;
273}
274
275}  // namespace android
276