static Mdct GetSetup(int n) { lock (_setupCache) { if (!_setupCache.ContainsKey(n)) { _setupCache[n] = new Mdct(n); } return(_setupCache[n]); } }
void DecodePacket() { // inverse coupling var steps = _mode.Mapping.CouplingSteps; var halfSizeW = _mode.BlockSize / 2; for (int i = steps.Length - 1; i >= 0; i--) { if (_floorData[steps[i].Angle].ExecuteChannel || _floorData[steps[i].Magnitude].ExecuteChannel) { var magnitude = _residue[steps[i].Magnitude]; var angle = _residue[steps[i].Angle]; // we only have to do the first half; MDCT ignores the last half for (int j = 0; j < halfSizeW; j++) { float newM, newA; if (magnitude[j] > 0) { if (angle[j] > 0) { newM = magnitude[j]; newA = magnitude[j] - angle[j]; } else { newA = magnitude[j]; newM = magnitude[j] + angle[j]; } } else { if (angle[j] > 0) { newM = magnitude[j]; newA = magnitude[j] + angle[j]; } else { newA = magnitude[j]; newM = magnitude[j] - angle[j]; } } magnitude[j] = newM; angle[j] = newA; } } } // apply floor / dot product / MDCT (only run if we have sound energy in that channel) for (int c = 0; c < _channels; c++) { var floorData = _floorData[c]; var res = _residue[c]; if (floorData.ExecuteChannel) { _mode.Mapping.ChannelSubmap[c].Floor.Apply(floorData, res); Mdct.Reverse(res, _mode.BlockSize); } else { // since we aren't doing the IMDCT, we have to explicitly clear the back half of the block Array.Clear(res, halfSizeW, halfSizeW); } } }