/* * Copyright (c) 2011 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ /* File: ALACDecoder.cpp */ #include #include #include "ALACDecoder.h" #include "dplib.h" #include "aglib.h" #include "matrixlib.h" #include "ALACBitUtilities.h" #include "EndianPortable.h" // constants/data const uint32_t kMaxBitDepth = 32; // max allowed bit depth is 32 // prototypes static void Zero16( int16_t * buffer, uint32_t numItems, uint32_t stride ); static void Zero24( uint8_t * buffer, uint32_t numItems, uint32_t stride ); static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride ); /* Constructor */ ALACDecoder::ALACDecoder() : mMixBufferU( nil ), mMixBufferV( nil ), mPredictor( nil ), mShiftBuffer( nil ) { memset( &mConfig, 0, sizeof(mConfig) ); } /* Destructor */ ALACDecoder::~ALACDecoder() { // delete the matrix mixing buffers if ( mMixBufferU ) { free(mMixBufferU); mMixBufferU = NULL; } if ( mMixBufferV ) { free(mMixBufferV); mMixBufferV = NULL; } // delete the dynamic predictor's "corrector" buffer // - note: mShiftBuffer shares memory with this buffer if ( mPredictor ) { free(mPredictor); mPredictor = NULL; } } /* Init() - initialize the decoder with the given configuration */ int32_t ALACDecoder::Init( void * inMagicCookie, uint32_t inMagicCookieSize ) { int32_t status = ALAC_noErr; ALACSpecificConfig theConfig; uint8_t * theActualCookie = (uint8_t *)inMagicCookie; uint32_t theCookieBytesRemaining = inMagicCookieSize; // For historical reasons the decoder needs to be resilient to magic cookies vended by older encoders. // As specified in the ALACMagicCookieDescription.txt document, there may be additional data encapsulating // the ALACSpecificConfig. This would consist of format ('frma') and 'alac' atoms which precede the // ALACSpecificConfig. // See ALACMagicCookieDescription.txt for additional documentation concerning the 'magic cookie' // skip format ('frma') atom if present if (theActualCookie[4] == 'f' && theActualCookie[5] == 'r' && theActualCookie[6] == 'm' && theActualCookie[7] == 'a') { theActualCookie += 12; theCookieBytesRemaining -= 12; } // skip 'alac' atom header if present if (theActualCookie[4] == 'a' && theActualCookie[5] == 'l' && theActualCookie[6] == 'a' && theActualCookie[7] == 'c') { theActualCookie += 12; theCookieBytesRemaining -= 12; } // read the ALACSpecificConfig if (theCookieBytesRemaining >= sizeof(ALACSpecificConfig)) { memcpy(&theConfig, theActualCookie, sizeof(ALACSpecificConfig)); theConfig.frameLength = Swap32BtoN(theConfig.frameLength); theConfig.maxRun = Swap16BtoN(theConfig.maxRun); theConfig.maxFrameBytes = Swap32BtoN(theConfig.maxFrameBytes); theConfig.avgBitRate = Swap32BtoN(theConfig.avgBitRate); theConfig.sampleRate = Swap32BtoN(theConfig.sampleRate); mConfig = theConfig; RequireAction( mConfig.compatibleVersion <= kALACVersion, return kALAC_ParamError; ); // allocate mix buffers mMixBufferU = (int32_t *) calloc( mConfig.frameLength * sizeof(int32_t), 1 ); mMixBufferV = (int32_t *) calloc( mConfig.frameLength * sizeof(int32_t), 1 ); // allocate dynamic predictor buffer mPredictor = (int32_t *) calloc( mConfig.frameLength * sizeof(int32_t), 1 ); // "shift off" buffer shares memory with predictor buffer mShiftBuffer = (uint16_t *) mPredictor; RequireAction( (mMixBufferU != nil) && (mMixBufferV != nil) && (mPredictor != nil), status = kALAC_MemFullError; goto Exit; ); } else { status = kALAC_ParamError; } // skip to Channel Layout Info // theActualCookie += sizeof(ALACSpecificConfig); // Currently, the Channel Layout Info portion of the magic cookie (as defined in the // ALACMagicCookieDescription.txt document) is unused by the decoder. Exit: return status; } /* Decode() - the decoded samples are interleaved into the output buffer in the order they arrive in the bitstream */ int32_t ALACDecoder::Decode( BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples ) { BitBuffer shiftBits; uint32_t bits1, bits2; uint8_t tag; uint8_t elementInstanceTag; AGParamRec agParams; uint32_t channelIndex; int16_t coefsU[32]; // max possible size is 32 although NUMCOEPAIRS is the current limit int16_t coefsV[32]; uint8_t numU, numV; uint8_t mixBits; int8_t mixRes; uint16_t unusedHeader; uint8_t escapeFlag; uint32_t chanBits; uint8_t bytesShifted; uint32_t shift; uint8_t modeU, modeV; uint32_t denShiftU, denShiftV; uint16_t pbFactorU, pbFactorV; uint16_t pb; int16_t * samples; int16_t * out16; uint8_t * out20; uint8_t * out24; int32_t * out32; uint8_t headerByte; uint8_t partialFrame; uint32_t extraBits; int32_t val; uint32_t i, j; int32_t status; RequireAction( (bits != nil) && (sampleBuffer != nil) && (outNumSamples != nil), return kALAC_ParamError; ); RequireAction( numChannels > 0, return kALAC_ParamError; ); mActiveElements = 0; channelIndex = 0; samples = (int16_t *) sampleBuffer; status = ALAC_noErr; *outNumSamples = numSamples; while ( status == ALAC_noErr ) { // bail if we ran off the end of the buffer RequireAction( bits->cur < bits->end, status = kALAC_ParamError; goto Exit; ); // copy global decode params for this element pb = mConfig.pb; // read element tag tag = BitBufferReadSmall( bits, 3 ); switch ( tag ) { case ID_SCE: case ID_LFE: { // mono/LFE channel elementInstanceTag = BitBufferReadSmall( bits, 4 ); mActiveElements |= (1u << elementInstanceTag); // read the 12 unused header bits unusedHeader = (uint16_t) BitBufferRead( bits, 12 ); RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; ); // read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag headerByte = (uint8_t) BitBufferRead( bits, 4 ); partialFrame = headerByte >> 3; bytesShifted = (headerByte >> 1) & 0x3u; RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; ); shift = bytesShifted * 8; escapeFlag = headerByte & 0x1; chanBits = mConfig.bitDepth - (bytesShifted * 8); // check for partial frame to override requested numSamples if ( partialFrame != 0 ) { numSamples = BitBufferRead( bits, 16 ) << 16; numSamples |= BitBufferRead( bits, 16 ); } if ( escapeFlag == 0 ) { // compressed frame, read rest of parameters mixBits = (uint8_t) BitBufferRead( bits, 8 ); mixRes = (int8_t) BitBufferRead( bits, 8 ); //Assert( (mixBits == 0) && (mixRes == 0) ); // no mixing for mono headerByte = (uint8_t) BitBufferRead( bits, 8 ); modeU = headerByte >> 4; denShiftU = headerByte & 0xfu; headerByte = (uint8_t) BitBufferRead( bits, 8 ); pbFactorU = headerByte >> 5; numU = headerByte & 0x1fu; for ( i = 0; i < numU; i++ ) coefsU[i] = (int16_t) BitBufferRead( bits, 16 ); // if shift active, skip the the shift buffer but remember where it starts if ( bytesShifted != 0 ) { shiftBits = *bits; BitBufferAdvance( bits, (bytesShifted * 8) * numSamples ); } // decompress set_ag_params( &agParams, mConfig.mb, (pb * pbFactorU) / 4, mConfig.kb, numSamples, numSamples, mConfig.maxRun ); status = dyn_decomp( &agParams, bits, mPredictor, numSamples, chanBits, &bits1 ); RequireNoErr( status, goto Exit; ); if ( modeU == 0 ) { unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } else { // the special "numActive == 31" mode can be done in-place unpc_block( mPredictor, mPredictor, numSamples, nil, 31, chanBits, 0 ); unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } } else { //Assert( bytesShifted == 0 ); // uncompressed frame, copy data into the mix buffer to use common output code shift = 32 - chanBits; if ( chanBits <= 16 ) { for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits ); val = (val << shift) >> shift; mMixBufferU[i] = val; } } else { // BitBufferRead() can't read more than 16 bits at a time so break up the reads extraBits = chanBits - 16; for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, 16 ); val = (val << 16) >> shift; mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t) extraBits ); } } mixBits = mixRes = 0; bits1 = chanBits * numSamples; bytesShifted = 0; } // now read the shifted values into the shift buffer if ( bytesShifted != 0 ) { shift = bytesShifted * 8; //Assert( shift <= 16 ); for ( i = 0; i < numSamples; i++ ) mShiftBuffer[i] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift ); } // convert 32-bit integers into output buffer switch ( mConfig.bitDepth ) { case 16: out16 = &((int16_t *)sampleBuffer)[channelIndex]; for ( i = 0, j = 0; i < numSamples; i++, j += numChannels ) out16[j] = (int16_t) mMixBufferU[i]; break; case 20: out20 = (uint8_t *)sampleBuffer + (channelIndex * 3); copyPredictorTo20( mMixBufferU, out20, numChannels, numSamples ); break; case 24: out24 = (uint8_t *)sampleBuffer + (channelIndex * 3); if ( bytesShifted != 0 ) copyPredictorTo24Shift( mMixBufferU, mShiftBuffer, out24, numChannels, numSamples, bytesShifted ); else copyPredictorTo24( mMixBufferU, out24, numChannels, numSamples ); break; case 32: out32 = &((int32_t *)sampleBuffer)[channelIndex]; if ( bytesShifted != 0 ) copyPredictorTo32Shift( mMixBufferU, mShiftBuffer, out32, numChannels, numSamples, bytesShifted ); else copyPredictorTo32( mMixBufferU, out32, numChannels, numSamples); break; } channelIndex += 1; *outNumSamples = numSamples; break; } case ID_CPE: { // if decoding this pair would take us over the max channels limit, bail if ( (channelIndex + 2) > numChannels ) goto NoMoreChannels; // stereo channel pair elementInstanceTag = BitBufferReadSmall( bits, 4 ); mActiveElements |= (1u << elementInstanceTag); // read the 12 unused header bits unusedHeader = (uint16_t) BitBufferRead( bits, 12 ); RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; ); // read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag headerByte = (uint8_t) BitBufferRead( bits, 4 ); partialFrame = headerByte >> 3; bytesShifted = (headerByte >> 1) & 0x3u; RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; ); shift = bytesShifted * 8; escapeFlag = headerByte & 0x1; chanBits = mConfig.bitDepth - (bytesShifted * 8) + 1; // check for partial frame length to override requested numSamples if ( partialFrame != 0 ) { numSamples = BitBufferRead( bits, 16 ) << 16; numSamples |= BitBufferRead( bits, 16 ); } if ( escapeFlag == 0 ) { // compressed frame, read rest of parameters mixBits = (uint8_t) BitBufferRead( bits, 8 ); mixRes = (int8_t) BitBufferRead( bits, 8 ); headerByte = (uint8_t) BitBufferRead( bits, 8 ); modeU = headerByte >> 4; denShiftU = headerByte & 0xfu; headerByte = (uint8_t) BitBufferRead( bits, 8 ); pbFactorU = headerByte >> 5; numU = headerByte & 0x1fu; for ( i = 0; i < numU; i++ ) coefsU[i] = (int16_t) BitBufferRead( bits, 16 ); headerByte = (uint8_t) BitBufferRead( bits, 8 ); modeV = headerByte >> 4; denShiftV = headerByte & 0xfu; headerByte = (uint8_t) BitBufferRead( bits, 8 ); pbFactorV = headerByte >> 5; numV = headerByte & 0x1fu; for ( i = 0; i < numV; i++ ) coefsV[i] = (int16_t) BitBufferRead( bits, 16 ); // if shift active, skip the interleaved shifted values but remember where they start if ( bytesShifted != 0 ) { shiftBits = *bits; BitBufferAdvance( bits, (bytesShifted * 8) * 2 * numSamples ); } // decompress and run predictor for "left" channel set_ag_params( &agParams, mConfig.mb, (pb * pbFactorU) / 4, mConfig.kb, numSamples, numSamples, mConfig.maxRun ); status = dyn_decomp( &agParams, bits, mPredictor, numSamples, chanBits, &bits1 ); RequireNoErr( status, goto Exit; ); if ( modeU == 0 ) { unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } else { // the special "numActive == 31" mode can be done in-place unpc_block( mPredictor, mPredictor, numSamples, nil, 31, chanBits, 0 ); unpc_block( mPredictor, mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU ); } // decompress and run predictor for "right" channel set_ag_params( &agParams, mConfig.mb, (pb * pbFactorV) / 4, mConfig.kb, numSamples, numSamples, mConfig.maxRun ); status = dyn_decomp( &agParams, bits, mPredictor, numSamples, chanBits, &bits2 ); RequireNoErr( status, goto Exit; ); if ( modeV == 0 ) { unpc_block( mPredictor, mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV ); } else { // the special "numActive == 31" mode can be done in-place unpc_block( mPredictor, mPredictor, numSamples, nil, 31, chanBits, 0 ); unpc_block( mPredictor, mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV ); } } else { //Assert( bytesShifted == 0 ); // uncompressed frame, copy data into the mix buffers to use common output code chanBits = mConfig.bitDepth; shift = 32 - chanBits; if ( chanBits <= 16 ) { for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits ); val = (val << shift) >> shift; mMixBufferU[i] = val; val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits ); val = (val << shift) >> shift; mMixBufferV[i] = val; } } else { // BitBufferRead() can't read more than 16 bits at a time so break up the reads extraBits = chanBits - 16; for ( i = 0; i < numSamples; i++ ) { val = (int32_t) BitBufferRead( bits, 16 ); val = (val << 16) >> shift; mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t)extraBits ); val = (int32_t) BitBufferRead( bits, 16 ); val = (val << 16) >> shift; mMixBufferV[i] = val | BitBufferRead( bits, (uint8_t)extraBits ); } } bits1 = chanBits * numSamples; bits2 = chanBits * numSamples; mixBits = mixRes = 0; bytesShifted = 0; } // now read the shifted values into the shift buffer if ( bytesShifted != 0 ) { shift = bytesShifted * 8; //Assert( shift <= 16 ); for ( i = 0; i < (numSamples * 2); i += 2 ) { mShiftBuffer[i + 0] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift ); mShiftBuffer[i + 1] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift ); } } // un-mix the data and convert to output format // - note that mixRes = 0 means just interleave so we use that path for uncompressed frames switch ( mConfig.bitDepth ) { case 16: out16 = &((int16_t *)sampleBuffer)[channelIndex]; unmix16( mMixBufferU, mMixBufferV, out16, numChannels, numSamples, mixBits, mixRes ); break; case 20: out20 = (uint8_t *)sampleBuffer + (channelIndex * 3); unmix20( mMixBufferU, mMixBufferV, out20, numChannels, numSamples, mixBits, mixRes ); break; case 24: out24 = (uint8_t *)sampleBuffer + (channelIndex * 3); unmix24( mMixBufferU, mMixBufferV, out24, numChannels, numSamples, mixBits, mixRes, mShiftBuffer, bytesShifted ); break; case 32: out32 = &((int32_t *)sampleBuffer)[channelIndex]; unmix32( mMixBufferU, mMixBufferV, out32, numChannels, numSamples, mixBits, mixRes, mShiftBuffer, bytesShifted ); break; } channelIndex += 2; *outNumSamples = numSamples; break; } case ID_CCE: case ID_PCE: { // unsupported element, bail //AssertNoErr( tag ); status = kALAC_ParamError; break; } case ID_DSE: { // data stream element -- parse but ignore status = this->DataStreamElement( bits ); break; } case ID_FIL: { // fill element -- parse but ignore status = this->FillElement( bits ); break; } case ID_END: { // frame end, all done so byte align the frame and check for overruns BitBufferByteAlign( bits, false ); //Assert( bits->cur == bits->end ); goto Exit; } } #if ! DEBUG // if we've decoded all of our channels, bail (but not in debug b/c we want to know if we're seeing bad bits) // - this also protects us if the config does not match the bitstream or crap data bits follow the audio bits if ( channelIndex >= numChannels ) break; #endif } NoMoreChannels: // if we get here and haven't decoded all of the requested channels, fill the remaining channels with zeros for ( ; channelIndex < numChannels; channelIndex++ ) { switch ( mConfig.bitDepth ) { case 16: { int16_t * fill16 = &((int16_t *)sampleBuffer)[channelIndex]; Zero16( fill16, numSamples, numChannels ); break; } case 24: { uint8_t * fill24 = (uint8_t *)sampleBuffer + (channelIndex * 3); Zero24( fill24, numSamples, numChannels ); break; } case 32: { int32_t * fill32 = &((int32_t *)sampleBuffer)[channelIndex]; Zero32( fill32, numSamples, numChannels ); break; } } } Exit: return status; } #if PRAGMA_MARK #pragma mark - #endif /* FillElement() - they're just filler so we don't need 'em */ int32_t ALACDecoder::FillElement( BitBuffer * bits ) { int16_t count; // 4-bit count or (4-bit + 8-bit count) if 4-bit count == 15 // - plus this weird -1 thing I still don't fully understand count = BitBufferReadSmall( bits, 4 ); if ( count == 15 ) count += (int16_t) BitBufferReadSmall( bits, 8 ) - 1; BitBufferAdvance( bits, count * 8 ); RequireAction( bits->cur <= bits->end, return kALAC_ParamError; ); return ALAC_noErr; } /* DataStreamElement() - we don't care about data stream elements so just skip them */ int32_t ALACDecoder::DataStreamElement( BitBuffer * bits ) { uint8_t element_instance_tag; int32_t data_byte_align_flag; uint16_t count; // the tag associates this data stream element with a given audio element element_instance_tag = BitBufferReadSmall( bits, 4 ); data_byte_align_flag = BitBufferReadOne( bits ); // 8-bit count or (8-bit + 8-bit count) if 8-bit count == 255 count = BitBufferReadSmall( bits, 8 ); if ( count == 255 ) count += BitBufferReadSmall( bits, 8 ); // the align flag means the bitstream should be byte-aligned before reading the following data bytes if ( data_byte_align_flag ) BitBufferByteAlign( bits, false ); // skip the data bytes BitBufferAdvance( bits, count * 8 ); RequireAction( bits->cur <= bits->end, return kALAC_ParamError; ); return ALAC_noErr; } /* ZeroN() - helper routines to clear out output channel buffers when decoding fewer channels than requested */ static void Zero16( int16_t * buffer, uint32_t numItems, uint32_t stride ) { if ( stride == 1 ) { memset( buffer, 0, numItems * sizeof(int16_t) ); } else { for ( uint32_t index = 0; index < (numItems * stride); index += stride ) buffer[index] = 0; } } static void Zero24( uint8_t * buffer, uint32_t numItems, uint32_t stride ) { if ( stride == 1 ) { memset( buffer, 0, numItems * 3 ); } else { for ( uint32_t index = 0; index < (numItems * stride * 3); index += (stride * 3) ) { buffer[index + 0] = 0; buffer[index + 1] = 0; buffer[index + 2] = 0; } } } static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride ) { if ( stride == 1 ) { memset( buffer, 0, numItems * sizeof(int32_t) ); } else { for ( uint32_t index = 0; index < (numItems * stride); index += stride ) buffer[index] = 0; } }