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 //#define LOG_NDEBUG 0
22 #include <log/log.h>
23 #include <audio_utils/spdif/SPDIFEncoder.h>
24 
25 #include "AC3FrameScanner.h"
26 #include "DTSFrameScanner.h"
27 
28 namespace android {
29 
30 static int32_t sEndianDetector = 1;
31 #define isLittleEndian()  (*((uint8_t *)&sEndianDetector))
32 
SPDIFEncoder(audio_format_t format)33 SPDIFEncoder::SPDIFEncoder(audio_format_t format)
34   : mFramer(NULL)
35   , mSampleRate(48000)
36   , mBurstBuffer(NULL)
37   , mBurstBufferSizeBytes(0)
38   , mRateMultiplier(1)
39   , mBurstFrames(0)
40   , mByteCursor(0)
41   , mBitstreamNumber(0)
42   , mPayloadBytesPending(0)
43   , mScanning(true)
44 {
45     switch(format) {
46         case AUDIO_FORMAT_AC3:
47         case AUDIO_FORMAT_E_AC3:
48         case AUDIO_FORMAT_E_AC3_JOC:
49             mFramer = new AC3FrameScanner(format);
50             break;
51         case AUDIO_FORMAT_DTS:
52         case AUDIO_FORMAT_DTS_HD:
53             mFramer = new DTSFrameScanner();
54             break;
55         default:
56             break;
57     }
58 
59     // This a programmer error. Call isFormatSupported() first.
60     LOG_ALWAYS_FATAL_IF((mFramer == NULL),
61         "SPDIFEncoder: invalid audio format = 0x%08X", format);
62 
63     mBurstBufferSizeBytes = sizeof(uint16_t)
64             * kSpdifEncodedChannelCount
65             * mFramer->getMaxSampleFramesPerSyncFrame();
66 
67     ALOGI("SPDIFEncoder: mBurstBufferSizeBytes = %zu, littleEndian = %d",
68             mBurstBufferSizeBytes, isLittleEndian());
69     mBurstBuffer = new uint16_t[mBurstBufferSizeBytes >> 1];
70     clearBurstBuffer();
71 }
72 
SPDIFEncoder()73 SPDIFEncoder::SPDIFEncoder()
74     : SPDIFEncoder(AUDIO_FORMAT_AC3)
75 {
76 }
77 
~SPDIFEncoder()78 SPDIFEncoder::~SPDIFEncoder()
79 {
80     delete[] mBurstBuffer;
81     delete mFramer;
82 }
83 
isFormatSupported(audio_format_t format)84 bool SPDIFEncoder::isFormatSupported(audio_format_t format)
85 {
86     switch(format) {
87         case AUDIO_FORMAT_AC3:
88         case AUDIO_FORMAT_E_AC3:
89         case AUDIO_FORMAT_E_AC3_JOC:
90         case AUDIO_FORMAT_DTS:
91         case AUDIO_FORMAT_DTS_HD:
92             return true;
93         default:
94             return false;
95     }
96 }
97 
getBytesPerOutputFrame()98 int SPDIFEncoder::getBytesPerOutputFrame()
99 {
100     return kSpdifEncodedChannelCount * sizeof(int16_t);
101 }
102 
wouldOverflowBuffer(size_t numBytes) const103 bool SPDIFEncoder::wouldOverflowBuffer(size_t numBytes) const {
104     // Avoid numeric overflow when calculating whether the buffer would overflow.
105     return (numBytes > mBurstBufferSizeBytes)
106         || (mByteCursor > (mBurstBufferSizeBytes - numBytes));  // (max - n) won't overflow
107 }
108 
writeBurstBufferShorts(const uint16_t * buffer,size_t numShorts)109 void SPDIFEncoder::writeBurstBufferShorts(const uint16_t *buffer, size_t numShorts)
110 {
111     // avoid static analyser warning
112     LOG_ALWAYS_FATAL_IF((mBurstBuffer == NULL), "mBurstBuffer never allocated");
113 
114     mByteCursor = (mByteCursor + 1) & ~1; // round up to even byte
115     size_t bytesToWrite = numShorts * sizeof(uint16_t);
116     if (wouldOverflowBuffer(bytesToWrite)) {
117         ALOGE("SPDIFEncoder::%s() Burst buffer overflow!", __func__);
118         reset();
119         return;
120     }
121     memcpy(&mBurstBuffer[mByteCursor >> 1], buffer, bytesToWrite);
122     mByteCursor += bytesToWrite;
123 }
124 
125 // Pack the bytes into the short buffer in the order:
126 //   byte[0] -> short[0] MSB
127 //   byte[1] -> short[0] LSB
128 //   byte[2] -> short[1] MSB
129 //   byte[3] -> short[1] LSB
130 //   etcetera
131 // This way they should come out in the correct order for SPDIF on both
132 // Big and Little Endian CPUs.
writeBurstBufferBytes(const uint8_t * buffer,size_t numBytes)133 void SPDIFEncoder::writeBurstBufferBytes(const uint8_t *buffer, size_t numBytes)
134 {
135     if (wouldOverflowBuffer(numBytes)) {
136         ALOGE("SPDIFEncoder::%s() Burst buffer overflow!", __func__);
137         clearBurstBuffer();
138         return;
139     }
140 
141     // Avoid reading first word past end of mBurstBuffer.
142     if (numBytes == 0) {
143         return;
144     }
145     // Pack bytes into short buffer.
146     uint16_t pad = mBurstBuffer[mByteCursor >> 1];
147     for (size_t i = 0; i < numBytes; i++) {
148         if (mByteCursor & 1 ) {
149             pad |= *buffer++; // put second byte in LSB
150             mBurstBuffer[mByteCursor >> 1] = pad;
151             pad = 0;
152         } else {
153             pad |= (*buffer++) << 8; // put first byte in MSB
154         }
155         mByteCursor++;
156     }
157     // Save partially filled short.
158     if (mByteCursor & 1 ){
159         mBurstBuffer[mByteCursor >> 1] = pad;
160     }
161 }
162 
sendZeroPad()163 void SPDIFEncoder::sendZeroPad()
164 {
165     // Pad remainder of burst with zeros.
166     size_t burstSize = mFramer->getSampleFramesPerSyncFrame() * sizeof(uint16_t)
167             * kSpdifEncodedChannelCount;
168     if (mByteCursor > burstSize) {
169         ALOGE("SPDIFEncoder: Burst buffer, contents too large!");
170         clearBurstBuffer();
171     } else {
172         // We don't have to write zeros because buffer already set to zero
173         // by clearBurstBuffer(). Just pretend we wrote zeros by
174         // incrementing cursor.
175         mByteCursor = burstSize;
176     }
177 }
178 
reset()179 void SPDIFEncoder::reset()
180 {
181     ALOGV("SPDIFEncoder: reset()");
182     clearBurstBuffer();
183     if (mFramer != NULL) {
184         mFramer->resetBurst();
185     }
186     mPayloadBytesPending = 0;
187     mScanning = true;
188 }
189 
flushBurstBuffer()190 void SPDIFEncoder::flushBurstBuffer()
191 {
192     const int preambleSize = 4 * sizeof(uint16_t);
193     if (mByteCursor > preambleSize) {
194         // Set lengthCode for valid payload before zeroPad.
195         uint16_t numBytes = (mByteCursor - preambleSize);
196         mBurstBuffer[3] = mFramer->convertBytesToLengthCode(numBytes);
197 
198         sendZeroPad();
199         size_t bytesWritten = 0;
200         while (mByteCursor > bytesWritten) {
201             ssize_t res = writeOutput(mBurstBuffer + bytesWritten, mByteCursor - bytesWritten);
202             if (res < 0) {
203                 ALOGE("SPDIFEncoder::%s write error %zd", __func__, res);
204                 break;
205             } else {
206                 bytesWritten += res;
207             }
208         }
209     }
210     reset();
211 }
212 
clearBurstBuffer()213 void SPDIFEncoder::clearBurstBuffer()
214 {
215     if (mBurstBuffer) {
216         memset(mBurstBuffer, 0, mBurstBufferSizeBytes);
217     }
218     mByteCursor = 0;
219 }
220 
startDataBurst()221 void SPDIFEncoder::startDataBurst()
222 {
223     // Encode IEC61937-1 Burst Preamble
224     uint16_t preamble[4];
225 
226     uint16_t burstInfo = (mBitstreamNumber << 13)
227         | (mFramer->getDataTypeInfo() << 8)
228         | mFramer->getDataType();
229 
230     mRateMultiplier = mFramer->getRateMultiplier();
231 
232     preamble[0] = kSpdifSync1;
233     preamble[1] = kSpdifSync2;
234     preamble[2] = burstInfo;
235     preamble[3] = 0; // lengthCode - This will get set after the buffer is full.
236     writeBurstBufferShorts(preamble, 4);
237 }
238 
startSyncFrame()239 size_t SPDIFEncoder::startSyncFrame()
240 {
241     // Write start of encoded frame that was buffered in frame detector.
242     size_t headerSize = mFramer->getHeaderSizeBytes();
243     writeBurstBufferBytes(mFramer->getHeaderAddress(), headerSize);
244     // This is provided by the encoded audio file and may be invalid.
245     size_t frameSize = mFramer->getFrameSizeBytes();
246     if (frameSize < headerSize) {
247         ALOGE("SPDIFEncoder: invalid frameSize = %zu", frameSize);
248         return 0;
249     }
250     // Calculate how many more bytes we need to complete the frame.
251     return frameSize - headerSize;
252 }
253 
254 // Wraps raw encoded data into a data burst.
write(const void * buffer,size_t numBytes)255 ssize_t SPDIFEncoder::write( const void *buffer, size_t numBytes )
256 {
257     size_t bytesLeft = numBytes;
258     const uint8_t *data = (const uint8_t *)buffer;
259     ALOGV("SPDIFEncoder: mScanning = %d, write(buffer[0] = 0x%02X, numBytes = %zu)",
260         mScanning, (uint) *data, numBytes);
261     while (bytesLeft > 0) {
262         if (mScanning) {
263         // Look for beginning of next encoded frame.
264             if (mFramer->scan(*data)) {
265                 if (mByteCursor == 0) {
266                     startDataBurst();
267                 } else if (mFramer->isFirstInBurst()) {
268                     // Make sure that this frame is at the beginning of the data burst.
269                     flushBurstBuffer();
270                     startDataBurst();
271                 }
272                 mPayloadBytesPending = startSyncFrame();
273                 mScanning = false;
274             }
275             data++;
276             bytesLeft--;
277         } else {
278             // Write payload until we hit end of frame.
279             size_t bytesToWrite = bytesLeft;
280             // Only write as many as we need to finish the frame.
281             if (bytesToWrite > mPayloadBytesPending) {
282                 bytesToWrite = mPayloadBytesPending;
283             }
284             writeBurstBufferBytes(data, bytesToWrite);
285 
286             data += bytesToWrite;
287             bytesLeft -= bytesToWrite;
288             mPayloadBytesPending -= bytesToWrite;
289 
290             // If we have all the payload then send a data burst.
291             if (mPayloadBytesPending == 0) {
292                 if (mFramer->isLastInBurst()) {
293                     flushBurstBuffer();
294                 }
295                 mScanning = true;
296             }
297         }
298     }
299     return numBytes;
300 }
301 
302 }  // namespace android
303