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