• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 namespace android {
28 
29 // Burst Preamble defined in IEC61937-1
30 const unsigned short SPDIFEncoder::kSPDIFSync1 = 0xF872; // Pa
31 const unsigned short SPDIFEncoder::kSPDIFSync2 = 0x4E1F; // Pb
32 
33 static int32_t sEndianDetector = 1;
34 #define isLittleEndian()  (*((uint8_t *)&sEndianDetector))
35 
SPDIFEncoder(audio_format_t format)36 SPDIFEncoder::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 
SPDIFEncoder()75 SPDIFEncoder::SPDIFEncoder()
76     : SPDIFEncoder(AUDIO_FORMAT_AC3)
77 {
78 }
79 
~SPDIFEncoder()80 SPDIFEncoder::~SPDIFEncoder()
81 {
82     delete[] mBurstBuffer;
83     delete mFramer;
84 }
85 
isFormatSupported(audio_format_t format)86 bool 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 
getBytesPerOutputFrame()99 int SPDIFEncoder::getBytesPerOutputFrame()
100 {
101     return SPDIF_ENCODED_CHANNEL_COUNT * sizeof(int16_t);
102 }
103 
writeBurstBufferShorts(const uint16_t * buffer,size_t numShorts)104 void 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.
writeBurstBufferBytes(const uint8_t * buffer,size_t numBytes)127 void 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 
sendZeroPad()152 void 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 
reset()168 void 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 
flushBurstBuffer()179 void 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 
clearBurstBuffer()193 void SPDIFEncoder::clearBurstBuffer()
194 {
195     if (mBurstBuffer) {
196         memset(mBurstBuffer, 0, mBurstBufferSizeBytes);
197     }
198     mByteCursor = 0;
199 }
200 
startDataBurst()201 void 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 
startSyncFrame()219 size_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.
write(const void * buffer,size_t numBytes)228 ssize_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