/src/libsndfile/src/ALAC/alac_encoder.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2011 Apple Inc. All rights reserved. |
3 | | * Copyright (C) 2012-2015 Erik de Castro Lopo <erikd@mega-nerd.com> |
4 | | * |
5 | | * @APPLE_APACHE_LICENSE_HEADER_START@ |
6 | | * |
7 | | * Licensed under the Apache License, Version 2.0 (the "License") ; |
8 | | * you may not use this file except in compliance with the License. |
9 | | * You may obtain a copy of the License at |
10 | | * |
11 | | * http://www.apache.org/licenses/LICENSE-2.0 |
12 | | * |
13 | | * Unless required by applicable law or agreed to in writing, software |
14 | | * distributed under the License is distributed on an "AS IS" BASIS, |
15 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | | * See the License for the specific language governing permissions and |
17 | | * limitations under the License. |
18 | | * |
19 | | * @APPLE_APACHE_LICENSE_HEADER_END@ |
20 | | */ |
21 | | |
22 | | /* |
23 | | File: ALACEncoder.cpp |
24 | | */ |
25 | | |
26 | | // build stuff |
27 | | #define VERBOSE_DEBUG 0 |
28 | | #define DebugMsg printf |
29 | | |
30 | | // headers |
31 | | #include "config.h" |
32 | | |
33 | | #include <stdio.h> |
34 | | #include <stdlib.h> |
35 | | #include <stdbool.h> |
36 | | #include <string.h> |
37 | | |
38 | | #include "sfendian.h" |
39 | | |
40 | | #include "alac_codec.h" |
41 | | |
42 | | #include "aglib.h" |
43 | | #include "dplib.h" |
44 | | #include "matrixlib.h" |
45 | | |
46 | | #include "ALACBitUtilities.h" |
47 | | #include "ALACAudioTypes.h" |
48 | | #include "EndianPortable.h" |
49 | | |
50 | | static void GetConfig (ALAC_ENCODER *p, ALACSpecificConfig * config) ; |
51 | | |
52 | | static int32_t EncodeStereo (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples) ; |
53 | | static int32_t EncodeStereoFast (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples) ; |
54 | | static int32_t EncodeStereoEscape (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * input, uint32_t stride, uint32_t numSamples) ; |
55 | | static int32_t EncodeMono (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples) ; |
56 | | |
57 | | |
58 | | |
59 | | // Note: in C you can't typecast to a 2-dimensional array pointer but that's what we need when |
60 | | // picking which coefs to use so we declare this typedef b/c we *can* typecast to this type |
61 | | typedef int16_t (*SearchCoefs) [kALACMaxCoefs] ; |
62 | | |
63 | | // defines/constants |
64 | | const uint32_t kALACEncoderMagic = MAKE_MARKER ('d', 'p', 'g', 'e') ; |
65 | | const uint32_t kMaxSampleSize = 32 ; // max allowed bit width is 32 |
66 | | const uint32_t kDefaultMixBits = 2 ; |
67 | | const uint32_t kDefaultMixRes = 0 ; |
68 | | const uint32_t kMaxRes = 4 ; |
69 | | const uint32_t kDefaultNumUV = 8 ; |
70 | | const uint32_t kMinUV = 4 ; |
71 | | const uint32_t kMaxUV = 8 ; |
72 | | |
73 | | // static functions |
74 | | #if VERBOSE_DEBUG |
75 | | static void AddFiller (BitBuffer * bits, int32_t numBytes) ; |
76 | | #endif |
77 | | |
78 | | |
79 | | /* |
80 | | Map Format: 3-bit field per channel which is the same as the "element tag" that should be placed |
81 | | at the beginning of the frame for that channel. Indicates whether SCE, CPE, or LFE. |
82 | | Each particular field is accessed via the current channel indx. Note that the channel |
83 | | indx increments by two for channel pairs. |
84 | | |
85 | | For example: |
86 | | |
87 | | C L R 3-channel input = (ID_CPE << 3) | (ID_SCE) |
88 | | indx 0 value = (map & (0x7ul << (0 * 3))) >> (0 * 3) |
89 | | indx 1 value = (map & (0x7ul << (1 * 3))) >> (1 * 3) |
90 | | |
91 | | C L R Ls Rs LFE 5.1-channel input = (ID_LFE << 15) | (ID_CPE << 9) | (ID_CPE << 3) | (ID_SCE) |
92 | | indx 0 value = (map & (0x7ul << (0 * 3))) >> (0 * 3) |
93 | | indx 1 value = (map & (0x7ul << (1 * 3))) >> (1 * 3) |
94 | | indx 3 value = (map & (0x7ul << (3 * 3))) >> (3 * 3) |
95 | | indx 5 value = (map & (0x7ul << (5 * 3))) >> (5 * 3) |
96 | | indx 7 value = (map & (0x7ul << (7 * 3))) >> (7 * 3) |
97 | | */ |
98 | | static const uint32_t sChannelMaps [kALACMaxChannels] = |
99 | | { |
100 | | ID_SCE, |
101 | | ID_CPE, |
102 | | (ID_CPE << 3) | (ID_SCE), |
103 | | (ID_SCE << 9) | (ID_CPE << 3) | (ID_SCE), |
104 | | (ID_CPE << 9) | (ID_CPE << 3) | (ID_SCE), |
105 | | (ID_SCE << 15) | (ID_CPE << 9) | (ID_CPE << 3) | (ID_SCE), |
106 | | (ID_SCE << 18) | (ID_SCE << 15) | (ID_CPE << 9) | (ID_CPE << 3) | (ID_SCE), |
107 | | (ID_SCE << 21) | (ID_CPE << 15) | (ID_CPE << 9) | (ID_CPE << 3) | (ID_SCE) |
108 | | } ; |
109 | | |
110 | | #if PRAGMA_MARK |
111 | | #pragma mark - |
112 | | #endif |
113 | | |
114 | | void |
115 | | alac_set_fastmode (ALAC_ENCODER * p, int32_t fast) |
116 | 0 | { |
117 | 0 | p->mFastMode = fast ; |
118 | 0 | } |
119 | | |
120 | | |
121 | | /* |
122 | | HEADER SPECIFICATION |
123 | | |
124 | | For every segment we adopt the following header: |
125 | | |
126 | | 1 byte reserved (always 0) |
127 | | 1 byte flags (see below) |
128 | | [4 byte frame length] (optional, see below) |
129 | | ---Next, the per-segment ALAC parameters--- |
130 | | 1 byte mixBits (middle-side parameter) |
131 | | 1 byte mixRes (middle-side parameter, interpreted as signed char) |
132 | | |
133 | | 1 byte shiftU (4 bits modeU, 4 bits denShiftU) |
134 | | 1 byte filterU (3 bits pbFactorU, 5 bits numU) |
135 | | (numU) shorts (signed DP coefficients for V channel) |
136 | | ---Next, 2nd-channel ALAC parameters in case of stereo mode--- |
137 | | 1 byte shiftV (4 bits modeV, 4 bits denShiftV) |
138 | | 1 byte filterV (3 bits pbFactorV, 5 bits numV) |
139 | | (numV) shorts (signed DP coefficients for V channel) |
140 | | ---After this come the shift-off bytes for (>= 24)-bit data (n-byte shift) if indicated--- |
141 | | ---Then comes the AG-compressor bitstream--- |
142 | | |
143 | | |
144 | | FLAGS |
145 | | ----- |
146 | | |
147 | | The presence of certain flag bits changes the header format such that the parameters might |
148 | | not even be sent. The currently defined flags format is: |
149 | | |
150 | | 0000psse |
151 | | |
152 | | where 0 = reserved, must be 0 |
153 | | p = 1-bit field "partial frame" flag indicating 32-bit frame length follows this byte |
154 | | ss = 2-bit field indicating "number of shift-off bytes ignored by compression" |
155 | | e = 1-bit field indicating "escape" |
156 | | |
157 | | The "partial frame" flag means that the following segment is not equal to the frame length specified |
158 | | in the out-of-band decoder configuration. This allows the decoder to deal with end-of-file partial |
159 | | segments without incurring the 32-bit overhead for each segment. |
160 | | |
161 | | The "shift-off" field indicates the number of bytes at the bottom of the word that were passed through |
162 | | uncompressed. The reason for this is that the entropy inherent in the LS bytes of >= 24-bit words |
163 | | quite often means that the frame would have to be "escaped" b/c the compressed size would be >= the |
164 | | uncompressed size. However, by shifting the input values down and running the remaining bits through |
165 | | the normal compression algorithm, a net win can be achieved. If this field is non-zero, it means that |
166 | | the shifted-off bytes follow after the parameter section of the header and before the compressed |
167 | | bitstream. Note that doing this also allows us to use matrixing on 32-bit inputs after one or more |
168 | | bytes are shifted off the bottom which helps the eventual compression ratio. For stereo channels, |
169 | | the shifted off bytes are interleaved. |
170 | | |
171 | | The "escape" flag means that this segment was not compressed b/c the compressed size would be |
172 | | >= uncompressed size. In that case, the audio data was passed through uncompressed after the header. |
173 | | The other header parameter bytes will not be sent. |
174 | | |
175 | | |
176 | | PARAMETERS |
177 | | ---------- |
178 | | |
179 | | If the segment is not a partial or escape segment, the total header size (in bytes) is given exactly by: |
180 | | |
181 | | 4 + (2 + 2 * numU) (mono mode) |
182 | | 4 + (2 + 2 * numV) + (2 + 2 * numV) (stereo mode) |
183 | | |
184 | | where the ALAC filter-lengths numU, numV are bounded by a |
185 | | constant (in the current source, numU, numV <= NUMCOEPAIRS), and |
186 | | this forces an absolute upper bound on header size. |
187 | | |
188 | | Each segment-decode process loads up these bytes from the front of the |
189 | | local stream, in the above order, then follows with the entropy-encoded |
190 | | bits for the given segment. |
191 | | |
192 | | To generalize middle-side, there are various mixing modes including middle-side, each lossless, |
193 | | as embodied in the mix () and unmix () functions. These functions exploit a generalized middle-side |
194 | | transformation: |
195 | | |
196 | | u := [(rL + (m-r)R)/m] ; |
197 | | v := L - R ; |
198 | | |
199 | | where [ ] denotes integer floor. The (lossless) inverse is |
200 | | |
201 | | L = u + v - [rV/m] ; |
202 | | R = L - v ; |
203 | | |
204 | | In the segment header, m and r are encoded in mixBits and mixRes. |
205 | | Classical "middle-side" is obtained with m = 2, r = 1, but now |
206 | | we have more generalized mixes. |
207 | | |
208 | | NOTES |
209 | | ----- |
210 | | The relevance of the ALAC coefficients is explained in detail |
211 | | in patent documents. |
212 | | */ |
213 | | |
214 | | /* |
215 | | EncodeStereo () |
216 | | - encode a channel pair |
217 | | */ |
218 | | static int32_t |
219 | | EncodeStereo (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples) |
220 | 0 | { |
221 | 0 | BitBuffer workBits ; |
222 | 0 | BitBuffer startBits = *bitstream ; // squirrel away copy of current state in case we need to go back and do an escape packet |
223 | 0 | AGParamRec agParams ; |
224 | 0 | uint32_t bits1, bits2 ; |
225 | 0 | uint32_t dilate ; |
226 | 0 | int32_t mixBits, mixRes, maxRes ; |
227 | 0 | uint32_t minBits, minBits1, minBits2 ; |
228 | 0 | uint32_t numU, numV ; |
229 | 0 | uint32_t mode ; |
230 | 0 | uint32_t pbFactor ; |
231 | 0 | uint32_t chanBits ; |
232 | 0 | uint8_t bytesShifted ; |
233 | 0 | SearchCoefs coefsU ; |
234 | 0 | SearchCoefs coefsV ; |
235 | 0 | uint32_t indx ; |
236 | 0 | uint8_t partialFrame ; |
237 | 0 | uint32_t escapeBits ; |
238 | 0 | bool doEscape ; |
239 | 0 | int32_t status = ALAC_noErr ; |
240 | 0 | int32_t bestRes ; |
241 | | |
242 | | // make sure we handle this bit-depth before we get going |
243 | 0 | RequireAction ((p->mBitDepth == 16) || (p->mBitDepth == 20) || (p->mBitDepth == 24) || (p->mBitDepth == 32), return kALAC_ParamError ;) ; |
244 | | |
245 | | // reload coefs pointers for this channel pair |
246 | | // - note that, while you might think they should be re-initialized per block, retaining state across blocks |
247 | | // actually results in better overall compression |
248 | | // - strangely, re-using the same coefs for the different passes of the "mixRes" search loop instead of using |
249 | | // different coefs for the different passes of "mixRes" results in even better compression |
250 | 0 | coefsU = (SearchCoefs) p->mCoefsU [channelIndex] ; |
251 | 0 | coefsV = (SearchCoefs) p->mCoefsV [channelIndex] ; |
252 | | |
253 | | // matrix encoding adds an extra bit but 32-bit inputs cannot be matrixed b/c 33 is too many |
254 | | // so enable 16-bit "shift off" and encode in 17-bit mode |
255 | | // - in addition, 24-bit mode really improves with one byte shifted off |
256 | 0 | if (p->mBitDepth == 32) |
257 | 0 | bytesShifted = 2 ; |
258 | 0 | else if (p->mBitDepth >= 24) |
259 | 0 | bytesShifted = 1 ; |
260 | 0 | else |
261 | 0 | bytesShifted = 0 ; |
262 | |
|
263 | 0 | chanBits = p->mBitDepth - (bytesShifted * 8) + 1 ; |
264 | | |
265 | | // flag whether or not this is a partial frame |
266 | 0 | partialFrame = (numSamples == p->mFrameSize) ? 0 : 1 ; |
267 | | |
268 | | // brute-force encode optimization loop |
269 | | // - run over variations of the encoding params to find the best choice |
270 | 0 | mixBits = kDefaultMixBits ; |
271 | 0 | maxRes = kMaxRes ; |
272 | 0 | numU = numV = kDefaultNumUV ; |
273 | 0 | mode = 0 ; |
274 | 0 | pbFactor = 4 ; |
275 | 0 | dilate = 8 ; |
276 | |
|
277 | 0 | minBits = minBits1 = minBits2 = 1ul << 31 ; |
278 | |
|
279 | 0 | bestRes = p->mLastMixRes [channelIndex] ; |
280 | |
|
281 | 0 | for (mixRes = 0 ; mixRes <= maxRes ; mixRes++) |
282 | 0 | { |
283 | | // mix the stereo inputs |
284 | 0 | switch (p->mBitDepth) |
285 | 0 | { |
286 | 0 | case 16: |
287 | 0 | mix16 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples / dilate, mixBits, mixRes) ; |
288 | 0 | break ; |
289 | 0 | case 20: |
290 | 0 | mix20 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples / dilate, mixBits, mixRes) ; |
291 | 0 | break ; |
292 | 0 | case 24: |
293 | | // includes extraction of shifted-off bytes |
294 | 0 | mix24 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples / dilate, |
295 | 0 | mixBits, mixRes, p->mShiftBufferUV, bytesShifted) ; |
296 | 0 | break ; |
297 | 0 | case 32: |
298 | | // includes extraction of shifted-off bytes |
299 | 0 | mix32 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples / dilate, |
300 | 0 | mixBits, mixRes, p->mShiftBufferUV, bytesShifted) ; |
301 | 0 | break ; |
302 | 0 | } |
303 | | |
304 | 0 | BitBufferInit (&workBits, p->mWorkBuffer, p->mMaxOutputBytes) ; |
305 | | |
306 | | // run the dynamic predictors |
307 | 0 | pc_block (p->mMixBufferU, p->mPredictorU, numSamples / dilate, coefsU [numU - 1], numU, chanBits, DENSHIFT_DEFAULT) ; |
308 | 0 | pc_block (p->mMixBufferV, p->mPredictorV, numSamples / dilate, coefsV [numV - 1], numV, chanBits, DENSHIFT_DEFAULT) ; |
309 | | |
310 | | // run the lossless compressor on each channel |
311 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples / dilate, numSamples / dilate, MAX_RUN_DEFAULT) ; |
312 | 0 | status = dyn_comp (&agParams, p->mPredictorU, &workBits, numSamples / dilate, chanBits, &bits1) ; |
313 | 0 | RequireNoErr (status, goto Exit ;) ; |
314 | |
|
315 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples / dilate, numSamples / dilate, MAX_RUN_DEFAULT) ; |
316 | 0 | status = dyn_comp (&agParams, p->mPredictorV, &workBits, numSamples / dilate, chanBits, &bits2) ; |
317 | 0 | RequireNoErr (status, goto Exit ;) ; |
318 | | |
319 | | // look for best match |
320 | 0 | if ((bits1 + bits2) < minBits1) |
321 | 0 | { |
322 | 0 | minBits1 = bits1 + bits2 ; |
323 | 0 | bestRes = mixRes ; |
324 | 0 | } |
325 | 0 | } |
326 | | |
327 | 0 | p->mLastMixRes [channelIndex] = (int16_t) bestRes ; |
328 | | |
329 | | // mix the stereo inputs with the current best mixRes |
330 | 0 | mixRes = p->mLastMixRes [channelIndex] ; |
331 | 0 | switch (p->mBitDepth) |
332 | 0 | { |
333 | 0 | case 16: |
334 | 0 | mix16 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes) ; |
335 | 0 | break ; |
336 | 0 | case 20: |
337 | 0 | mix20 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes) ; |
338 | 0 | break ; |
339 | 0 | case 24: |
340 | | // also extracts the shifted off bytes into the shift buffers |
341 | 0 | mix24 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, |
342 | 0 | mixBits, mixRes, p->mShiftBufferUV, bytesShifted) ; |
343 | 0 | break ; |
344 | 0 | case 32: |
345 | | // also extracts the shifted off bytes into the shift buffers |
346 | 0 | mix32 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, |
347 | 0 | mixBits, mixRes, p->mShiftBufferUV, bytesShifted) ; |
348 | 0 | break ; |
349 | 0 | } |
350 | | |
351 | | // now it's time for the predictor coefficient search loop |
352 | 0 | numU = numV = kMinUV ; |
353 | 0 | minBits1 = minBits2 = 1ul << 31 ; |
354 | |
|
355 | 0 | for (uint32_t numUV = kMinUV ; numUV <= kMaxUV ; numUV += 4) |
356 | 0 | { |
357 | 0 | BitBufferInit (&workBits, p->mWorkBuffer, p->mMaxOutputBytes) ; |
358 | |
|
359 | 0 | dilate = 32 ; |
360 | | |
361 | | // run the predictor over the same data multiple times to help it converge |
362 | 0 | for (uint32_t converge = 0 ; converge < 8 ; converge++) |
363 | 0 | { |
364 | 0 | pc_block (p->mMixBufferU, p->mPredictorU, numSamples / dilate, coefsU [numUV-1], numUV, chanBits, DENSHIFT_DEFAULT) ; |
365 | 0 | pc_block (p->mMixBufferV, p->mPredictorV, numSamples / dilate, coefsV [numUV-1], numUV, chanBits, DENSHIFT_DEFAULT) ; |
366 | 0 | } |
367 | |
|
368 | 0 | dilate = 8 ; |
369 | |
|
370 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples / dilate, numSamples / dilate, MAX_RUN_DEFAULT) ; |
371 | 0 | status = dyn_comp (&agParams, p->mPredictorU, &workBits, numSamples / dilate, chanBits, &bits1) ; |
372 | |
|
373 | 0 | if ((bits1 * dilate + 16 * numUV) < minBits1) |
374 | 0 | { |
375 | 0 | minBits1 = bits1 * dilate + 16 * numUV ; |
376 | 0 | numU = numUV ; |
377 | 0 | } |
378 | |
|
379 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples / dilate, numSamples / dilate, MAX_RUN_DEFAULT) ; |
380 | 0 | status = dyn_comp (&agParams, p->mPredictorV, &workBits, numSamples / dilate, chanBits, &bits2) ; |
381 | |
|
382 | 0 | if ((bits2 * dilate + 16 * numUV) < minBits2) |
383 | 0 | { |
384 | 0 | minBits2 = bits2 * dilate + 16 * numUV ; |
385 | 0 | numV = numUV ; |
386 | 0 | } |
387 | 0 | } |
388 | | |
389 | | // test for escape hatch if best calculated compressed size turns out to be more than the input size |
390 | 0 | minBits = minBits1 + minBits2 + (8 /* mixRes/maxRes/etc. */ * 8) + ((partialFrame == true) ? 32 : 0) ; |
391 | 0 | if (bytesShifted != 0) |
392 | 0 | minBits += (numSamples * (bytesShifted * 8) * 2) ; |
393 | |
|
394 | 0 | escapeBits = (numSamples * p->mBitDepth * 2) + ((partialFrame == true) ? 32 : 0) + (2 * 8) ; /* 2 common header bytes */ |
395 | |
|
396 | 0 | doEscape = (minBits >= escapeBits) ? true : false ; |
397 | |
|
398 | 0 | if (doEscape == false) |
399 | 0 | { |
400 | | // write bitstream header and coefs |
401 | 0 | BitBufferWrite (bitstream, 0, 12) ; |
402 | 0 | BitBufferWrite (bitstream, (partialFrame << 3) | (bytesShifted << 1), 4) ; |
403 | 0 | if (partialFrame) |
404 | 0 | BitBufferWrite (bitstream, numSamples, 32) ; |
405 | 0 | BitBufferWrite (bitstream, mixBits, 8) ; |
406 | 0 | BitBufferWrite (bitstream, mixRes, 8) ; |
407 | | |
408 | | //Assert ((mode < 16) && (DENSHIFT_DEFAULT < 16)) ; |
409 | | //Assert ((pbFactor < 8) && (numU < 32)) ; |
410 | | //Assert ((pbFactor < 8) && (numV < 32)) ; |
411 | |
|
412 | 0 | BitBufferWrite (bitstream, (mode << 4) | DENSHIFT_DEFAULT, 8) ; |
413 | 0 | BitBufferWrite (bitstream, (pbFactor << 5) | numU, 8) ; |
414 | 0 | for (indx = 0 ; indx < numU ; indx++) |
415 | 0 | BitBufferWrite (bitstream, coefsU [numU - 1][indx], 16) ; |
416 | |
|
417 | 0 | BitBufferWrite (bitstream, (mode << 4) | DENSHIFT_DEFAULT, 8) ; |
418 | 0 | BitBufferWrite (bitstream, (pbFactor << 5) | numV, 8) ; |
419 | 0 | for (indx = 0 ; indx < numV ; indx++) |
420 | 0 | BitBufferWrite (bitstream, coefsV [numV - 1][indx], 16) ; |
421 | | |
422 | | // if shift active, write the interleaved shift buffers |
423 | 0 | if (bytesShifted != 0) |
424 | 0 | { |
425 | 0 | uint32_t bitShift = bytesShifted * 8 ; |
426 | | |
427 | | //Assert (bitShift <= 16) ; |
428 | |
|
429 | 0 | for (indx = 0 ; indx < (numSamples * 2) ; indx += 2) |
430 | 0 | { |
431 | 0 | uint32_t shiftedVal ; |
432 | |
|
433 | 0 | shiftedVal = ((uint32_t) p->mShiftBufferUV [indx + 0] << bitShift) | (uint32_t) p->mShiftBufferUV [indx + 1] ; |
434 | 0 | BitBufferWrite (bitstream, shiftedVal, bitShift * 2) ; |
435 | 0 | } |
436 | 0 | } |
437 | | |
438 | | // run the dynamic predictor and lossless compression for the "left" channel |
439 | | // - note: to avoid allocating more buffers, we're mixing and matching between the available buffers instead |
440 | | // of only using "U" buffers for the U-channel and "V" buffers for the V-channel |
441 | 0 | if (mode == 0) |
442 | 0 | { |
443 | 0 | pc_block (p->mMixBufferU, p->mPredictorU, numSamples, coefsU [numU - 1], numU, chanBits, DENSHIFT_DEFAULT) ; |
444 | 0 | } |
445 | 0 | else |
446 | 0 | { |
447 | 0 | pc_block (p->mMixBufferU, p->mPredictorV, numSamples, coefsU [numU - 1], numU, chanBits, DENSHIFT_DEFAULT) ; |
448 | 0 | pc_block (p->mPredictorV, p->mPredictorU, numSamples, NULL, 31, chanBits, 0) ; |
449 | 0 | } |
450 | |
|
451 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples, numSamples, MAX_RUN_DEFAULT) ; |
452 | 0 | status = dyn_comp (&agParams, p->mPredictorU, bitstream, numSamples, chanBits, &bits1) ; |
453 | 0 | RequireNoErr (status, goto Exit ;) ; |
454 | | |
455 | | // run the dynamic predictor and lossless compression for the "right" channel |
456 | 0 | if (mode == 0) |
457 | 0 | { |
458 | 0 | pc_block (p->mMixBufferV, p->mPredictorV, numSamples, coefsV [numV - 1], numV, chanBits, DENSHIFT_DEFAULT) ; |
459 | 0 | } |
460 | 0 | else |
461 | 0 | { |
462 | 0 | pc_block (p->mMixBufferV, p->mPredictorU, numSamples, coefsV [numV - 1], numV, chanBits, DENSHIFT_DEFAULT) ; |
463 | 0 | pc_block (p->mPredictorU, p->mPredictorV, numSamples, NULL, 31, chanBits, 0) ; |
464 | 0 | } |
465 | |
|
466 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples, numSamples, MAX_RUN_DEFAULT) ; |
467 | 0 | status = dyn_comp (&agParams, p->mPredictorV, bitstream, numSamples, chanBits, &bits2) ; |
468 | 0 | RequireNoErr (status, goto Exit ;) ; |
469 | | |
470 | | /* if we happened to create a compressed packet that was actually bigger than an escape packet would be, |
471 | | chuck it and do an escape packet |
472 | | */ |
473 | 0 | minBits = BitBufferGetPosition (bitstream) - BitBufferGetPosition (&startBits) ; |
474 | 0 | if (minBits >= escapeBits) |
475 | 0 | { |
476 | 0 | *bitstream = startBits ; // reset bitstream state |
477 | 0 | doEscape = true ; |
478 | 0 | printf ("compressed frame too big: %u vs. %u \n", minBits, escapeBits) ; |
479 | 0 | } |
480 | 0 | } |
481 | | |
482 | 0 | if (doEscape == true) |
483 | 0 | { |
484 | | /* escape */ |
485 | 0 | status = EncodeStereoEscape (p, bitstream, inputBuffer, stride, numSamples) ; |
486 | |
|
487 | | #if VERBOSE_DEBUG |
488 | | DebugMsg ("escape!: %u vs %u\n", minBits, escapeBits) ; |
489 | | #endif |
490 | 0 | } |
491 | |
|
492 | 0 | Exit: |
493 | 0 | return status ; |
494 | 0 | } |
495 | | |
496 | | /* |
497 | | EncodeStereoFast () |
498 | | - encode a channel pair without the search loop for maximum possible speed |
499 | | */ |
500 | | static int32_t |
501 | | EncodeStereoFast (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples) |
502 | 0 | { |
503 | 0 | BitBuffer startBits = *bitstream ; // squirrel away current bit position in case we decide to use escape hatch |
504 | 0 | AGParamRec agParams ; |
505 | 0 | uint32_t bits1, bits2 ; |
506 | 0 | int32_t mixBits, mixRes ; |
507 | 0 | uint32_t minBits, minBits1, minBits2 ; |
508 | 0 | uint32_t numU, numV ; |
509 | 0 | uint32_t mode ; |
510 | 0 | uint32_t pbFactor ; |
511 | 0 | uint32_t chanBits ; |
512 | 0 | uint8_t bytesShifted ; |
513 | 0 | SearchCoefs coefsU ; |
514 | 0 | SearchCoefs coefsV ; |
515 | 0 | uint32_t indx ; |
516 | 0 | uint8_t partialFrame ; |
517 | 0 | uint32_t escapeBits ; |
518 | 0 | bool doEscape ; |
519 | 0 | int32_t status ; |
520 | | |
521 | | // make sure we handle this bit-depth before we get going |
522 | 0 | RequireAction ((p->mBitDepth == 16) || (p->mBitDepth == 20) || (p->mBitDepth == 24) || (p->mBitDepth == 32), return kALAC_ParamError ;) ; |
523 | | |
524 | | // reload coefs pointers for this channel pair |
525 | | // - note that, while you might think they should be re-initialized per block, retaining state across blocks |
526 | | // actually results in better overall compression |
527 | | // - strangely, re-using the same coefs for the different passes of the "mixRes" search loop instead of using |
528 | | // different coefs for the different passes of "mixRes" results in even better compression |
529 | 0 | coefsU = (SearchCoefs) p->mCoefsU [channelIndex] ; |
530 | 0 | coefsV = (SearchCoefs) p->mCoefsV [channelIndex] ; |
531 | | |
532 | | // matrix encoding adds an extra bit but 32-bit inputs cannot be matrixed b/c 33 is too many |
533 | | // so enable 16-bit "shift off" and encode in 17-bit mode |
534 | | // - in addition, 24-bit mode really improves with one byte shifted off |
535 | 0 | if (p->mBitDepth == 32) |
536 | 0 | bytesShifted = 2 ; |
537 | 0 | else if (p->mBitDepth >= 24) |
538 | 0 | bytesShifted = 1 ; |
539 | 0 | else |
540 | 0 | bytesShifted = 0 ; |
541 | |
|
542 | 0 | chanBits = p->mBitDepth - (bytesShifted * 8) + 1 ; |
543 | | |
544 | | // flag whether or not this is a partial frame |
545 | 0 | partialFrame = (numSamples == p->mFrameSize) ? 0 : 1 ; |
546 | | |
547 | | // set up default encoding parameters for "fast" mode |
548 | 0 | mixBits = kDefaultMixBits ; |
549 | 0 | mixRes = kDefaultMixRes ; |
550 | 0 | numU = numV = kDefaultNumUV ; |
551 | 0 | mode = 0 ; |
552 | 0 | pbFactor = 4 ; |
553 | |
|
554 | 0 | minBits = minBits1 = minBits2 = 1ul << 31 ; |
555 | | |
556 | | // mix the stereo inputs with default mixBits/mixRes |
557 | 0 | switch (p->mBitDepth) |
558 | 0 | { |
559 | 0 | case 16: |
560 | 0 | mix16 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes) ; |
561 | 0 | break ; |
562 | 0 | case 20: |
563 | 0 | mix20 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, mixBits, mixRes) ; |
564 | 0 | break ; |
565 | 0 | case 24: |
566 | | // also extracts the shifted off bytes into the shift buffers |
567 | 0 | mix24 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, |
568 | 0 | mixBits, mixRes, p->mShiftBufferUV, bytesShifted) ; |
569 | 0 | break ; |
570 | 0 | case 32: |
571 | | // also extracts the shifted off bytes into the shift buffers |
572 | 0 | mix32 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, |
573 | 0 | mixBits, mixRes, p->mShiftBufferUV, bytesShifted) ; |
574 | 0 | break ; |
575 | 0 | } |
576 | | |
577 | | /* speculatively write the bitstream assuming the compressed version will be smaller */ |
578 | | |
579 | | // write bitstream header and coefs |
580 | 0 | BitBufferWrite (bitstream, 0, 12) ; |
581 | 0 | BitBufferWrite (bitstream, (partialFrame << 3) | (bytesShifted << 1), 4) ; |
582 | 0 | if (partialFrame) |
583 | 0 | BitBufferWrite (bitstream, numSamples, 32) ; |
584 | 0 | BitBufferWrite (bitstream, mixBits, 8) ; |
585 | 0 | BitBufferWrite (bitstream, mixRes, 8) ; |
586 | | |
587 | | //Assert ((mode < 16) && (DENSHIFT_DEFAULT < 16)) ; |
588 | | //Assert ((pbFactor < 8) && (numU < 32)) ; |
589 | | //Assert ((pbFactor < 8) && (numV < 32)) ; |
590 | |
|
591 | 0 | BitBufferWrite (bitstream, (mode << 4) | DENSHIFT_DEFAULT, 8) ; |
592 | 0 | BitBufferWrite (bitstream, (pbFactor << 5) | numU, 8) ; |
593 | 0 | for (indx = 0 ; indx < numU ; indx++) |
594 | 0 | BitBufferWrite (bitstream, coefsU [numU - 1][indx], 16) ; |
595 | |
|
596 | 0 | BitBufferWrite (bitstream, (mode << 4) | DENSHIFT_DEFAULT, 8) ; |
597 | 0 | BitBufferWrite (bitstream, (pbFactor << 5) | numV, 8) ; |
598 | 0 | for (indx = 0 ; indx < numV ; indx++) |
599 | 0 | BitBufferWrite (bitstream, coefsV [numV - 1][indx], 16) ; |
600 | | |
601 | | // if shift active, write the interleaved shift buffers |
602 | 0 | if (bytesShifted != 0) |
603 | 0 | { |
604 | 0 | uint32_t bitShift = bytesShifted * 8 ; |
605 | | |
606 | | //Assert (bitShift <= 16) ; |
607 | |
|
608 | 0 | for (indx = 0 ; indx < (numSamples * 2) ; indx += 2) |
609 | 0 | { |
610 | 0 | uint32_t shiftedVal ; |
611 | |
|
612 | 0 | shiftedVal = ((uint32_t) p->mShiftBufferUV [indx + 0] << bitShift) | (uint32_t) p->mShiftBufferUV [indx + 1] ; |
613 | 0 | BitBufferWrite (bitstream, shiftedVal, bitShift * 2) ; |
614 | 0 | } |
615 | 0 | } |
616 | | |
617 | | // run the dynamic predictor and lossless compression for the "left" channel |
618 | | // - note: we always use mode 0 in the "fast" path so we don't need the code for mode != 0 |
619 | 0 | pc_block (p->mMixBufferU, p->mPredictorU, numSamples, coefsU [numU - 1], numU, chanBits, DENSHIFT_DEFAULT) ; |
620 | |
|
621 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples, numSamples, MAX_RUN_DEFAULT) ; |
622 | 0 | status = dyn_comp (&agParams, p->mPredictorU, bitstream, numSamples, chanBits, &bits1) ; |
623 | 0 | RequireNoErr (status, goto Exit ;) ; |
624 | | |
625 | | // run the dynamic predictor and lossless compression for the "right" channel |
626 | 0 | pc_block (p->mMixBufferV, p->mPredictorV, numSamples, coefsV [numV - 1], numV, chanBits, DENSHIFT_DEFAULT) ; |
627 | |
|
628 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples, numSamples, MAX_RUN_DEFAULT) ; |
629 | 0 | status = dyn_comp (&agParams, p->mPredictorV, bitstream, numSamples, chanBits, &bits2) ; |
630 | 0 | RequireNoErr (status, goto Exit ;) ; |
631 | | |
632 | | // do bit requirement calculations |
633 | 0 | minBits1 = bits1 + (numU * sizeof (int16_t) * 8) ; |
634 | 0 | minBits2 = bits2 + (numV * sizeof (int16_t) * 8) ; |
635 | | |
636 | | // test for escape hatch if best calculated compressed size turns out to be more than the input size |
637 | 0 | minBits = minBits1 + minBits2 + (8 /* mixRes/maxRes/etc. */ * 8) + ((partialFrame == true) ? 32 : 0) ; |
638 | 0 | if (bytesShifted != 0) |
639 | 0 | minBits += (numSamples * (bytesShifted * 8) * 2) ; |
640 | |
|
641 | 0 | escapeBits = (numSamples * p->mBitDepth * 2) + ((partialFrame == true) ? 32 : 0) + (2 * 8) ; /* 2 common header bytes */ |
642 | |
|
643 | 0 | doEscape = (minBits >= escapeBits) ? true : false ; |
644 | |
|
645 | 0 | if (doEscape == false) |
646 | 0 | { |
647 | | /* if we happened to create a compressed packet that was actually bigger than an escape packet would be, |
648 | | chuck it and do an escape packet |
649 | | */ |
650 | 0 | minBits = BitBufferGetPosition (bitstream) - BitBufferGetPosition (&startBits) ; |
651 | 0 | if (minBits >= escapeBits) |
652 | 0 | { |
653 | 0 | doEscape = true ; |
654 | 0 | printf ("compressed frame too big: %u vs. %u\n", minBits, escapeBits) ; |
655 | 0 | } |
656 | |
|
657 | 0 | } |
658 | |
|
659 | 0 | if (doEscape == true) |
660 | 0 | { |
661 | | /* escape */ |
662 | | |
663 | | // reset bitstream position since we speculatively wrote the compressed version |
664 | 0 | *bitstream = startBits ; |
665 | | |
666 | | // write escape frame |
667 | 0 | status = EncodeStereoEscape (p, bitstream, inputBuffer, stride, numSamples) ; |
668 | |
|
669 | | #if VERBOSE_DEBUG |
670 | | DebugMsg ("escape!: %u vs %u\n", minBits, (numSamples * p->mBitDepth * 2)) ; |
671 | | #endif |
672 | 0 | } |
673 | |
|
674 | 0 | Exit: |
675 | 0 | return status ; |
676 | 0 | } |
677 | | |
678 | | /* |
679 | | EncodeStereoEscape () |
680 | | - encode stereo escape frame |
681 | | */ |
682 | | static int32_t |
683 | | EncodeStereoEscape (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * inputBuffer, uint32_t stride, uint32_t numSamples) |
684 | 0 | { |
685 | 0 | uint8_t partialFrame ; |
686 | 0 | uint32_t indx ; |
687 | | |
688 | | // flag whether or not this is a partial frame |
689 | 0 | partialFrame = (numSamples == p->mFrameSize) ? 0 : 1 ; |
690 | | |
691 | | // write bitstream header |
692 | 0 | BitBufferWrite (bitstream, 0, 12) ; |
693 | 0 | BitBufferWrite (bitstream, (partialFrame << 3) | 1, 4) ; // LSB = 1 means "frame not compressed" |
694 | 0 | if (partialFrame) |
695 | 0 | BitBufferWrite (bitstream, numSamples, 32) ; |
696 | | |
697 | | // just copy the input data to the output buffer |
698 | 0 | switch (p->mBitDepth) |
699 | 0 | { |
700 | 0 | case 16: |
701 | 0 | for (indx = 0 ; indx < (numSamples * stride) ; indx += stride) |
702 | 0 | { |
703 | 0 | BitBufferWrite (bitstream, inputBuffer [indx + 0] >> 16, 16) ; |
704 | 0 | BitBufferWrite (bitstream, inputBuffer [indx + 1] >> 16, 16) ; |
705 | 0 | } |
706 | 0 | break ; |
707 | 0 | case 20: |
708 | 0 | for (indx = 0 ; indx < (numSamples * stride) ; indx += stride) |
709 | 0 | { |
710 | 0 | BitBufferWrite (bitstream, inputBuffer [indx + 0] >> 12, 16) ; |
711 | 0 | BitBufferWrite (bitstream, inputBuffer [indx + 1] >> 12, 16) ; |
712 | 0 | } |
713 | 0 | break ; |
714 | 0 | case 24: |
715 | | // mix24 () with mixres param = 0 means de-interleave so use it to simplify things |
716 | 0 | mix24 (inputBuffer, stride, p->mMixBufferU, p->mMixBufferV, numSamples, 0, 0, p->mShiftBufferUV, 0) ; |
717 | 0 | for (indx = 0 ; indx < numSamples ; indx++) |
718 | 0 | { |
719 | 0 | BitBufferWrite (bitstream, p->mMixBufferU [indx] >> 8, 24) ; |
720 | 0 | BitBufferWrite (bitstream, p->mMixBufferV [indx] >> 8, 24) ; |
721 | 0 | } |
722 | 0 | break ; |
723 | 0 | case 32: |
724 | 0 | for (indx = 0 ; indx < (numSamples * stride) ; indx += stride) |
725 | 0 | { |
726 | 0 | BitBufferWrite (bitstream, inputBuffer [indx + 0], 32) ; |
727 | 0 | BitBufferWrite (bitstream, inputBuffer [indx + 1], 32) ; |
728 | 0 | } |
729 | 0 | break ; |
730 | 0 | } |
731 | | |
732 | 0 | return ALAC_noErr ; |
733 | 0 | } |
734 | | |
735 | | /* |
736 | | EncodeMono () |
737 | | - encode a mono input buffer |
738 | | */ |
739 | | static int32_t |
740 | | EncodeMono (ALAC_ENCODER *p, struct BitBuffer * bitstream, const int32_t * inputBuffer, uint32_t stride, uint32_t channelIndex, uint32_t numSamples) |
741 | 0 | { |
742 | 0 | BitBuffer startBits = *bitstream ; // squirrel away copy of current state in case we need to go back and do an escape packet |
743 | 0 | AGParamRec agParams ; |
744 | 0 | uint32_t bits1 ; |
745 | 0 | uint32_t numU ; |
746 | 0 | SearchCoefs coefsU ; |
747 | 0 | uint32_t dilate ; |
748 | 0 | uint32_t minBits, bestU ; |
749 | 0 | uint32_t minU, maxU ; |
750 | 0 | uint32_t indx, indx2 ; |
751 | 0 | uint8_t bytesShifted ; |
752 | 0 | uint32_t shift ; |
753 | 0 | uint32_t mask ; |
754 | 0 | uint32_t chanBits ; |
755 | 0 | uint8_t pbFactor ; |
756 | 0 | uint8_t partialFrame ; |
757 | 0 | uint32_t escapeBits ; |
758 | 0 | bool doEscape ; |
759 | 0 | int32_t status = ALAC_noErr ; |
760 | | |
761 | | |
762 | | // make sure we handle this bit-depth before we get going |
763 | 0 | RequireAction ((p->mBitDepth == 16) || (p->mBitDepth == 20) || (p->mBitDepth == 24) || (p->mBitDepth == 32), return kALAC_ParamError ;) ; |
764 | | |
765 | | // reload coefs array from previous frame |
766 | 0 | coefsU = (SearchCoefs) p->mCoefsU [channelIndex] ; |
767 | | |
768 | | // pick bit depth for actual encoding |
769 | | // - we lop off the lower byte (s) for 24-/32-bit encodings |
770 | 0 | if (p->mBitDepth == 32) |
771 | 0 | bytesShifted = 2 ; |
772 | 0 | else if (p->mBitDepth >= 24) |
773 | 0 | bytesShifted = 1 ; |
774 | 0 | else |
775 | 0 | bytesShifted = 0 ; |
776 | |
|
777 | 0 | shift = bytesShifted * 8 ; |
778 | 0 | mask = (1ul << shift) - 1 ; |
779 | 0 | chanBits = p->mBitDepth - (bytesShifted * 8) ; |
780 | | |
781 | | // flag whether or not this is a partial frame |
782 | 0 | partialFrame = (numSamples == p->mFrameSize) ? 0 : 1 ; |
783 | | |
784 | | // convert N-bit data to 32-bit for predictor |
785 | 0 | switch (p->mBitDepth) |
786 | 0 | { |
787 | 0 | case 16: |
788 | | // convert 16-bit data to 32-bit for predictor |
789 | 0 | for (indx = 0, indx2 = 0 ; indx < numSamples ; indx++, indx2 += stride) |
790 | 0 | p->mMixBufferU [indx] = inputBuffer [indx2] >> 16 ; |
791 | 0 | break ; |
792 | | |
793 | 0 | case 20: |
794 | | // convert 20-bit data to 32-bit for predictor |
795 | 0 | for (indx = 0, indx2 = 0 ; indx < numSamples ; indx++, indx2 += stride) |
796 | 0 | p->mMixBufferU [indx] = inputBuffer [indx2] >> 12 ; |
797 | 0 | break ; |
798 | 0 | case 24: |
799 | | // convert 24-bit data to 32-bit for the predictor and extract the shifted off byte (s) |
800 | 0 | for (indx = 0, indx2 = 0 ; indx < numSamples ; indx++, indx2 += stride) |
801 | 0 | { |
802 | 0 | p->mMixBufferU [indx] = inputBuffer [indx2] >> 8 ; |
803 | 0 | p->mShiftBufferUV [indx] = (uint16_t) (p->mMixBufferU [indx] & mask) ; |
804 | 0 | p->mMixBufferU [indx] >>= shift ; |
805 | 0 | } |
806 | |
|
807 | 0 | break ; |
808 | 0 | case 32: |
809 | | // just copy the 32-bit input data for the predictor and extract the shifted off byte (s) |
810 | 0 | for (indx = 0, indx2 = 0 ; indx < numSamples ; indx++, indx2 += stride) |
811 | 0 | { |
812 | 0 | p->mShiftBufferUV [indx] = (uint16_t) (inputBuffer [indx2] & mask) ; |
813 | 0 | p->mMixBufferU [indx] = inputBuffer [indx2] >> shift ; |
814 | 0 | } |
815 | 0 | break ; |
816 | 0 | } |
817 | | |
818 | | // brute-force encode optimization loop (implied "encode depth" of 0 if comparing to cmd line tool) |
819 | | // - run over variations of the encoding params to find the best choice |
820 | 0 | minU = 4 ; |
821 | 0 | maxU = 8 ; |
822 | 0 | minBits = 1ul << 31 ; |
823 | 0 | pbFactor = 4 ; |
824 | |
|
825 | 0 | bestU = minU ; |
826 | |
|
827 | 0 | for (numU = minU ; numU <= maxU ; numU += 4) |
828 | 0 | { |
829 | 0 | BitBuffer workBits ; |
830 | 0 | uint32_t numBits ; |
831 | |
|
832 | 0 | BitBufferInit (&workBits, p->mWorkBuffer, p->mMaxOutputBytes) ; |
833 | |
|
834 | 0 | dilate = 32 ; |
835 | 0 | for (uint32_t converge = 0 ; converge < 7 ; converge++) |
836 | 0 | pc_block (p->mMixBufferU, p->mPredictorU, numSamples / dilate, coefsU [numU - 1], numU, chanBits, DENSHIFT_DEFAULT) ; |
837 | |
|
838 | 0 | dilate = 8 ; |
839 | 0 | pc_block (p->mMixBufferU, p->mPredictorU, numSamples / dilate, coefsU [numU - 1], numU, chanBits, DENSHIFT_DEFAULT) ; |
840 | |
|
841 | 0 | set_ag_params (&agParams, MB0, (pbFactor * PB0) / 4, KB0, numSamples / dilate, numSamples / dilate, MAX_RUN_DEFAULT) ; |
842 | 0 | status = dyn_comp (&agParams, p->mPredictorU, &workBits, numSamples / dilate, chanBits, &bits1) ; |
843 | 0 | RequireNoErr (status, goto Exit ;) ; |
844 | |
|
845 | 0 | numBits = (dilate * bits1) + (16 * numU) ; |
846 | 0 | if (numBits < minBits) |
847 | 0 | { |
848 | 0 | bestU = numU ; |
849 | 0 | minBits = numBits ; |
850 | 0 | } |
851 | 0 | } |
852 | | |
853 | | // test for escape hatch if best calculated compressed size turns out to be more than the input size |
854 | | // - first, add bits for the header bytes mixRes/maxRes/shiftU/filterU |
855 | 0 | minBits += (4 /* mixRes/maxRes/etc. */ * 8) + ((partialFrame == true) ? 32 : 0) ; |
856 | 0 | if (bytesShifted != 0) |
857 | 0 | minBits += (numSamples * (bytesShifted * 8)) ; |
858 | |
|
859 | 0 | escapeBits = (numSamples * p->mBitDepth) + ((partialFrame == true) ? 32 : 0) + (2 * 8) ; /* 2 common header bytes */ |
860 | |
|
861 | 0 | doEscape = (minBits >= escapeBits) ? true : false ; |
862 | |
|
863 | 0 | if (doEscape == false) |
864 | 0 | { |
865 | | // write bitstream header |
866 | 0 | BitBufferWrite (bitstream, 0, 12) ; |
867 | 0 | BitBufferWrite (bitstream, (partialFrame << 3) | (bytesShifted << 1), 4) ; |
868 | 0 | if (partialFrame) |
869 | 0 | BitBufferWrite (bitstream, numSamples, 32) ; |
870 | 0 | BitBufferWrite (bitstream, 0, 16) ; // mixBits = mixRes = 0 |
871 | | |
872 | | // write the params and predictor coefs |
873 | 0 | numU = bestU ; |
874 | 0 | BitBufferWrite (bitstream, (0 << 4) | DENSHIFT_DEFAULT, 8) ; // modeU = 0 |
875 | 0 | BitBufferWrite (bitstream, (pbFactor << 5) | numU, 8) ; |
876 | 0 | for (indx = 0 ; indx < numU ; indx++) |
877 | 0 | BitBufferWrite (bitstream, coefsU [numU-1][indx], 16) ; |
878 | | |
879 | | // if shift active, write the interleaved shift buffers |
880 | 0 | if (bytesShifted != 0) |
881 | 0 | { |
882 | 0 | for (indx = 0 ; indx < numSamples ; indx++) |
883 | 0 | BitBufferWrite (bitstream, p->mShiftBufferUV [indx], shift) ; |
884 | 0 | } |
885 | | |
886 | | // run the dynamic predictor with the best result |
887 | 0 | pc_block (p->mMixBufferU, p->mPredictorU, numSamples, coefsU [numU-1], numU, chanBits, DENSHIFT_DEFAULT) ; |
888 | | |
889 | | // do lossless compression |
890 | 0 | set_standard_ag_params (&agParams, numSamples, numSamples) ; |
891 | 0 | status = dyn_comp (&agParams, p->mPredictorU, bitstream, numSamples, chanBits, &bits1) ; |
892 | | //AssertNoErr (status) ; |
893 | | |
894 | | |
895 | | /* if we happened to create a compressed packet that was actually bigger than an escape packet would be, |
896 | | chuck it and do an escape packet |
897 | | */ |
898 | 0 | minBits = BitBufferGetPosition (bitstream) - BitBufferGetPosition (&startBits) ; |
899 | 0 | if (minBits >= escapeBits) |
900 | 0 | { |
901 | 0 | *bitstream = startBits ; // reset bitstream state |
902 | 0 | doEscape = true ; |
903 | 0 | printf ("compressed frame too big: %u vs. %u\n", minBits, escapeBits) ; |
904 | 0 | } |
905 | 0 | } |
906 | |
|
907 | 0 | if (doEscape == true) |
908 | 0 | { |
909 | | // write bitstream header and coefs |
910 | 0 | BitBufferWrite (bitstream, 0, 12) ; |
911 | 0 | BitBufferWrite (bitstream, (partialFrame << 3) | 1, 4) ; // LSB = 1 means "frame not compressed" |
912 | 0 | if (partialFrame) |
913 | 0 | BitBufferWrite (bitstream, numSamples, 32) ; |
914 | | |
915 | | // just copy the input data to the output buffer |
916 | 0 | switch (p->mBitDepth) |
917 | 0 | { |
918 | 0 | case 16: |
919 | 0 | for (indx = 0 ; indx < (numSamples * stride) ; indx += stride) |
920 | 0 | BitBufferWrite (bitstream, inputBuffer [indx] >> 16, 16) ; |
921 | 0 | break ; |
922 | 0 | case 20: |
923 | | // convert 20-bit data to 32-bit for simplicity |
924 | 0 | for (indx = 0 ; indx < (numSamples * stride) ; indx += stride) |
925 | 0 | BitBufferWrite (bitstream, inputBuffer [indx] >> 12, 20) ; |
926 | 0 | break ; |
927 | 0 | case 24: |
928 | | // convert 24-bit data to 32-bit for simplicity |
929 | 0 | for (indx = 0, indx2 = 0 ; indx < numSamples ; indx++, indx2 += stride) |
930 | 0 | { |
931 | 0 | p->mMixBufferU [indx] = inputBuffer [indx2] >> 8 ; |
932 | 0 | BitBufferWrite (bitstream, p->mMixBufferU [indx], 24) ; |
933 | 0 | } |
934 | 0 | break ; |
935 | 0 | case 32: |
936 | 0 | for (indx = 0 ; indx < (numSamples * stride) ; indx += stride) |
937 | 0 | BitBufferWrite (bitstream, inputBuffer [indx], 32) ; |
938 | 0 | break ; |
939 | 0 | } |
940 | | #if VERBOSE_DEBUG |
941 | | DebugMsg ("escape!: %u vs %u\n", minBits, (numSamples * p->mBitDepth)) ; |
942 | | #endif |
943 | 0 | } |
944 | | |
945 | 0 | Exit: |
946 | 0 | return status ; |
947 | 0 | } |
948 | | |
949 | | #if PRAGMA_MARK |
950 | | #pragma mark - |
951 | | #endif |
952 | | |
953 | | /* |
954 | | Encode () |
955 | | - encode the next block of samples |
956 | | */ |
957 | | int32_t |
958 | | alac_encode (ALAC_ENCODER *p, uint32_t numSamples, |
959 | | const int32_t * theReadBuffer, unsigned char * theWriteBuffer, uint32_t * ioNumBytes) |
960 | 0 | { |
961 | 0 | uint32_t outputSize ; |
962 | 0 | BitBuffer bitstream ; |
963 | 0 | int32_t status ; |
964 | 0 | uint32_t numChannels = p->mNumChannels ; |
965 | | |
966 | | // make sure we handle this bit-depth before we get going |
967 | 0 | RequireAction ((p->mBitDepth == 16) || (p->mBitDepth == 20) || (p->mBitDepth == 24) || (p->mBitDepth == 32), return kALAC_ParamError ;) ; |
968 | | |
969 | | // create a bit buffer structure pointing to our output buffer |
970 | 0 | BitBufferInit (&bitstream, theWriteBuffer, p->mMaxOutputBytes) ; |
971 | |
|
972 | 0 | if (numChannels == 2) |
973 | 0 | { |
974 | | // add 3-bit frame start tag ID_CPE = channel pair & 4-bit element instance tag = 0 |
975 | 0 | BitBufferWrite (&bitstream, ID_CPE, 3) ; |
976 | 0 | BitBufferWrite (&bitstream, 0, 4) ; |
977 | | |
978 | | // encode stereo input buffer |
979 | 0 | if (p->mFastMode == false) |
980 | 0 | status = EncodeStereo (p, &bitstream, theReadBuffer, 2, 0, numSamples) ; |
981 | 0 | else |
982 | 0 | status = EncodeStereoFast (p, &bitstream, theReadBuffer, 2, 0, numSamples) ; |
983 | 0 | RequireNoErr (status, goto Exit ;) ; |
984 | 0 | } |
985 | 0 | else if (numChannels == 1) |
986 | 0 | { |
987 | | // add 3-bit frame start tag ID_SCE = mono channel & 4-bit element instance tag = 0 |
988 | 0 | BitBufferWrite (&bitstream, ID_SCE, 3) ; |
989 | 0 | BitBufferWrite (&bitstream, 0, 4) ; |
990 | | |
991 | | // encode mono input buffer |
992 | 0 | status = EncodeMono (p, &bitstream, theReadBuffer, 1, 0, numSamples) ; |
993 | 0 | RequireNoErr (status, goto Exit ;) ; |
994 | 0 | } |
995 | 0 | else |
996 | 0 | { |
997 | 0 | const int32_t * inputBuffer ; |
998 | 0 | uint32_t tag ; |
999 | 0 | uint32_t channelIndex ; |
1000 | 0 | uint8_t stereoElementTag ; |
1001 | 0 | uint8_t monoElementTag ; |
1002 | 0 | uint8_t lfeElementTag ; |
1003 | |
|
1004 | 0 | inputBuffer = theReadBuffer ; |
1005 | |
|
1006 | 0 | stereoElementTag = 0 ; |
1007 | 0 | monoElementTag = 0 ; |
1008 | 0 | lfeElementTag = 0 ; |
1009 | |
|
1010 | 0 | for (channelIndex = 0 ; channelIndex < numChannels ;) |
1011 | 0 | { |
1012 | 0 | tag = (sChannelMaps [numChannels - 1] & (0x7ul << (channelIndex * 3))) >> (channelIndex * 3) ; |
1013 | |
|
1014 | 0 | BitBufferWrite (&bitstream, tag, 3) ; |
1015 | 0 | switch (tag) |
1016 | 0 | { |
1017 | 0 | case ID_SCE: |
1018 | | // mono |
1019 | 0 | BitBufferWrite (&bitstream, monoElementTag, 4) ; |
1020 | |
|
1021 | 0 | status = EncodeMono (p, &bitstream, inputBuffer, numChannels, channelIndex, numSamples) ; |
1022 | |
|
1023 | 0 | inputBuffer += 1 ; |
1024 | 0 | channelIndex++ ; |
1025 | 0 | monoElementTag++ ; |
1026 | 0 | break ; |
1027 | | |
1028 | 0 | case ID_CPE: |
1029 | | // stereo |
1030 | 0 | BitBufferWrite (&bitstream, stereoElementTag, 4) ; |
1031 | |
|
1032 | 0 | status = EncodeStereo (p, &bitstream, inputBuffer, numChannels, channelIndex, numSamples) ; |
1033 | |
|
1034 | 0 | inputBuffer += 2 ; |
1035 | 0 | channelIndex += 2 ; |
1036 | 0 | stereoElementTag++ ; |
1037 | 0 | break ; |
1038 | | |
1039 | 0 | case ID_LFE: |
1040 | | // LFE channel (subwoofer) |
1041 | 0 | BitBufferWrite (&bitstream, lfeElementTag, 4) ; |
1042 | |
|
1043 | 0 | status = EncodeMono (p, &bitstream, inputBuffer, numChannels, channelIndex, numSamples) ; |
1044 | |
|
1045 | 0 | inputBuffer += 1 ; |
1046 | 0 | channelIndex++ ; |
1047 | 0 | lfeElementTag++ ; |
1048 | 0 | break ; |
1049 | | |
1050 | 0 | default: |
1051 | 0 | printf ("That ain't right! (%u)\n", tag) ; |
1052 | 0 | status = kALAC_ParamError ; |
1053 | 0 | goto Exit ; |
1054 | 0 | } |
1055 | | |
1056 | 0 | RequireNoErr (status, goto Exit ;) ; |
1057 | 0 | } |
1058 | 0 | } |
1059 | | |
1060 | | #if VERBOSE_DEBUG |
1061 | | { |
1062 | | // if there is room left in the output buffer, add some random fill data to test decoder |
1063 | | int32_t bitsLeft ; |
1064 | | int32_t bytesLeft ; |
1065 | | |
1066 | | bitsLeft = BitBufferGetPosition (&bitstream) - 3 ; // - 3 for ID_END tag |
1067 | | bytesLeft = bitstream.byteSize - ((bitsLeft + 7) / 8) ; |
1068 | | |
1069 | | if ((bytesLeft > 20) && ((bytesLeft & 0x4u) != 0)) |
1070 | | AddFiller (&bitstream, bytesLeft) ; |
1071 | | } |
1072 | | #endif |
1073 | | |
1074 | | // add 3-bit frame end tag: ID_END |
1075 | 0 | BitBufferWrite (&bitstream, ID_END, 3) ; |
1076 | | |
1077 | | // byte-align the output data |
1078 | 0 | BitBufferByteAlign (&bitstream, true) ; |
1079 | |
|
1080 | 0 | outputSize = BitBufferGetPosition (&bitstream) / 8 ; |
1081 | | //Assert (outputSize <= mMaxOutputBytes) ; |
1082 | | |
1083 | | |
1084 | | // all good, let iTunes know what happened and remember the total number of input sample frames |
1085 | 0 | *ioNumBytes = outputSize ; |
1086 | | //mEncodedFrames += encodeMsg->numInputSamples ; |
1087 | | |
1088 | | // gather encoding stats |
1089 | 0 | p->mTotalBytesGenerated += outputSize ; |
1090 | 0 | p->mMaxFrameBytes = MAX (p->mMaxFrameBytes, outputSize) ; |
1091 | |
|
1092 | 0 | status = ALAC_noErr ; |
1093 | |
|
1094 | 0 | Exit: |
1095 | 0 | return status ; |
1096 | 0 | } |
1097 | | |
1098 | | |
1099 | | #if PRAGMA_MARK |
1100 | | #pragma mark - |
1101 | | #endif |
1102 | | |
1103 | | /* |
1104 | | GetConfig () |
1105 | | */ |
1106 | | void |
1107 | | GetConfig (ALAC_ENCODER *p, ALACSpecificConfig * config) |
1108 | 0 | { |
1109 | 0 | config->frameLength = Swap32NtoB (p->mFrameSize) ; |
1110 | 0 | config->compatibleVersion = (uint8_t) kALACCompatibleVersion ; |
1111 | 0 | config->bitDepth = (uint8_t) p->mBitDepth ; |
1112 | 0 | config->pb = (uint8_t) PB0 ; |
1113 | 0 | config->kb = (uint8_t) KB0 ; |
1114 | 0 | config->mb = (uint8_t) MB0 ; |
1115 | 0 | config->numChannels = (uint8_t) p->mNumChannels ; |
1116 | 0 | config->maxRun = Swap16NtoB ((uint16_t) MAX_RUN_DEFAULT) ; |
1117 | 0 | config->maxFrameBytes = Swap32NtoB (p->mMaxFrameBytes) ; |
1118 | 0 | config->avgBitRate = Swap32NtoB (p->mAvgBitRate) ; |
1119 | 0 | config->sampleRate = Swap32NtoB (p->mOutputSampleRate) ; |
1120 | 0 | } |
1121 | | |
1122 | | uint32_t |
1123 | | alac_get_magic_cookie_size (uint32_t inNumChannels) |
1124 | 0 | { |
1125 | 0 | if (inNumChannels > 2) |
1126 | 0 | { |
1127 | 0 | return sizeof (ALACSpecificConfig) + kChannelAtomSize + sizeof (ALACAudioChannelLayout) ; |
1128 | 0 | } |
1129 | 0 | else |
1130 | 0 | { |
1131 | 0 | return sizeof (ALACSpecificConfig) ; |
1132 | 0 | } |
1133 | 0 | } |
1134 | | |
1135 | | void |
1136 | | alac_get_magic_cookie (ALAC_ENCODER *p, void * outCookie, uint32_t * ioSize) |
1137 | 0 | { |
1138 | 0 | ALACSpecificConfig theConfig = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ; |
1139 | 0 | ALACAudioChannelLayout theChannelLayout = { 0, 0, 0 } ; |
1140 | 0 | uint8_t theChannelAtom [kChannelAtomSize] = { 0, 0, 0, 0, 'c', 'h', 'a', 'n', 0, 0, 0, 0 } ; |
1141 | 0 | uint32_t theCookieSize = sizeof (ALACSpecificConfig) ; |
1142 | 0 | uint8_t * theCookiePointer = (uint8_t *) outCookie ; |
1143 | |
|
1144 | 0 | GetConfig (p, &theConfig) ; |
1145 | 0 | if (theConfig.numChannels > 2) |
1146 | 0 | { |
1147 | 0 | theChannelLayout.mChannelLayoutTag = Swap32NtoB (ALACChannelLayoutTags [theConfig.numChannels - 1]) ; |
1148 | 0 | theCookieSize += (sizeof (ALACAudioChannelLayout) + kChannelAtomSize) ; |
1149 | 0 | } |
1150 | 0 | if (*ioSize >= theCookieSize) |
1151 | 0 | { |
1152 | 0 | memcpy (theCookiePointer, &theConfig, sizeof (ALACSpecificConfig)) ; |
1153 | 0 | theChannelAtom [3] = (sizeof (ALACAudioChannelLayout) + kChannelAtomSize) ; |
1154 | 0 | if (theConfig.numChannels > 2) |
1155 | 0 | { |
1156 | 0 | theCookiePointer += sizeof (ALACSpecificConfig) ; |
1157 | 0 | memcpy (theCookiePointer, theChannelAtom, kChannelAtomSize) ; |
1158 | 0 | theCookiePointer += kChannelAtomSize ; |
1159 | 0 | memcpy (theCookiePointer, &theChannelLayout, sizeof (ALACAudioChannelLayout)) ; |
1160 | 0 | } |
1161 | 0 | *ioSize = theCookieSize ; |
1162 | 0 | } |
1163 | 0 | else |
1164 | 0 | { |
1165 | 0 | *ioSize = 0 ; // no incomplete cookies |
1166 | 0 | } |
1167 | 0 | } |
1168 | | |
1169 | | /* |
1170 | | alac_encoder_init () |
1171 | | - initialize the encoder component with the current config |
1172 | | */ |
1173 | | int32_t |
1174 | | alac_encoder_init (ALAC_ENCODER *p, uint32_t samplerate, uint32_t channels, uint32_t format_flags, uint32_t frameSize) |
1175 | 0 | { |
1176 | 0 | int32_t status ; |
1177 | |
|
1178 | 0 | p->mFrameSize = (frameSize > 0 && frameSize <= ALAC_FRAME_LENGTH) ? frameSize : ALAC_FRAME_LENGTH ; |
1179 | |
|
1180 | 0 | p->mOutputSampleRate = samplerate ; |
1181 | 0 | p->mNumChannels = channels ; |
1182 | 0 | switch (format_flags) |
1183 | 0 | { |
1184 | 0 | case 1: |
1185 | 0 | p->mBitDepth = 16 ; |
1186 | 0 | break ; |
1187 | 0 | case 2: |
1188 | 0 | p->mBitDepth = 20 ; |
1189 | 0 | break ; |
1190 | 0 | case 3: |
1191 | 0 | p->mBitDepth = 24 ; |
1192 | 0 | break ; |
1193 | 0 | case 4: |
1194 | 0 | p->mBitDepth = 32 ; |
1195 | 0 | break ; |
1196 | 0 | default: |
1197 | 0 | break ; |
1198 | 0 | } |
1199 | | |
1200 | | // set up default encoding parameters and state |
1201 | | // - note: mFrameSize is set in the constructor or via alac_set_frame_size () which must be called before this routine |
1202 | 0 | for (uint32_t indx = 0 ; indx < kALACMaxChannels ; indx++) |
1203 | 0 | p->mLastMixRes [indx] = kDefaultMixRes ; |
1204 | | |
1205 | | // the maximum output frame size can be no bigger than (samplesPerBlock * numChannels * ((10 + sampleSize)/8) + 1) |
1206 | | // but note that this can be bigger than the input size! |
1207 | | // - since we don't yet know what our input format will be, use our max allowed sample size in the calculation |
1208 | 0 | p->mMaxOutputBytes = p->mFrameSize * p->mNumChannels * ((10 + kMaxSampleSize) / 8) + 1 ; |
1209 | |
|
1210 | 0 | status = ALAC_noErr ; |
1211 | | |
1212 | | // initialize coefs arrays once b/c retaining state across blocks actually improves the encode ratio |
1213 | 0 | for (int32_t channel = 0 ; channel < (int32_t) p->mNumChannels ; channel++) |
1214 | 0 | { |
1215 | 0 | for (int32_t search = 0 ; search < kALACMaxSearches ; search++) |
1216 | 0 | { |
1217 | 0 | init_coefs (p->mCoefsU [channel][search], DENSHIFT_DEFAULT, kALACMaxCoefs) ; |
1218 | 0 | init_coefs (p->mCoefsV [channel][search], DENSHIFT_DEFAULT, kALACMaxCoefs) ; |
1219 | 0 | } |
1220 | 0 | } |
1221 | |
|
1222 | 0 | return status ; |
1223 | 0 | } |
1224 | | |
1225 | | /* |
1226 | | alac_get_source_format () |
1227 | | - given the input format, return one of our supported formats |
1228 | | */ |
1229 | | void |
1230 | | alac_get_source_format (ALAC_ENCODER *p, const AudioFormatDescription * source, AudioFormatDescription * output) |
1231 | 0 | { |
1232 | 0 | (void) output ; |
1233 | | // default is 16-bit native endian |
1234 | | // - note: for float input we assume that's coming from one of our decoders (mp3, aac) so it only makes sense |
1235 | | // to encode to 16-bit since the source was lossy in the first place |
1236 | | // - note: if not a supported bit depth, find the closest supported bit depth to the input one |
1237 | 0 | if ((source->mFormatID != kALACFormatLinearPCM) || ((source->mFormatFlags & kALACFormatFlagIsFloat) != 0) || (source->mBitsPerChannel <= 16)) |
1238 | 0 | p->mBitDepth = 16 ; |
1239 | 0 | else if (source->mBitsPerChannel <= 20) |
1240 | 0 | p->mBitDepth = 20 ; |
1241 | 0 | else if (source->mBitsPerChannel <= 24) |
1242 | 0 | p->mBitDepth = 24 ; |
1243 | 0 | else |
1244 | 0 | p->mBitDepth = 32 ; |
1245 | | |
1246 | | // we support 16/20/24/32-bit integer data at any sample rate and our target number of channels |
1247 | | // and sample rate were specified when we were configured |
1248 | | /* |
1249 | | MakeUncompressedAudioFormat (mNumChannels, (float) mOutputSampleRate, mBitDepth, kAudioFormatFlagsNativeIntegerPacked, output) ; |
1250 | | */ |
1251 | 0 | } |
1252 | | |
1253 | | |
1254 | | |
1255 | | #if VERBOSE_DEBUG |
1256 | | |
1257 | | #if PRAGMA_MARK |
1258 | | #pragma mark - |
1259 | | #endif |
1260 | | |
1261 | | /* |
1262 | | AddFiller () |
1263 | | - add fill and data stream elements to the bitstream to test the decoder |
1264 | | */ |
1265 | | static void AddFiller (BitBuffer * bits, int32_t numBytes) |
1266 | | { |
1267 | | uint8_t tag ; |
1268 | | int32_t indx ; |
1269 | | |
1270 | | // out of lameness, subtract 6 bytes to deal with header + alignment as required for fill/data elements |
1271 | | numBytes -= 6 ; |
1272 | | if (numBytes <= 0) |
1273 | | return ; |
1274 | | |
1275 | | // randomly pick Fill or Data Stream Element based on numBytes requested |
1276 | | tag = (numBytes & 0x8) ? ID_FIL : ID_DSE ; |
1277 | | |
1278 | | BitBufferWrite (bits, tag, 3) ; |
1279 | | if (tag == ID_FIL) |
1280 | | { |
1281 | | // can't write more than 269 bytes in a fill element |
1282 | | numBytes = (numBytes > 269) ? 269 : numBytes ; |
1283 | | |
1284 | | // fill element = 4-bit size unless >= 15 then 4-bit size + 8-bit extension size |
1285 | | if (numBytes >= 15) |
1286 | | { |
1287 | | uint16_t extensionSize ; |
1288 | | |
1289 | | BitBufferWrite (bits, 15, 4) ; |
1290 | | |
1291 | | // 8-bit extension count field is "extra + 1" which is weird but I didn't define the syntax |
1292 | | // - otherwise, there's no way to represent 15 |
1293 | | // - for example, to really mean 15 bytes you must encode extensionSize = 1 |
1294 | | // - why it's not like data stream elements I have no idea |
1295 | | extensionSize = (numBytes - 15) + 1 ; |
1296 | | //Assert (extensionSize <= 255) ; |
1297 | | BitBufferWrite (bits, extensionSize, 8) ; |
1298 | | } |
1299 | | else |
1300 | | BitBufferWrite (bits, numBytes, 4) ; |
1301 | | |
1302 | | BitBufferWrite (bits, 0x10, 8) ; // extension_type = FILL_DATA = b0001 or'ed with fill_nibble = b0000 |
1303 | | for (indx = 0 ; indx < (numBytes - 1) ; indx++) |
1304 | | BitBufferWrite (bits, 0xa5, 8) ; // fill_byte = b10100101 = 0xa5 |
1305 | | } |
1306 | | else |
1307 | | { |
1308 | | // can't write more than 510 bytes in a data stream element |
1309 | | numBytes = (numBytes > 510) ? 510 : numBytes ; |
1310 | | |
1311 | | BitBufferWrite (bits, 0, 4) ; // element instance tag |
1312 | | BitBufferWrite (bits, 1, 1) ; // byte-align flag = true |
1313 | | |
1314 | | // data stream element = 8-bit size unless >= 255 then 8-bit size + 8-bit size |
1315 | | if (numBytes >= 255) |
1316 | | { |
1317 | | BitBufferWrite (bits, 255, 8) ; |
1318 | | BitBufferWrite (bits, numBytes - 255, 8) ; |
1319 | | } |
1320 | | else |
1321 | | BitBufferWrite (bits, numBytes, 8) ; |
1322 | | |
1323 | | BitBufferByteAlign (bits, true) ; // byte-align with zeros |
1324 | | |
1325 | | for (indx = 0 ; indx < numBytes ; indx++) |
1326 | | BitBufferWrite (bits, 0x5a, 8) ; |
1327 | | } |
1328 | | } |
1329 | | |
1330 | | #endif /* VERBOSE_DEBUG */ |