public void ExportAsPCM(int index, Stream soundBankStream, Stream outStream) { int count = _fileHeader.numBlocks; DviAdpcmDecoder.AdpcmState state = new DviAdpcmDecoder.AdpcmState(); for (int k = 0; k < count; k++) { ExportWaveBlockAsPCM(index, k, ref state, soundBankStream, outStream); } }
public void ExportAsPCM(int index, Stream soundBankStream, Stream outStream) { WaveInfo waveInfo = _waveInfos[index]; int count = waveInfo.numSamplesInBytes_computed / 2048; DviAdpcmDecoder.AdpcmState state = new DviAdpcmDecoder.AdpcmState(); for (int k = 0; k < count; k++) { ExportWaveBlockAsPCM(index, k, ref state, soundBankStream, outStream); } }
public void Initialize(AudioFile file, AudioWave wave) { _file = file; _wave = wave; _format = new WaveFormat(_wave.SamplesPerSecond, 16, 1); _lastBlock = -1; _looped = false; _state = new DviAdpcmDecoder.AdpcmState(); _leftOverBuffer = null; }
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 void ExportMultichannelAsPCM(Stream soundBankStream, Stream outStream) { int numBlocks = _fileHeader.numBlocks; int numChannels = _fileHeader.numChannels; DviAdpcmDecoder.AdpcmState[] state = new DviAdpcmDecoder.AdpcmState[numChannels]; BinaryWriter bw = new BinaryWriter(outStream); int[] inverseChannelOrder = new int[numChannels]; for (int i = 0; i < numChannels; i++) { inverseChannelOrder[_channelOrder[i]] = i; } for (int i = 0; i < numChannels; i++) { state[i] = new DviAdpcmDecoder.AdpcmState(); } for (int blockIndex = 0; blockIndex < numBlocks; blockIndex++) { byte[][] blockData = new byte[numChannels][]; // Decode the block for all channels for (int channelIndex = 0; channelIndex < numChannels; channelIndex++) { MemoryStream ms = new MemoryStream(); ExportWaveBlockAsPCM(channelIndex, blockIndex, ref state[channelIndex], soundBankStream, ms); blockData[channelIndex] = ms.ToArray(); } // Now interleave them for (int j = 0; j < blockData[0].Length / 2; j++) { for (int i = 0; i < numChannels; i++) { bw.Write(blockData[inverseChannelOrder[i]][j * 2 + 0]); bw.Write(blockData[inverseChannelOrder[i]][j * 2 + 1]); } } } }
public void ExportMultichannelAsPCM(Stream soundBankStream, Stream outStream) { int numBlocks = _fileHeader.numBlocks; int numChannels = _fileHeader.numChannels; DviAdpcmDecoder.AdpcmState[] state = new DviAdpcmDecoder.AdpcmState[numChannels]; BinaryWriter bw = new BinaryWriter(outStream); int[] inverseChannelOrder = new int[numChannels]; for (int i = 0; i < numChannels; i++) { inverseChannelOrder[_channelOrder[i]] = i; } for (int i = 0; i < numChannels; i++) { state[i] = new DviAdpcmDecoder.AdpcmState(); } for (int blockIndex = 0; blockIndex < numBlocks; blockIndex++) { byte[][] blockData = new byte[numChannels][]; // Decode the block for all channels for (int channelIndex = 0; channelIndex < numChannels; channelIndex++) { MemoryStream ms = new MemoryStream(); ExportWaveBlockAsPCM(channelIndex, blockIndex, ref state[channelIndex], soundBankStream, ms); blockData[channelIndex] = ms.ToArray(); } // Now interleave them for (int j = 0; j < blockData[0].Length / 2; j++) { for (int i = 0; i < numChannels; i++) { bw.Write(blockData[inverseChannelOrder[i]][j*2 + 0]); bw.Write(blockData[inverseChannelOrder[i]][j*2 + 1]); } } } }
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); }
private void Filler(IntPtr data, int size) { int blockCount = _wave.BlockCount; byte[] b = new byte[size]; if (_file != null && (_looped || _lastBlock < blockCount)) { MemoryStream ms = new MemoryStream(); if (_leftOverBuffer != null) { ms.Write(_leftOverBuffer, 0, _leftOverBuffer.Length); } while (ms.Position < size) { _lastBlock++; if (_lastBlock >= blockCount) { if (!_looped) { while(ms.Position < size) { ms.WriteByte(0); } break; } else { _lastBlock = 0; _state = new DviAdpcmDecoder.AdpcmState(); } } _file.SoundBank.ExportWaveBlockAsPCM(_wave.Index, _lastBlock, ref _state, _file.Stream, ms); } int extraData = (int)(ms.Position - size); ms.Seek(0, SeekOrigin.Begin); ms.Read(b, 0, size); if (extraData > 0) { _leftOverBuffer = new byte[extraData]; ms.Read(_leftOverBuffer, 0, extraData); } else { _leftOverBuffer = null; } } else { for (int i = 0; i < b.Length; i++) { b[i] = 0; } } System.Runtime.InteropServices.Marshal.Copy(b, 0, data, size); }
public void Play(bool looped) { try { Stop(); _looped = looped; _lastBlock = -1; _state = new DviAdpcmDecoder.AdpcmState(); _player = new WaveOutPlayer(-1, _format, _wave.BlockSize * 4, 3, Filler); _leftOverBuffer = null; } catch { MessageBox.Show("Audio play error.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }