예제 #1
0
        public void Read(BinaryReader br)
        {
            // Read header

            _fileHeader = new Header(br);

            bool errorCondition = false;

            if (!(_fileHeader.numBlocks > 0)) errorCondition = true;
            if (!(_fileHeader.sizeBlock > 0)) errorCondition = true;
            if (_fileHeader.numBlocks * _fileHeader.sizeBlock > br.BaseStream.Length) errorCondition = true;
            if (_fileHeader.offsetBlockInfo > _fileHeader.sizeHeader) errorCondition = true;

            if (errorCondition)
            {
                throw new SoundBankException("Unexpected values in Header");
            }

            // read adpcm state info

            br.BaseStream.Seek(_fileHeader.offsetChannelInfo, SeekOrigin.Begin);
            _channelInfoHeader = new ChannelInfoHeader[_fileHeader.numChannels];
            for (int i = 0; i < _fileHeader.numChannels; i++)
            {
                _channelInfoHeader[i] = new ChannelInfoHeader(br);
            }
            
            _channelInfo = new ChannelInfo[_fileHeader.numChannels];
            var currentOffset = br.BaseStream.Position;

            for (int i = 0; i < _fileHeader.numChannels; i++)
            {
                br.BaseStream.Seek(currentOffset + _channelInfoHeader[i].offset, SeekOrigin.Begin);
                _channelInfo[i] = new ChannelInfo(br);

                if (_channelInfoHeader[i].size <= 36)
                {
                    _isCompressed = false;
                }
                else
                {
                    _channelInfo[i].adpcmInfo = new AdpcmInfo(br);
                }
            }

            // Read comp block info (in header)
            br.BaseStream.Seek(_fileHeader.offsetBlockInfo, SeekOrigin.Begin);
            _blockInfoHeader = new BlockInfoHeader[_fileHeader.numBlocks];
            for (int i = 0; i < _fileHeader.numBlocks; i++)
            {
                _blockInfoHeader[i] = new BlockInfoHeader(br);
            }

            // Read comp block info / channel info
            _blockInfo = new BlockInfo[_fileHeader.numBlocks];
            for (int i = 0; i < _fileHeader.numBlocks; i++)
            {
                var computedOffset = _fileHeader.sizeHeader + _fileHeader.sizeBlock*i;
                br.BaseStream.Seek(computedOffset, SeekOrigin.Begin);

                _blockInfo[i] = new BlockInfo(br);
                _blockInfo[i].computed_offset = computedOffset;

                _blockInfo[i].channelInfo = new BlockChannelInfo[_fileHeader.numChannels];
                int numCodeIndices = 0;
                for(int j=0; j<_fileHeader.numChannels; j++)
                {
                    _blockInfo[i].channelInfo[j] = new BlockChannelInfo(br);
                    
                    int end = _blockInfo[i].channelInfo[j].startIndex + _blockInfo[i].channelInfo[j].count;
                    if (numCodeIndices < end)
                    {
                        numCodeIndices = end;
                    }
                }

                _blockInfo[i].codeIndices = new CodeIndices[numCodeIndices];
                for (int j = 0; j < numCodeIndices; j++)
                {
                    _blockInfo[i].codeIndices[j] = new CodeIndices(br);
                    _blockInfo[i].codeIndices[j].computed_channel = -1;

                    if (_isCompressed)
                    {
                        _blockInfo[i].codeIndices[j].computed_adpcmIndex = _blockInfo[i].codeIndices[j].startIndex/
                                                                            4096;
                    }
                }

                for (int j = 0; j < _fileHeader.numChannels; j++)
                {
                    int channelIdxStart = _blockInfo[i].channelInfo[j].startIndex;
                    int channelIdxCount = _blockInfo[i].channelInfo[j].count;
                    for (int k = 0; k < channelIdxCount; k++)
                    {
                        _blockInfo[i].codeIndices[k + channelIdxStart].computed_channel = j;
                    }
                }

                int new_start =
                    (int) (Math.Ceiling((float) (_blockInfo[i].offset2 + 8*numCodeIndices)/BlockSize)*BlockSize);
                _sizeBlockHeader = Math.Max(_sizeBlockHeader, new_start);
            }

            _waveInfos = new List<ISoundWave>(_fileHeader.numChannels);
            for (int i = 0; i < _fileHeader.numChannels; i++)
            {
                _waveInfos.Add( new SoundWave(_fileHeader, _channelInfo[i]) );
            }

            _supportsMultichannelExport = ReorganizeForMultiChannelWave();
        }
예제 #2
0
 public SoundWave(Header header, ChannelInfo channelInfo)
 {
     _header = header;
     _channelInfo = channelInfo;
 }