public int ExportWaveBlockAsPCM(int waveIndex, int blockIndex, ref DviAdpcmDecoder.AdpcmState state, Stream soundBankStream, Stream outStream) { int samplesWritten = 0; WaveInfo waveInfo = _waveInfos[waveIndex]; BinaryWriter bw = new BinaryWriter(outStream); byte[] block = new byte[2048]; int blockSize = 2048; if (blockIndex == (waveInfo.numSamplesInBytes_computed / blockSize) - 1) { // Last block blockSize = waveInfo.numSamplesInBytes % blockSize; } if (waveInfo.states != null && blockIndex < waveInfo.states.Length) { state = waveInfo.states[blockIndex]; } soundBankStream.Seek(Header.headerSize + waveInfo.offset + blockIndex * 2048, SeekOrigin.Begin); soundBankStream.Read(block, 0, blockSize); int nibblePairCount = 0; while (nibblePairCount < blockSize) { if (waveInfo.is_compressed) { bw.Write(DviAdpcmDecoder.DecodeAdpcm((byte)(block[nibblePairCount] & 0xf), ref state)); bw.Write(DviAdpcmDecoder.DecodeAdpcm((byte)((block[nibblePairCount] >> 4) & 0xf), ref state)); samplesWritten += 2; nibblePairCount++; } else { bw.Write(BitConverter.ToInt16(block, nibblePairCount)); samplesWritten++; nibblePairCount += 2; } } return(samplesWritten * 2); // byte size }
public int ExportWaveBlockAsPCM(int waveIndex, int blockIndex, ref DviAdpcmDecoder.AdpcmState state, Stream soundBankStream, Stream outStream) { // waveIndex would be the channel here... // blockIndex is the real block index BinaryWriter writer = new BinaryWriter(outStream); long offset = _blockInfo[blockIndex].computed_offset + _sizeBlockHeader; soundBankStream.Seek(offset, SeekOrigin.Begin); if (_isCompressed) { for (int i = 0; i < _blockInfo[blockIndex].codeIndices.Length; i++) { int currentChannel = _blockInfo[blockIndex].codeIndices[i].computed_channel; if (currentChannel == waveIndex) { int adpcmIndex = _blockInfo[blockIndex].codeIndices[i].computed_adpcmIndex; if (adpcmIndex < _channelInfo[currentChannel].adpcmInfo.states.Length) { state = _channelInfo[currentChannel].adpcmInfo.states[adpcmIndex]; } byte[] buffer = new byte[BlockSize]; soundBankStream.Read(buffer, 0, BlockSize); for (int j = 0; j < BlockSize; j++) { byte code = buffer[j]; writer.Write(DviAdpcmDecoder.DecodeAdpcm((byte)(code & 0xf), ref state)); writer.Write(DviAdpcmDecoder.DecodeAdpcm((byte)((code >> 4) & 0xf), ref state)); } } else { soundBankStream.Seek(2048, SeekOrigin.Current); } } } else { for (int i = 0; i < _blockInfo[blockIndex].codeIndices.Length; i++) { int currentChannel = _blockInfo[blockIndex].codeIndices[i].computed_channel; if (currentChannel == waveIndex) { short[] block = new short[BlockSize / 2]; // all the seeking is done here... soundBankStream.Seek(_blockInfo[blockIndex].computed_offset + i * BlockSize + _sizeBlockHeader, SeekOrigin.Begin); for (int j = 0; j < BlockSize / 2; j++) { byte[] b = new byte[2]; soundBankStream.Read(b, 0, 2); block[j] = BitConverter.ToInt16(b, 0); } // this adjusts for weird values in codeIndices. if (_blockInfo[blockIndex].channelInfo[currentChannel].offsetIntoCodeBlockIndices < 0) { _blockInfo[blockIndex].codeIndices[i].startIndex -= _blockInfo[blockIndex].channelInfo[currentChannel].offsetIntoCodeBlockIndices; _blockInfo[blockIndex].channelInfo[currentChannel].offsetIntoCodeBlockIndices = 0; } else if (_blockInfo[blockIndex].channelInfo[currentChannel].offsetIntoCodeBlockIndices > 0) { int len = _blockInfo[blockIndex].channelInfo[currentChannel].offsetIntoCodeBlockIndices; short[] newblock = new short[BlockSize / 2 - len]; Array.Copy(block, len, newblock, 0, BlockSize / 2 - len); block = newblock; _blockInfo[blockIndex].channelInfo[currentChannel].offsetIntoCodeBlockIndices = 0; } int count = _blockInfo[blockIndex].codeIndices[i].endIndex - _blockInfo[blockIndex].codeIndices[i].startIndex; for (int j = 0; j <= count; j++) { writer.Write(block[j]); } } } } return(0); }