예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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;
        }
예제 #4
0
        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
        }
예제 #5
0
        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]);
                    }
                }
            }
        }
예제 #6
0
        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]);
                    }
                }
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
            }
        }
예제 #10
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);
        }
예제 #11
0
        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);
            }
        }