ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

wma.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Based on xoreos' WMA code which is in turn
00024 // Largely based on the WMA implementation found in FFmpeg.
00025 
00026 #include "common/util.h"
00027 #include "common/math.h"
00028 #include "common/sinewindows.h"
00029 #include "common/error.h"
00030 #include "common/memstream.h"
00031 #include "common/mdct.h"
00032 #include "common/huffman.h"
00033 
00034 #include "audio/audiostream.h"
00035 
00036 #include "audio/decoders/util.h"
00037 #include "audio/decoders/raw.h"
00038 #include "audio/decoders/wma.h"
00039 #include "audio/decoders/wmadata.h"
00040 
00041 namespace Audio {
00042 
00043 static inline void butterflyFloats(float *v1, float *v2, int len) {
00044     while (len-- > 0) {
00045         float t = *v1 - *v2;
00046 
00047         *v1++ += *v2;
00048         *v2++  = t;
00049     }
00050 }
00051 
00052 static inline void vectorFMulAdd(float *dst, const float *src0,
00053                           const float *src1, const float *src2, int len) {
00054     while (len-- > 0)
00055         *dst++ = *src0++ * *src1++ + *src2++;
00056 }
00057 
00058 static inline void vectorFMulReverse(float *dst, const float *src0,
00059                                      const float *src1, int len) {
00060     src1 += len - 1;
00061 
00062     while (len-- > 0)
00063         *dst++ = *src0++ * *src1--;
00064 }
00065 
00066 
00067 WMACodec::WMACodec(int version, uint32 sampleRate, uint8 channels,
00068         uint32 bitRate, uint32 blockAlign, Common::SeekableReadStream *extraData) :
00069     _version(version), _sampleRate(sampleRate), _channels(channels),
00070     _bitRate(bitRate), _blockAlign(blockAlign), _audioFlags(0),
00071     _resetBlockLengths(true), _curFrame(0), _frameLen(0), _frameLenBits(0),
00072     _blockSizeCount(0), _framePos(0), _curBlock(0), _blockLen(0), _blockLenBits(0),
00073     _nextBlockLenBits(0), _prevBlockLenBits(0), _byteOffsetBits(0),
00074     _hgainHuffman(0), _expHuffman(0), _lastSuperframeLen(0), _lastBitoffset(0) {
00075 
00076     for (int i = 0; i < 2; i++) {
00077         _coefHuffman[i] = 0;
00078 
00079         _coefHuffmanRunTable  [i] = 0;
00080         _coefHuffmanLevelTable[i] = 0;
00081         _coefHuffmanIntTable  [i] = 0;
00082     }
00083 
00084     if ((_version != 1) && (_version != 2))
00085         error("WMACodec::init(): Unsupported WMA version %d", _version);
00086 
00087     if ((_sampleRate == 0) || (_sampleRate > 50000))
00088         error("WMACodec::init(): Invalid sample rate %d", _sampleRate);
00089     if ((_channels == 0) || (_channels > kChannelsMax))
00090         error("WMACodec::init(): Unsupported number of channels %d",
00091                                 _channels);
00092 
00093     _audioFlags = FLAG_16BITS;
00094 
00095 #ifdef SCUMM_LITTLE_ENDIAN
00096     _audioFlags |= FLAG_LITTLE_ENDIAN;
00097 #endif
00098 
00099     if (_channels == 2) {
00100         _audioFlags |= FLAG_STEREO;
00101     }
00102 
00103     init(extraData);
00104 }
00105 
00106 WMACodec::~WMACodec() {
00107     delete _expHuffman;
00108     delete _hgainHuffman;
00109 
00110     for (int i = 0; i < 2; i++) {
00111         delete[] _coefHuffmanRunTable  [i];
00112         delete[] _coefHuffmanLevelTable[i];
00113         delete[] _coefHuffmanIntTable  [i];
00114 
00115         delete _coefHuffman[i];
00116     }
00117 
00118     for (Common::Array<Common::MDCT *>::iterator m = _mdct.begin(); m != _mdct.end(); ++m)
00119         delete *m;
00120 }
00121 
00122 void WMACodec::init(Common::SeekableReadStream *extraData) {
00123     // Flags
00124     uint16 flags = getFlags(extraData);
00125     evalFlags(flags, extraData);
00126 
00127     // Frame length
00128     _frameLenBits = getFrameBitLength();
00129     _frameLen     = 1 << _frameLenBits;
00130 
00131     // Number of MDCT block sizes
00132     _blockSizeCount = getBlockSizeCount(flags);
00133 
00134     float bps = ((float) _bitRate) / ((float) (_channels * _sampleRate));
00135 
00136     _byteOffsetBits = Common::intLog2((int) (bps * _frameLen / 8.0 + 0.05)) + 2;
00137 
00138     // Compute high frequency value and choose if noise coding should be activated
00139     float highFreq;
00140     _useNoiseCoding = useNoiseCoding(highFreq, bps);
00141 
00142     // Compute the scale factor band sizes for each MDCT block size
00143     evalMDCTScales(highFreq);
00144 
00145     // Init the noise generator
00146     initNoise();
00147 
00148     // Init the coefficient huffman codes
00149     initCoefHuffman(bps);
00150 
00151     // Init MDCTs
00152     initMDCT();
00153 
00154     // Init exponent codes
00155     initExponents();
00156 
00157     // Clear the sample output buffers
00158     memset(_output  , 0, sizeof(_output));
00159     memset(_frameOut, 0, sizeof(_frameOut));
00160 }
00161 
00162 uint16 WMACodec::getFlags(Common::SeekableReadStream *extraData) {
00163     if ((_version == 1) && extraData && (extraData->size() >= 4)) {
00164         extraData->seek(2);
00165         return extraData->readUint16LE();
00166     }
00167 
00168     if ((_version == 2) && extraData && (extraData->size() >= 6)) {
00169         extraData->seek(4);
00170         return extraData->readUint16LE();
00171     }
00172 
00173     return 0;
00174 }
00175 
00176 void WMACodec::evalFlags(uint16 flags, Common::SeekableReadStream *extraData) {
00177     _useExpHuffman       = (flags & 0x0001) != 0;
00178     _useBitReservoir     = (flags & 0x0002) != 0;
00179     _useVariableBlockLen = (flags & 0x0004) != 0;
00180 
00181     if ((_version == 2) && extraData && (extraData->size() >= 8)) {
00182         extraData->seek(4);
00183         if ((extraData->readUint16LE() == 0x000D) && _useVariableBlockLen) {
00184             // Apparently, this fixes ffmpeg "issue1503"
00185 
00186             _useVariableBlockLen = false;
00187         }
00188     }
00189 }
00190 
00191 int WMACodec::getFrameBitLength() {
00192     if (_sampleRate <= 16000)
00193         return 9;
00194 
00195     if ((_sampleRate <= 22050) || (_sampleRate <= 32000 && _version == 1))
00196         return 10;
00197 
00198     if (_sampleRate <= 48000)
00199         return 11;
00200 
00201     if (_sampleRate <= 96000)
00202         return 12;
00203 
00204     return 13;
00205 }
00206 
00207 int WMACodec::getBlockSizeCount(uint16 flags) {
00208     if (!_useVariableBlockLen)
00209         return 1;
00210 
00211     int count = ((flags >> 3) & 3) + 1;
00212 
00213     if ((_bitRate / _channels) >= 32000)
00214         count += 2;
00215 
00216     const int maxCount = _frameLenBits - kBlockBitsMin;
00217 
00218     return MIN(count, maxCount) + 1;
00219 }
00220 
00221 uint32 WMACodec::getNormalizedSampleRate() {
00222     // Sample rates are only normalized in WMAv2
00223     if (_version != 2)
00224         return _sampleRate;
00225 
00226     if (_sampleRate>= 44100)
00227         return 44100;
00228 
00229     if (_sampleRate >= 22050)
00230         return 22050;
00231 
00232     if (_sampleRate >= 16000)
00233         return 16000;
00234 
00235     if (_sampleRate >= 11025)
00236         return 11025;
00237 
00238     if (_sampleRate >=  8000)
00239         return 8000;
00240 
00241     return _sampleRate;
00242 }
00243 
00244 bool WMACodec::useNoiseCoding(float &highFreq, float &bps) {
00245     highFreq = _sampleRate * 0.5;
00246 
00247     uint32 rateNormalized = getNormalizedSampleRate();
00248 
00249     float bpsOrig = bps;
00250     if (_channels == 2)
00251         bps = bpsOrig * 1.6;
00252 
00253     if (rateNormalized == 44100) {
00254         if (bps >= 0.61)
00255             return false;
00256 
00257         highFreq = highFreq * 0.4;
00258         return true;
00259     }
00260 
00261     if (rateNormalized == 22050) {
00262         if (bps >= 1.16)
00263             return false;
00264 
00265         if (bps >= 0.72)
00266             highFreq = highFreq * 0.7;
00267         else
00268             highFreq = highFreq * 0.6;
00269 
00270         return true;
00271     }
00272 
00273     if (rateNormalized == 16000) {
00274         if (bpsOrig > 0.5)
00275             highFreq = highFreq * 0.5;
00276         else
00277             highFreq = highFreq * 0.3;
00278 
00279         return true;
00280     }
00281 
00282     if (rateNormalized == 11025) {
00283         highFreq = highFreq * 0.7;
00284         return true;
00285     }
00286 
00287     if (rateNormalized == 8000) {
00288         if (bpsOrig > 0.75)
00289             return false;
00290 
00291         if (bpsOrig <= 0.625)
00292             highFreq = highFreq * 0.5;
00293         else
00294             highFreq = highFreq * 0.65;
00295 
00296         return true;
00297     }
00298 
00299 
00300     if (bpsOrig >= 0.8)
00301         highFreq = highFreq * 0.75;
00302     else if (bpsOrig >= 0.6)
00303         highFreq = highFreq * 0.6;
00304     else
00305         highFreq = highFreq * 0.5;
00306 
00307     return true;
00308 }
00309 
00310 void WMACodec::evalMDCTScales(float highFreq) {
00311     if (_version == 1)
00312         _coefsStart = 3;
00313     else
00314         _coefsStart = 0;
00315 
00316     for (int k = 0; k < _blockSizeCount; k++) {
00317         int blockLen = _frameLen >> k;
00318 
00319         if (_version == 1) {
00320             int i, lpos = 0;
00321 
00322             for (i = 0; i < 25; i++) {
00323                 int a   = wmaCriticalFreqs[i];
00324                 int b   = _sampleRate;
00325                 int pos = ((blockLen * 2 * a) + (b >> 1)) / b;
00326 
00327                 if (pos > blockLen)
00328                     pos = blockLen;
00329 
00330                 _exponentBands[0][i] = pos - lpos;
00331                 if (pos >= blockLen) {
00332                     i++;
00333                     break;
00334                 }
00335                 lpos = pos;
00336             }
00337 
00338             _exponentSizes[0] = i;
00339 
00340         } else {
00341             // Hardcoded tables
00342             const uint8 *table = 0;
00343 
00344             int t = _frameLenBits - kBlockBitsMin - k;
00345             if (t < 3) {
00346                 if (_sampleRate >= 44100)
00347                     table = exponentBand44100[t];
00348                 else if (_sampleRate >= 32000)
00349                     table = exponentBand32000[t];
00350                 else if (_sampleRate >= 22050)
00351                     table = exponentBand22050[t];
00352             }
00353 
00354             if (table) {
00355                 int n = *table++;
00356 
00357                 for (int i = 0; i < n; i++)
00358                     _exponentBands[k][i] = table[i];
00359 
00360                 _exponentSizes[k] = n;
00361 
00362             } else {
00363                 int j = 0, lpos = 0;
00364 
00365                 for (int i = 0; i < 25; i++) {
00366                     int a   = wmaCriticalFreqs[i];
00367                     int b   = _sampleRate;
00368                     int pos = ((blockLen * 2 * a) + (b << 1)) / (4 * b);
00369 
00370                     pos <<= 2;
00371                     if (pos > blockLen)
00372                         pos = blockLen;
00373 
00374                     if (pos > lpos)
00375                         _exponentBands[k][j++] = pos - lpos;
00376 
00377                     if (pos >= blockLen)
00378                         break;
00379 
00380                     lpos = pos;
00381                 }
00382 
00383                 _exponentSizes[k] = j;
00384             }
00385 
00386         }
00387 
00388         // Max number of coefs
00389         _coefsEnd[k] = (_frameLen - ((_frameLen * 9) / 100)) >> k;
00390 
00391         // High freq computation
00392         _highBandStart[k] = (int)((blockLen * 2 * highFreq) / _sampleRate + 0.5);
00393 
00394         int n   = _exponentSizes[k];
00395         int j   = 0;
00396         int pos = 0;
00397 
00398         for (int i = 0; i < n; i++) {
00399             int start, end;
00400 
00401             start = pos;
00402             pos  += _exponentBands[k][i];
00403             end   = pos;
00404 
00405             if (start < _highBandStart[k])
00406                 start = _highBandStart[k];
00407 
00408             if (end > _coefsEnd[k])
00409                 end = _coefsEnd[k];
00410 
00411             if (end > start)
00412                 _exponentHighBands[k][j++] = end - start;
00413 
00414         }
00415 
00416         _exponentHighSizes[k] = j;
00417     }
00418 }
00419 
00420 void WMACodec::initNoise() {
00421     if (!_useNoiseCoding)
00422         return;
00423 
00424     _noiseMult  = _useExpHuffman ? 0.02 : 0.04;
00425     _noiseIndex = 0;
00426 
00427     uint  seed = 1;
00428     float norm = (1.0 / (float)(1LL << 31)) * sqrt(3.0f) * _noiseMult;
00429 
00430     for (int i = 0; i < kNoiseTabSize; i++) {
00431         seed = seed * 314159 + 1;
00432 
00433         _noiseTable[i] = (float)((int)seed) * norm;
00434     }
00435 
00436     _hgainHuffman = new HuffmanDecoder(0, ARRAYSIZE(hgainHuffCodes),
00437                                         hgainHuffCodes, hgainHuffBits);
00438 }
00439 
00440 void WMACodec::initCoefHuffman(float bps) {
00441     // Choose the parameter table
00442     int coefHuffTable = 2;
00443     if (_sampleRate >= 32000) {
00444         if (bps < 0.72) {
00445             coefHuffTable = 0;
00446         } else if (bps < 1.16) {
00447             coefHuffTable = 1;
00448         }
00449     }
00450 
00451     _coefHuffmanParam[0] = &coefHuffmanParam[coefHuffTable * 2    ];
00452     _coefHuffmanParam[1] = &coefHuffmanParam[coefHuffTable * 2 + 1];
00453 
00454     _coefHuffman[0] = initCoefHuffman(_coefHuffmanRunTable[0], _coefHuffmanLevelTable[0],
00455                                       _coefHuffmanIntTable[0], *_coefHuffmanParam[0]);
00456     _coefHuffman[1] = initCoefHuffman(_coefHuffmanRunTable[1], _coefHuffmanLevelTable[1],
00457                                       _coefHuffmanIntTable[1], *_coefHuffmanParam[1]);
00458 }
00459 
00460 void WMACodec::initMDCT() {
00461     _mdct.reserve(_blockSizeCount);
00462     for (int i = 0; i < _blockSizeCount; i++)
00463         _mdct.push_back(new Common::MDCT(_frameLenBits - i + 1, true, 1.0));
00464 
00465     // Init MDCT windows (simple sine window)
00466     _mdctWindow.reserve(_blockSizeCount);
00467     for (int i = 0; i < _blockSizeCount; i++)
00468         _mdctWindow.push_back(Common::getSineWindow(_frameLenBits - i));
00469 }
00470 
00471 void WMACodec::initExponents() {
00472     if (_useExpHuffman)
00473         _expHuffman = new HuffmanDecoder(0, ARRAYSIZE(scaleHuffCodes),
00474                                           scaleHuffCodes, scaleHuffBits);
00475     else
00476         initLSPToCurve();
00477 }
00478 
00479 WMACodec::HuffmanDecoder *WMACodec::initCoefHuffman(uint16 *&runTable, float *&levelTable,
00480         uint16 *&intTable, const WMACoefHuffmanParam &params) {
00481 
00482     HuffmanDecoder *huffman =
00483         new HuffmanDecoder(0, params.n, params.huffCodes, params.huffBits);
00484 
00485     runTable   = new uint16[params.n];
00486     levelTable = new  float[params.n];
00487     intTable   = new uint16[params.n];
00488 
00489     uint16 *iLevelTable = new uint16[params.n];
00490 
00491     int i = 2;
00492     int level = 1;
00493     int k = 0;
00494 
00495     while (i < params.n) {
00496         intTable[k] = i;
00497 
00498         int l = params.levels[k++];
00499 
00500         for (int j = 0; j < l; j++) {
00501             runTable   [i] = j;
00502             iLevelTable[i] = level;
00503             levelTable [i] = level;
00504 
00505             i++;
00506         }
00507 
00508         level++;
00509     }
00510 
00511     delete[] iLevelTable;
00512 
00513     return huffman;
00514 }
00515 
00516 void WMACodec::initLSPToCurve() {
00517     float wdel = M_PI / _frameLen;
00518 
00519     for (int i = 0; i < _frameLen; i++)
00520         _lspCosTable[i] = 2.0f * cosf(wdel * i);
00521 
00522     // Tables for x^-0.25 computation
00523     for (int i = 0; i < 256; i++) {
00524         int e = i - 126;
00525 
00526         _lspPowETable[i] = powf(2.0, e * -0.25);
00527     }
00528 
00529     // NOTE: These two tables are needed to avoid two operations in pow_m1_4
00530     float b = 1.0;
00531     for (int i = (1 << kLSPPowBits) - 1; i >= 0; i--) {
00532         int   m = (1 << kLSPPowBits) + i;
00533         float a = (float) m * (0.5 / (1 << kLSPPowBits));
00534 
00535         a = pow(a, -0.25f);
00536 
00537         _lspPowMTable1[i] = 2 * a - b;
00538         _lspPowMTable2[i] = b - a;
00539 
00540         b = a;
00541     }
00542 }
00543 
00544 AudioStream *WMACodec::decodeFrame(Common::SeekableReadStream &data) {
00545     Common::SeekableReadStream *stream = decodeSuperFrame(data);
00546     if (!stream)
00547         return 0;
00548 
00549     return makeRawStream(stream, _sampleRate, _audioFlags, DisposeAfterUse::YES);
00550 }
00551 
00552 Common::SeekableReadStream *WMACodec::decodeSuperFrame(Common::SeekableReadStream &data) {
00553     uint32 size = data.size();
00554     if (size < _blockAlign) {
00555         warning("WMACodec::decodeSuperFrame(): size < _blockAlign");
00556         return 0;
00557     }
00558 
00559     if (_blockAlign)
00560         size = _blockAlign;
00561 
00562     Common::BitStream8MSB bits(data);
00563 
00564     int    outputDataSize = 0;
00565     int16 *outputData     = 0;
00566 
00567     _curFrame = 0;
00568 
00569     if (_useBitReservoir) {
00570         // This superframe consists of more than just one frame
00571 
00572         bits.skip(4); // Super frame index
00573 
00574         // Number of frames in this superframe
00575         int newFrameCount = bits.getBits(4) - 1;
00576         if (newFrameCount < 0) {
00577             warning("WMACodec::decodeSuperFrame(): newFrameCount == %d", newFrameCount);
00578 
00579             _resetBlockLengths = true;
00580             _lastSuperframeLen = 0;
00581             _lastBitoffset     = 0;
00582 
00583             return 0;
00584         }
00585 
00586         // Number of frames in this superframe + overhang from the last superframe
00587         int frameCount = newFrameCount;
00588         if (_lastSuperframeLen > 0)
00589             frameCount++;
00590 
00591         // PCM output data
00592         outputDataSize = frameCount * _channels * _frameLen;
00593         outputData     = new int16[outputDataSize];
00594 
00595         memset(outputData, 0, outputDataSize * 2);
00596 
00597         // Number of bits data that completes the last superframe's overhang.
00598         int bitOffset = bits.getBits(_byteOffsetBits + 3);
00599 
00600         if (_lastSuperframeLen > 0) {
00601             // We have overhang data from the last superframe. Paste the
00602             // complementary data from this superframe at the end and
00603             // decode it as another frame.
00604 
00605             byte *lastSuperframeEnd = _lastSuperframe + _lastSuperframeLen;
00606 
00607             while (bitOffset > 7) { // Full bytes
00608                 *lastSuperframeEnd++ = bits.getBits(8);
00609 
00610                 bitOffset          -= 8;
00611                 _lastSuperframeLen += 1;
00612             }
00613 
00614             if (bitOffset > 0) { // Remaining bits
00615                 *lastSuperframeEnd++ = bits.getBits(bitOffset) << (8 - bitOffset);
00616 
00617                 bitOffset           = 0;
00618                 _lastSuperframeLen += 1;
00619             }
00620 
00621             Common::MemoryReadStream lastSuperframe(_lastSuperframe, _lastSuperframeLen);
00622             Common::BitStream8MSB lastBits(lastSuperframe);
00623 
00624             lastBits.skip(_lastBitoffset);
00625 
00626             decodeFrame(lastBits, outputData);
00627 
00628             _curFrame++;
00629         }
00630 
00631         // Skip any complementary data we haven't used
00632         bits.skip(bitOffset);
00633 
00634         // New superframe = New block lengths
00635         _resetBlockLengths = true;
00636 
00637         // Decode the frames
00638         for (int i = 0; i < newFrameCount; i++, _curFrame++)
00639             if (!decodeFrame(bits, outputData))
00640                 return 0;
00641 
00642         // Check if we've got new overhang data
00643         int remainingBits = bits.size() - bits.pos();
00644         if (remainingBits > 0) {
00645             // We do: Save it
00646 
00647             _lastSuperframeLen = remainingBits >> 3;
00648             _lastBitoffset     = 8 - (remainingBits - (_lastSuperframeLen << 3));
00649 
00650             if (_lastBitoffset > 0)
00651                 _lastSuperframeLen++;
00652 
00653             data.seek(data.size() - _lastSuperframeLen);
00654             data.read(_lastSuperframe, _lastSuperframeLen);
00655         } else {
00656             // We don't
00657 
00658             _lastSuperframeLen = 0;
00659             _lastBitoffset     = 0;
00660         }
00661 
00662     } else {
00663         // This superframe has only one frame
00664 
00665         // PCM output data
00666         outputDataSize = _channels * _frameLen;
00667         outputData     = new int16[outputDataSize];
00668 
00669         memset(outputData, 0, outputDataSize * 2);
00670 
00671         // Decode the frame
00672         if (!decodeFrame(bits, outputData)) {
00673             delete[] outputData;
00674             return 0;
00675         }
00676     }
00677 
00678     // And return our PCM output data as a stream, if available
00679 
00680     if (!outputData)
00681         return 0;
00682 
00683     return new Common::MemoryReadStream((byte *) outputData, outputDataSize * 2, DisposeAfterUse::YES);
00684 }
00685 
00686 bool WMACodec::decodeFrame(Common::BitStream8MSB &bits, int16 *outputData) {
00687     _framePos = 0;
00688     _curBlock = 0;
00689 
00690     // Decode all blocks
00691     int finished = 0;
00692     while (finished == 0)
00693         finished = decodeBlock(bits);
00694 
00695     // Check for error
00696     if (finished < 0)
00697         return false;
00698 
00699     // Convert output into interleaved PCM data
00700 
00701     const float *floatOut[kChannelsMax];
00702     for (int i = 0; i < kChannelsMax; i++)
00703         floatOut[i] = _frameOut[i];
00704 
00705     int16 *pcmOut = outputData + _curFrame * _channels * _frameLen;
00706 
00707     floatToInt16Interleave(pcmOut, floatOut, _frameLen, _channels);
00708 
00709     // Prepare for the next frame
00710     for (int i = 0; i < _channels; i++)
00711         memmove(&_frameOut[i][0], &_frameOut[i][_frameLen], _frameLen * sizeof(float));
00712 
00713     return true;
00714 }
00715 
00716 int WMACodec::decodeBlock(Common::BitStream8MSB &bits) {
00717     // Computer new block length
00718     if (!evalBlockLength(bits))
00719         return -1;
00720 
00721     // Block size
00722 
00723     int bSize = _frameLenBits - _blockLenBits;
00724     assert((bSize >= 0) && (bSize < _blockSizeCount));
00725 
00726     // MS Stereo?
00727 
00728     bool msStereo = false;
00729     if (_channels == 2)
00730         msStereo = bits.getBit();
00731 
00732     // Which channels are encoded?
00733 
00734     bool hasChannels = false;
00735     bool hasChannel[kChannelsMax];
00736     for (int i = 0; i < kChannelsMax; i++)
00737         hasChannel[i] = false;
00738 
00739     for (int i = 0; i < _channels; i++) {
00740         hasChannel[i] = bits.getBit();
00741         if (hasChannel[i])
00742             hasChannels = true;
00743     }
00744 
00745     // Decode channels
00746 
00747     if (hasChannels)
00748         if (!decodeChannels(bits, bSize, msStereo, hasChannel))
00749             return -1;
00750 
00751     // Calculate IMDCTs
00752 
00753     if (!calculateIMDCT(bSize, msStereo, hasChannel))
00754         return -1;
00755 
00756     // Update block number
00757 
00758     _curBlock += 1;
00759     _framePos += _blockLen;
00760 
00761     // Finished
00762     if (_framePos >= _frameLen)
00763         return 1;
00764 
00765     // Need more blocks
00766     return 0;
00767 }
00768 
00769 bool WMACodec::decodeChannels(Common::BitStream8MSB &bits, int bSize,
00770                               bool msStereo, bool *hasChannel) {
00771 
00772     int totalGain    = readTotalGain(bits);
00773     int coefBitCount = totalGainToBits(totalGain);
00774 
00775     int coefCount[kChannelsMax];
00776     calculateCoefCount(coefCount, bSize);
00777 
00778     if (!decodeNoise(bits, bSize, hasChannel, coefCount))
00779         return false;
00780 
00781     if (!decodeExponents(bits, bSize, hasChannel))
00782         return false;
00783 
00784     if (!decodeSpectralCoef(bits, msStereo, hasChannel, coefCount, coefBitCount))
00785         return false;
00786 
00787     float mdctNorm = getNormalizedMDCTLength();
00788 
00789     calculateMDCTCoefficients(bSize, hasChannel, coefCount, totalGain, mdctNorm);
00790 
00791     if (msStereo && hasChannel[1]) {
00792         // Nominal case for ms stereo: we do it before MDCT
00793         // No need to optimize this case because it should almost never happen
00794 
00795         if (!hasChannel[0]) {
00796             memset(_coefs[0], 0, sizeof(float) * _blockLen);
00797             hasChannel[0] = true;
00798         }
00799 
00800         butterflyFloats(_coefs[0], _coefs[1], _blockLen);
00801     }
00802 
00803     return true;
00804 }
00805 
00806 bool WMACodec::calculateIMDCT(int bSize, bool msStereo, bool *hasChannel) {
00807     Common::MDCT &mdct = *_mdct[bSize];
00808 
00809     for (int i = 0; i < _channels; i++) {
00810         int n4 = _blockLen / 2;
00811 
00812         if (hasChannel[i])
00813             mdct.calcIMDCT(_output, _coefs[i]);
00814         else if (!(msStereo && (i == 1)))
00815             memset(_output, 0, sizeof(_output));
00816 
00817         // Multiply by the window and add in the frame
00818         int index = (_frameLen / 2) + _framePos - n4;
00819         window(&_frameOut[i][index]);
00820     }
00821 
00822     return true;
00823 }
00824 
00825 bool WMACodec::evalBlockLength(Common::BitStream8MSB &bits) {
00826     if (_useVariableBlockLen) {
00827         // Variable block lengths
00828 
00829         int n = Common::intLog2(_blockSizeCount - 1) + 1;
00830 
00831         if (_resetBlockLengths) {
00832             // Completely new block lengths
00833 
00834             _resetBlockLengths = false;
00835 
00836             const int prev     = bits.getBits(n);
00837             const int prevBits = _frameLenBits - prev;
00838             if (prev >= _blockSizeCount) {
00839                 warning("WMACodec::evalBlockLength(): _prevBlockLenBits %d out of range", prevBits);
00840                 return false;
00841             }
00842 
00843             _prevBlockLenBits = prevBits;
00844 
00845             const int cur     = bits.getBits(n);
00846             const int curBits = _frameLenBits - cur;
00847             if (cur >= _blockSizeCount) {
00848                 warning("WMACodec::evalBlockLength(): _blockLenBits %d out of range", curBits);
00849                 return false;
00850             }
00851 
00852             _blockLenBits = curBits;
00853 
00854         } else {
00855             // Update block lengths
00856 
00857             _prevBlockLenBits = _blockLenBits;
00858             _blockLenBits     = _nextBlockLenBits;
00859         }
00860 
00861         const int next     = bits.getBits(n);
00862         const int nextBits = _frameLenBits - next;
00863         if (next >= _blockSizeCount) {
00864             warning("WMACodec::evalBlockLength(): _nextBlockLenBits %d out of range", nextBits);
00865             return false;
00866         }
00867 
00868         _nextBlockLenBits = nextBits;
00869 
00870     } else {
00871         // Fixed block length
00872 
00873         _nextBlockLenBits = _frameLenBits;
00874         _prevBlockLenBits = _frameLenBits;
00875         _blockLenBits     = _frameLenBits;
00876     }
00877 
00878     // Sanity checks
00879 
00880     if (_frameLenBits - _blockLenBits >= _blockSizeCount) {
00881         warning("WMACodec::evalBlockLength(): _blockLenBits not initialized to a valid value");
00882         return false;
00883     }
00884 
00885     _blockLen = 1 << _blockLenBits;
00886     if ((_framePos + _blockLen) > _frameLen) {
00887         warning("WMACodec::evalBlockLength(): frame length overflow");
00888         return false;
00889     }
00890 
00891     return true;
00892 }
00893 
00894 void WMACodec::calculateCoefCount(int *coefCount, int bSize) const {
00895     const int coefN = _coefsEnd[bSize] - _coefsStart;
00896 
00897     for (int i = 0; i < _channels; i++)
00898         coefCount[i] = coefN;
00899 }
00900 
00901 bool WMACodec::decodeNoise(Common::BitStream8MSB &bits, int bSize,
00902                            bool *hasChannel, int *coefCount) {
00903     if (!_useNoiseCoding)
00904         return true;
00905 
00906     for (int i = 0; i < _channels; i++) {
00907         if (!hasChannel[i])
00908             continue;
00909 
00910         const int n = _exponentHighSizes[bSize];
00911         for (int j = 0; j < n; j++) {
00912             bool a = bits.getBit() != 0;
00913             _highBandCoded[i][j] = a;
00914 
00915             // With noise coding, the coefficients are not transmitted
00916             if (a)
00917                 coefCount[i] -= _exponentHighBands[bSize][j];
00918         }
00919     }
00920 
00921     for (int i = 0; i < _channels; i++) {
00922         if (!hasChannel[i])
00923             continue;
00924 
00925         const int n   = _exponentHighSizes[bSize];
00926               int val = (int) 0x80000000;
00927 
00928         for (int j = 0; j < n; j++) {
00929             if (!_highBandCoded[i][j])
00930                 continue;
00931 
00932             if (val != (int) 0x80000000) {
00933                 int code = _hgainHuffman->getSymbol(bits);
00934                 if (code < 0) {
00935                     warning("WMACodec::decodeNoise(): HGain Huffman invalid");
00936                     return false;
00937                 }
00938 
00939                 val += code - 18;
00940 
00941             } else
00942                 val = bits.getBits(7) - 19;
00943 
00944             _highBandValues[i][j] = val;
00945 
00946         }
00947     }
00948 
00949     return true;
00950 }
00951 
00952 bool WMACodec::decodeExponents(Common::BitStream8MSB &bits, int bSize, bool *hasChannel) {
00953     // Exponents can be reused in short blocks
00954     if (!((_blockLenBits == _frameLenBits) || bits.getBit()))
00955         return true;
00956 
00957     for (int i = 0; i < _channels; i++) {
00958         if (!hasChannel[i])
00959             continue;
00960 
00961         if (_useExpHuffman) {
00962             if (!decodeExpHuffman(bits, i))
00963                 return false;
00964         } else {
00965             if (!decodeExpLSP(bits, i))
00966                 return false;
00967         }
00968 
00969         _exponentsBSize[i] = bSize;
00970     }
00971 
00972     return true;
00973 }
00974 
00975 bool WMACodec::decodeSpectralCoef(Common::BitStream8MSB &bits, bool msStereo, bool *hasChannel,
00976                                   int *coefCount, int coefBitCount) {
00977     // Simple RLE encoding
00978 
00979     for (int i = 0; i < _channels; i++) {
00980         if (hasChannel[i]) {
00981             // Special Huffman tables are used for MS stereo
00982             // because there is potentially less energy there.
00983             const int tindex = ((i == 1) && msStereo);
00984 
00985             float *ptr = &_coefs1[i][0];
00986             memset(ptr, 0, _blockLen * sizeof(float));
00987 
00988             if (!decodeRunLevel(bits, *_coefHuffman[tindex],
00989                                 _coefHuffmanLevelTable[tindex], _coefHuffmanRunTable[tindex],
00990                                 0, ptr, 0, coefCount[i], _blockLen, _frameLenBits, coefBitCount))
00991                 return false;
00992         }
00993 
00994         if ((_version == 1) && (_channels >= 2))
00995             bits.skip(-bits.pos() & 7);
00996     }
00997 
00998     return true;
00999 }
01000 
01001 float WMACodec::getNormalizedMDCTLength() const {
01002     const int n4 = _blockLen / 2;
01003 
01004     float mdctNorm = 1.0 / (float) n4;
01005     if (_version == 1)
01006         mdctNorm *= sqrt((float) n4);
01007 
01008     return mdctNorm;
01009 }
01010 
01011 void WMACodec::calculateMDCTCoefficients(int bSize, bool *hasChannel,
01012                                         int *coefCount, int totalGain, float mdctNorm) {
01013 
01014     for (int i = 0; i < _channels; i++) {
01015         if (!hasChannel[i])
01016             continue;
01017 
01018               float *coefs     = _coefs[i];
01019         const float *coefs1    = _coefs1[i];
01020         const float *exponents = _exponents[i];
01021 
01022         const int eSize = _exponentsBSize[i];
01023 
01024         const float mult = (pow(10, totalGain * 0.05) / _maxExponent[i]) * mdctNorm;
01025 
01026         if (_useNoiseCoding) {
01027 
01028             // Very low freqs: noise
01029             for (int j = 0; j < _coefsStart; j++) {
01030                 *coefs++ = _noiseTable[_noiseIndex] * exponents[(j << bSize) >> eSize] * mult;
01031 
01032                 _noiseIndex = (_noiseIndex + 1) & (kNoiseTabSize - 1);
01033             }
01034 
01035             // Compute power of high bands
01036             float expPower[kHighBandSizeMax];
01037 
01038             const int n1 = _exponentHighSizes[bSize];
01039             exponents = _exponents[i] + ((_highBandStart[bSize] << bSize) >> eSize);
01040 
01041             int lastHighBand = 0;
01042             for (int k = 0; k < n1; k++) {
01043                 const int n = _exponentHighBands[_frameLenBits - _blockLenBits][k];
01044 
01045                 if (_highBandCoded[i][k]) {
01046                     float e2 = 0;
01047 
01048                     for (int j = 0; j < n; j++) {
01049                         const float v = exponents[(j << bSize) >> eSize];
01050 
01051                         e2 += v * v;
01052                     }
01053 
01054                     expPower[k] = e2 / n;
01055                     lastHighBand = k;
01056                 }
01057 
01058                 exponents += (n << bSize) >> eSize;
01059             }
01060 
01061             // Main freqs and high freqs
01062             exponents = _exponents[i] + ((_coefsStart << bSize) >> eSize);
01063 
01064             for (int k = -1; k < n1; k++) {
01065 
01066                 int n;
01067                 if (k < 0)
01068                     n = _highBandStart[bSize] - _coefsStart;
01069                 else
01070                     n = _exponentHighBands[_frameLenBits - _blockLenBits][k];
01071 
01072                 if (k >= 0 && _highBandCoded[i][k]) {
01073                     // Use noise with specified power
01074 
01075                     float mult1 = sqrt(expPower[k] / expPower[lastHighBand]);
01076 
01077                     mult1 *= pow(10, _highBandValues[i][k] * 0.05);
01078                     mult1 /= _maxExponent[i] * _noiseMult;
01079                     mult1 *= mdctNorm;
01080 
01081                     for (int j = 0; j < n; j++) {
01082                         float noise = _noiseTable[_noiseIndex];
01083 
01084                         _noiseIndex = (_noiseIndex + 1) & (kNoiseTabSize - 1);
01085                         *coefs++    = noise * exponents[(j << bSize) >> eSize] * mult1;
01086                     }
01087 
01088                     exponents += (n << bSize) >> eSize;
01089 
01090                 } else {
01091                     // Coded values + small noise
01092 
01093                     for (int j = 0; j < n; j++) {
01094                         float noise = _noiseTable[_noiseIndex];
01095 
01096                         _noiseIndex = (_noiseIndex + 1) & (kNoiseTabSize - 1);
01097                         *coefs++    = ((*coefs1++) + noise) * exponents[(j << bSize) >> eSize] * mult;
01098                     }
01099 
01100                     exponents += (n << bSize) >> eSize;
01101                 }
01102 
01103             }
01104 
01105             // Very high freqs: Noise
01106             const int   n     = _blockLen - _coefsEnd[bSize];
01107             const float mult1 = mult * exponents[(-(1 << bSize)) >> eSize];
01108 
01109             for (int j = 0; j < n; j++) {
01110                 *coefs++    = _noiseTable[_noiseIndex] * mult1;
01111                 _noiseIndex = (_noiseIndex + 1) & (kNoiseTabSize - 1);
01112             }
01113 
01114         } else {
01115 
01116             for (int j = 0; j < _coefsStart; j++)
01117                 *coefs++ = 0.0;
01118 
01119             for (int j = 0;j < coefCount[i]; j++) {
01120                 *coefs = coefs1[j] * exponents[(j << bSize) >> eSize] * mult;
01121                 coefs++;
01122             }
01123 
01124             int n = _blockLen - _coefsEnd[bSize];
01125             for (int j = 0; j < n; j++)
01126                 *coefs++ = 0.0;
01127 
01128         }
01129 
01130     }
01131 
01132 }
01133 
01134 static const float powTab[] = {
01135     1.7782794100389e-04, 2.0535250264571e-04,
01136     2.3713737056617e-04, 2.7384196342644e-04,
01137     3.1622776601684e-04, 3.6517412725484e-04,
01138     4.2169650342858e-04, 4.8696752516586e-04,
01139     5.6234132519035e-04, 6.4938163157621e-04,
01140     7.4989420933246e-04, 8.6596432336006e-04,
01141     1.0000000000000e-03, 1.1547819846895e-03,
01142     1.3335214321633e-03, 1.5399265260595e-03,
01143     1.7782794100389e-03, 2.0535250264571e-03,
01144     2.3713737056617e-03, 2.7384196342644e-03,
01145     3.1622776601684e-03, 3.6517412725484e-03,
01146     4.2169650342858e-03, 4.8696752516586e-03,
01147     5.6234132519035e-03, 6.4938163157621e-03,
01148     7.4989420933246e-03, 8.6596432336006e-03,
01149     1.0000000000000e-02, 1.1547819846895e-02,
01150     1.3335214321633e-02, 1.5399265260595e-02,
01151     1.7782794100389e-02, 2.0535250264571e-02,
01152     2.3713737056617e-02, 2.7384196342644e-02,
01153     3.1622776601684e-02, 3.6517412725484e-02,
01154     4.2169650342858e-02, 4.8696752516586e-02,
01155     5.6234132519035e-02, 6.4938163157621e-02,
01156     7.4989420933246e-02, 8.6596432336007e-02,
01157     1.0000000000000e-01, 1.1547819846895e-01,
01158     1.3335214321633e-01, 1.5399265260595e-01,
01159     1.7782794100389e-01, 2.0535250264571e-01,
01160     2.3713737056617e-01, 2.7384196342644e-01,
01161     3.1622776601684e-01, 3.6517412725484e-01,
01162     4.2169650342858e-01, 4.8696752516586e-01,
01163     5.6234132519035e-01, 6.4938163157621e-01,
01164     7.4989420933246e-01, 8.6596432336007e-01,
01165     1.0000000000000e+00, 1.1547819846895e+00,
01166     1.3335214321633e+00, 1.5399265260595e+00,
01167     1.7782794100389e+00, 2.0535250264571e+00,
01168     2.3713737056617e+00, 2.7384196342644e+00,
01169     3.1622776601684e+00, 3.6517412725484e+00,
01170     4.2169650342858e+00, 4.8696752516586e+00,
01171     5.6234132519035e+00, 6.4938163157621e+00,
01172     7.4989420933246e+00, 8.6596432336007e+00,
01173     1.0000000000000e+01, 1.1547819846895e+01,
01174     1.3335214321633e+01, 1.5399265260595e+01,
01175     1.7782794100389e+01, 2.0535250264571e+01,
01176     2.3713737056617e+01, 2.7384196342644e+01,
01177     3.1622776601684e+01, 3.6517412725484e+01,
01178     4.2169650342858e+01, 4.8696752516586e+01,
01179     5.6234132519035e+01, 6.4938163157621e+01,
01180     7.4989420933246e+01, 8.6596432336007e+01,
01181     1.0000000000000e+02, 1.1547819846895e+02,
01182     1.3335214321633e+02, 1.5399265260595e+02,
01183     1.7782794100389e+02, 2.0535250264571e+02,
01184     2.3713737056617e+02, 2.7384196342644e+02,
01185     3.1622776601684e+02, 3.6517412725484e+02,
01186     4.2169650342858e+02, 4.8696752516586e+02,
01187     5.6234132519035e+02, 6.4938163157621e+02,
01188     7.4989420933246e+02, 8.6596432336007e+02,
01189     1.0000000000000e+03, 1.1547819846895e+03,
01190     1.3335214321633e+03, 1.5399265260595e+03,
01191     1.7782794100389e+03, 2.0535250264571e+03,
01192     2.3713737056617e+03, 2.7384196342644e+03,
01193     3.1622776601684e+03, 3.6517412725484e+03,
01194     4.2169650342858e+03, 4.8696752516586e+03,
01195     5.6234132519035e+03, 6.4938163157621e+03,
01196     7.4989420933246e+03, 8.6596432336007e+03,
01197     1.0000000000000e+04, 1.1547819846895e+04,
01198     1.3335214321633e+04, 1.5399265260595e+04,
01199     1.7782794100389e+04, 2.0535250264571e+04,
01200     2.3713737056617e+04, 2.7384196342644e+04,
01201     3.1622776601684e+04, 3.6517412725484e+04,
01202     4.2169650342858e+04, 4.8696752516586e+04,
01203     5.6234132519035e+04, 6.4938163157621e+04,
01204     7.4989420933246e+04, 8.6596432336007e+04,
01205     1.0000000000000e+05, 1.1547819846895e+05,
01206     1.3335214321633e+05, 1.5399265260595e+05,
01207     1.7782794100389e+05, 2.0535250264571e+05,
01208     2.3713737056617e+05, 2.7384196342644e+05,
01209     3.1622776601684e+05, 3.6517412725484e+05,
01210     4.2169650342858e+05, 4.8696752516586e+05,
01211     5.6234132519035e+05, 6.4938163157621e+05,
01212     7.4989420933246e+05, 8.6596432336007e+05,
01213 };
01214 
01215 bool WMACodec::decodeExpHuffman(Common::BitStream8MSB &bits, int ch) {
01216     const float  *ptab  = powTab + 60;
01217     const uint32 *iptab = (const uint32 *) ptab;
01218 
01219     const uint16 *ptr = _exponentBands[_frameLenBits - _blockLenBits];
01220 
01221     uint32 *q = (uint32 *) _exponents[ch];
01222     uint32 *qEnd = q + _blockLen;
01223 
01224     float maxScale = 0;
01225 
01226     int lastExp;
01227     if (_version == 1) {
01228 
01229         lastExp = bits.getBits(5) + 10;
01230 
01231         float   v = ptab[lastExp];
01232         uint32 iv = iptab[lastExp];
01233 
01234         maxScale = v;
01235 
01236         int n = *ptr++;
01237 
01238         switch (n & 3) do {
01239             case 0: *q++ = iv; // fall through
01240             case 3: *q++ = iv; // fall through
01241             case 2: *q++ = iv; // fall through
01242             case 1: *q++ = iv;
01243         } while ((n -= 4) > 0);
01244 
01245     } else
01246         lastExp = 36;
01247 
01248     while (q < qEnd) {
01249         int code = _expHuffman->getSymbol(bits);
01250         if (code < 0) {
01251             warning("WMACodec::decodeExpHuffman(): Exponent invalid");
01252             return false;
01253         }
01254 
01255         // NOTE: This offset is the same as MPEG4 AAC!
01256         lastExp += code - 60;
01257         if ((unsigned) lastExp + 60 >= ARRAYSIZE(powTab)) {
01258             warning("WMACodec::decodeExpHuffman(): Exponent out of range: %d", lastExp);
01259             return false;
01260         }
01261 
01262         float   v = ptab[lastExp];
01263         uint32 iv = iptab[lastExp];
01264 
01265         if (v > maxScale)
01266             maxScale = v;
01267 
01268         int n = *ptr++;
01269 
01270         switch (n & 3) do {
01271             case 0: *q++ = iv; // fall through
01272             case 3: *q++ = iv; // fall through
01273             case 2: *q++ = iv; // fall through
01274             case 1: *q++ = iv;
01275         } while ((n -= 4) > 0);
01276 
01277     }
01278 
01279     _maxExponent[ch] = maxScale;
01280 
01281     return true;
01282 }
01283 
01284 void WMACodec::lspToCurve(float *out, float *val_max_ptr, int n, float *lsp) {
01285     float val_max = 0;
01286 
01287     for (int i = 0; i < n; i++) {
01288         float p = 0.5f;
01289         float q = 0.5f;
01290         float w = _lspCosTable[i];
01291 
01292         for (int j = 1; j < kLSPCoefCount; j += 2) {
01293             q *= w - lsp[j - 1];
01294             p *= w - lsp[j];
01295         }
01296 
01297         p *= p * (2.0f - w);
01298         q *= q * (2.0f + w);
01299 
01300         float v = p + q;
01301         v = pow_m1_4(v);
01302 
01303         if (v > val_max)
01304             val_max = v;
01305 
01306         out[i] = v;
01307     }
01308 
01309     *val_max_ptr = val_max;
01310 }
01311 
01312 // Decode exponents coded with LSP coefficients (same idea as Vorbis)
01313 bool WMACodec::decodeExpLSP(Common::BitStream8MSB &bits, int ch) {
01314     float lspCoefs[kLSPCoefCount];
01315 
01316     for (int i = 0; i < kLSPCoefCount; i++) {
01317         int val;
01318 
01319         if (i == 0 || i >= 8)
01320             val = bits.getBits(3);
01321         else
01322             val = bits.getBits(4);
01323 
01324         lspCoefs[i] = lspCodebook[i][val];
01325     }
01326 
01327     lspToCurve(_exponents[ch], &_maxExponent[ch], _blockLen, lspCoefs);
01328     return true;
01329 }
01330 
01331 bool WMACodec::decodeRunLevel(Common::BitStream8MSB &bits, const HuffmanDecoder &huffman,
01332     const float *levelTable, const uint16 *runTable, int version, float *ptr,
01333     int offset, int numCoefs, int blockLen, int frameLenBits, int coefNbBits) {
01334 
01335     const uint32 *ilvl = (const uint32*) levelTable;
01336     uint32 *iptr = (uint32 *) ptr;
01337 
01338     const unsigned int coefMask = blockLen - 1;
01339 
01340     for (; offset < numCoefs; offset++) {
01341         const int code = huffman.getSymbol(bits);
01342 
01343         if (code > 1) {
01344             // Normal code
01345 
01346             const int sign = bits.getBit() - 1;
01347 
01348             offset += runTable[code];
01349 
01350             iptr[offset & coefMask] = ilvl[code] ^ (sign << 31);
01351 
01352         } else if (code == 1) {
01353             // EOB
01354 
01355             break;
01356 
01357         } else {
01358             // Escape
01359 
01360             int level;
01361 
01362             if (!version) {
01363 
01364                 level   = bits.getBits(coefNbBits);
01365                 // NOTE: This is rather suboptimal. reading blockLenBits would be better
01366                 offset += bits.getBits(frameLenBits);
01367 
01368             } else {
01369                 level = getLargeVal(bits);
01370 
01371                 // Escape decode
01372                 if (bits.getBit()) {
01373                     if (bits.getBit()) {
01374                         if (bits.getBit()) {
01375                             warning("WMACodec::decodeRunLevel(): Broken escape sequence");
01376                             return false;
01377                         } else
01378                             offset += bits.getBits(frameLenBits) + 4;
01379                     } else
01380                         offset += bits.getBits(2) + 1;
01381                 }
01382 
01383             }
01384 
01385             const int sign = bits.getBit() - 1;
01386 
01387             ptr[offset & coefMask] = (level ^ sign) - sign;
01388 
01389         }
01390     }
01391 
01392     // NOTE: EOB can be omitted
01393     if (offset > numCoefs) {
01394         warning("WMACodec::decodeRunLevel(): Overflow in spectral RLE, ignoring");
01395         return true;
01396     }
01397 
01398     return true;
01399 }
01400 
01406 void WMACodec::window(float *out) const {
01407     const float *in = _output;
01408 
01409     // Left part
01410     if (_blockLenBits <= _prevBlockLenBits) {
01411 
01412         const int bSize = _frameLenBits - _blockLenBits;
01413 
01414         vectorFMulAdd(out, in, _mdctWindow[bSize], out, _blockLen);
01415 
01416     } else {
01417 
01418         const int blockLen = 1 << _prevBlockLenBits;
01419         const int n = (_blockLen - blockLen) / 2;
01420 
01421         const int bSize = _frameLenBits - _prevBlockLenBits;
01422 
01423         vectorFMulAdd(out + n, in + n, _mdctWindow[bSize], out + n, blockLen);
01424 
01425         memcpy(out + n + blockLen, in + n + blockLen, n * sizeof(float));
01426     }
01427 
01428     out += _blockLen;
01429     in  += _blockLen;
01430 
01431     // Right part
01432     if (_blockLenBits <= _nextBlockLenBits) {
01433 
01434         const int bSize = _frameLenBits - _blockLenBits;
01435 
01436         vectorFMulReverse(out, in, _mdctWindow[bSize], _blockLen);
01437 
01438     } else {
01439 
01440         const int blockLen = 1 << _nextBlockLenBits;
01441         const int n = (_blockLen - blockLen) / 2;
01442 
01443         const int bSize = _frameLenBits - _nextBlockLenBits;
01444 
01445         memcpy(out, in, n*sizeof(float));
01446 
01447         vectorFMulReverse(out + n, in + n, _mdctWindow[bSize], blockLen);
01448 
01449         memset(out + n + blockLen, 0, n * sizeof(float));
01450     }
01451 }
01452 
01453 float WMACodec::pow_m1_4(float x) const {
01454     union {
01455         float f;
01456         unsigned int v;
01457     } u, t;
01458 
01459     u.f = x;
01460 
01461     const unsigned int e =  u.v >>  23;
01462     const unsigned int m = (u.v >> (23 - kLSPPowBits)) & ((1 << kLSPPowBits) - 1);
01463 
01464     // Build interpolation scale: 1 <= t < 2
01465     t.v = ((u.v << kLSPPowBits) & ((1 << 23) - 1)) | (127 << 23);
01466 
01467     const float a = _lspPowMTable1[m];
01468     const float b = _lspPowMTable2[m];
01469 
01470     return _lspPowETable[e] * (a + b * t.f);
01471 }
01472 
01473 int WMACodec::readTotalGain(Common::BitStream8MSB &bits) {
01474     int totalGain = 1;
01475 
01476     int v = 127;
01477     while (v == 127) {
01478         v = bits.getBits(7);
01479 
01480         totalGain += v;
01481     }
01482 
01483     return totalGain;
01484 }
01485 
01486 int WMACodec::totalGainToBits(int totalGain) {
01487          if (totalGain < 15) return 13;
01488     else if (totalGain < 32) return 12;
01489     else if (totalGain < 40) return 11;
01490     else if (totalGain < 45) return 10;
01491     else                     return  9;
01492 }
01493 
01494 uint32 WMACodec::getLargeVal(Common::BitStream8MSB &bits) {
01495     // Consumes up to 34 bits
01496 
01497     int count = 8;
01498     if (bits.getBit()) {
01499         count += 8;
01500 
01501         if (bits.getBit()) {
01502             count += 8;
01503 
01504             if (bits.getBit())
01505                 count += 7;
01506         }
01507     }
01508 
01509     return bits.getBits(count);
01510 }
01511 
01512 } // End of namespace Audio


Generated on Sat Dec 7 2019 05:00:23 for ResidualVM by doxygen 1.7.1
curved edge   curved edge