internal PCMStream(WaveInfo* pWAVE, VoidPtr dataAddr) { _frequency = pWAVE->_sampleRate; _numSamples = pWAVE->NumSamples; _numChannels = pWAVE->_format._channels; _bps = pWAVE->_format._encoding == 0 ? 8 : 16; if (_numSamples <= 0) return; _loopStart = (int)pWAVE->LoopSample; _loopEnd = _numSamples; _source = (short*)dataAddr; _samplePos = 0; }
public void Init(VoidPtr strmAddr, int strmLen, WaveInfo* info) { Info = *info; _streamBuffer = new UnsafeBuffer(strmLen); Memory.Move(_streamBuffer.Address, strmAddr, (uint)strmLen); _audioSource = new DataSource(_streamBuffer.Address, _streamBuffer.Length); if (info->_format._encoding == 2) _stream = new ADPCMStream(info, _audioSource.Address); else _stream = new PCMStream(info, _audioSource.Address); }
public ADPCMStream(WaveInfo* pWAVE, VoidPtr dataAddr) { _dataAddress = dataAddr; ADPCMInfo*[] info; int loopBlock, loopChunk; byte* sPtr; info = new ADPCMInfo*[_numChannels = pWAVE->_format._channels]; _currentStates = new ADPCMState[_numChannels]; _loopStates = new ADPCMState[_numChannels]; _isLooped = pWAVE->_format._looped != 0; _sampleRate = pWAVE->_sampleRate; _numSamples = pWAVE->NumSamples; if (_numSamples <= 0) return; _blockLen = (_numSamples.Align(14) / 14 * 8).Align(0x20); _loopStartSample = (int)pWAVE->LoopSample; _loopEndSample = _numSamples; Init(); _blockStates = new ADPCMState[_numChannels, _numBlocks]; loopBlock = _loopStartSample / _samplesPerBlock; loopChunk = (_loopStartSample - (loopBlock * _samplesPerBlock)) / 14; int x = (loopBlock * _blockLen * _numChannels) + (loopChunk * 8); int y = (_loopStartSample / 14 * 8); sPtr = (byte*)dataAddr + x; //Get channel info for (int i = 0; i < _numChannels; i++) //{ // //sPtr = (byte*)dataAddr + pWAVE->GetChannelInfo(i)->_channelDataOffset + loopStart; info[i] = pWAVE->GetADPCMInfo(i); // //Fill loop state // _loopStates[i] = new ADPCMState(sPtr, info[i]->_lps, info[i]->_lyn1, info[i]->_lyn2, info[i]->Coefs); // //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++) { //sPtr = (byte*)dataAddr + pWAVE->GetChannelInfo(cIndex)->_channelDataOffset; //Get block state ADPCMInfo* i = info[cIndex]; _blockStates[cIndex, bIndex] = new ADPCMState(sPtr, i->_ps, i->_yn1, i->_yn2, i->_lps, i->_lyn1, i->_lyn2, i->Coefs); //Use ps from data stream //Advance address sPtr += (bIndex == _numBlocks - 1) ? _lastBlockSize : _blockLen; } }