public ADPCMStream(RSTMHeader* pRSTM, int channels, int startChannel, VoidPtr dataAddr) { HEADHeader* pHeader = pRSTM->HEADData; StrmDataInfo* part1 = pHeader->Part1; bshort* ynCache = (bshort*)pRSTM->ADPCData->Data; byte* sPtr; short[][] coefs; ADPCMInfo* info; int loopBlock, loopChunk; short yn1 = 0, yn2 = 0; _numChannels = part1->_format._channels; _isLooped = part1->_format._looped != 0; _sampleRate = part1->_sampleRate; _numSamples = part1->_numSamples; _numBlocks = part1->_numBlocks; _blockLen = part1->_blockSize; _loopStartSample = part1->_loopStartSample; _lastBlockSamples = part1->_lastBlockSamples; _lastBlockSize = part1->_lastBlockTotal; _samplesPerBlock = part1->_samplesPerBlock; _loopEndSample = _numSamples; _blockStates = new ADPCMState[_numChannels, _numBlocks]; _currentStates = new ADPCMState[_numChannels]; _loopStates = new ADPCMState[_numChannels]; coefs = new short[_numChannels][]; loopBlock = _loopStartSample / _samplesPerBlock; loopChunk = (_loopStartSample - (loopBlock * _samplesPerBlock)) / 14; sPtr = (byte*)dataAddr + (loopBlock * _blockLen * _numChannels) + (loopChunk * 8); //Get channel info for (int i = 0; i < _numChannels; i++) { info = pHeader->GetChannelInfo(i); //Get channel coefs coefs[i] = info->Coefs; //Fill loop state _loopStates[i] = new ADPCMState(sPtr, info->_lps, info->_lyn1, info->_lyn2, coefs[i]); //Advance source pointer for next channel sPtr += _blockLen; } //Fill block states in a linear fashion sPtr = (byte*)dataAddr; for (int sIndex = 0, bIndex = 0; sIndex < _numSamples; sIndex += _samplesPerBlock, bIndex++) for (int cIndex = 0; cIndex < _numChannels; cIndex++) { if (bIndex > 0) //yn values will be zero if first block { yn1 = *ynCache++; yn2 = *ynCache++; } //Get block state _blockStates[cIndex, bIndex] = new ADPCMState(sPtr, *sPtr, yn1, yn2, coefs[cIndex]); //Use ps from data stream //Advance address sPtr += (bIndex == _numBlocks - 1) ? _lastBlockSize : _blockLen; } _numChannels = channels; _startChannel = startChannel; }
public static ADPCMStream[] GetStreams(RSTMHeader* pRSTM, VoidPtr dataAddr) { HEADHeader* pHeader = pRSTM->HEADData; StrmDataInfo* part1 = pHeader->Part1; int c = part1->_format._channels; ADPCMStream[] streams = new ADPCMStream[c.RoundUpToEven() / 2]; for (int i = 0; i < streams.Length; i++) { int x = (i + 1) * 2 <= c ? 2 : 1; streams[i] = new ADPCMStream(pRSTM, x, i * 2, dataAddr); } return streams; }