Nanook.TheGhost.DatWad.ReplaceFsbFileWithWav C# (CSharp) Method

ReplaceFsbFileWithWav() public method

public ReplaceFsbFileWithWav ( DatItem item, string wavFilename ) : void
item DatItem
wavFilename string
return void
        public void ReplaceFsbFileWithWav(DatItem item, string wavFilename)
        {
            string tempWadFn = string.Format("{0}_{1}", _wadFilename, Guid.NewGuid().ToString("N"));

            byte[] buff;
            int filenameLen = 30;
            uint fileSize = 0;
            int diff;

            //save WAD to temp file
            using (FileStream fso = File.OpenWrite(tempWadFn))
            {
                using (FileStream fsi = File.OpenRead(_wadFilename))
                {
                    if (item.FileOffset != 0)
                        copy(fsi, fso, item.FileOffset);

                    using (FileStream fs = File.OpenRead(wavFilename))
                    {
                        //not fully correct for XBADPCM
                        WavSingleChunkHeader wh = WavProcessor.ParseWavSingleChunkHeader(fs);

                        long p = fso.Position;

                        BinaryEndianWriter bw = new BinaryEndianWriter(fso);

                        byte[] fsbFilename = new byte[filenameLen];

                        //http://www.fmod.org/forum/viewtopic.php?t=1551

                        //FileHeader

                        bw.Write(Encoding.Default.GetBytes("FSB3"));
                        bw.Write((uint)1, EndianType.Little); //1 sample in file
                        bw.Write((uint)80, EndianType.Little); //sampleheader length
                        bw.Write(wh.ChunkLength, EndianType.Little); //sampleheader length
                        bw.Write((uint)0x00030001, EndianType.Little); //header version 3.1
                        bw.Write((uint)0, EndianType.Little); //global mode flags

                        //p = fso.Position;

                        //SampleHeader (80 byte version)
                        bw.Write((UInt16)80, EndianType.Little); //sampleheader length
                        fsi.Seek(24 + 2, SeekOrigin.Current); //skip the start of the source fsb file name
                        fsi.Read(fsbFilename, 0, filenameLen);  //read filename from file being replaced
                        bw.Write(fsbFilename); //write filename

                        //sampleheader length (What's this about?)
                        uint lenSamp = (uint)Math.Round(((double)wh.SamplesPerSec / (double)wh.AvgBytesPerSec) * wh.ChunkLength);
                        if (lenSamp < 0xFA00)
                            lenSamp = 0xFA00; //set smallest allowed size? May be a memory allocation thing for FSB

                        bw.Write(lenSamp, EndianType.Little); //sampleheader length
                        bw.Write(wh.ChunkLength, EndianType.Little); //compressed bytes
                        bw.Write((uint)0x0, EndianType.Little); //loop start
                        bw.Write(lenSamp - 1, EndianType.Little); //loop end
                        bw.Write((uint)0x20400040, EndianType.Little); //sample mode
                        bw.Write(wh.SamplesPerSec, EndianType.Little); //frequency
                        bw.Write((ushort)0xFF, EndianType.Little); //default volume
                        bw.Write((ushort)0x0080, EndianType.Little); //default pan
                        bw.Write((ushort)0x0080, EndianType.Little); //default pri
                        bw.Write(wh.Channels, EndianType.Little); //channels
                        bw.Write((float)1, EndianType.Little); //min distance
                        bw.Write((float)10000, EndianType.Little); //max distance
                        bw.Write((uint)0x0, EndianType.Little); //varfreq
                        bw.Write((ushort)0x0, EndianType.Little); //varvol
                        bw.Write((ushort)0x0, EndianType.Little); //varpan

                        copy(fs, fso, wh.ChunkLength);
                        fileSize = (uint)(24 + 80 + wh.ChunkLength);

                        if (fileSize % DatWad.FileAlignment != 0)
                        {
                            buff = new byte[DatWad.FileAlignment - (fileSize % DatWad.FileAlignment)];
                            for (int i = 0; i < buff.Length; i++)
                                buff[i] = DatWad.FileAlignmentPadValue;
                            fso.Write(buff, 0, buff.Length);
                        }

                        //move past the rest of this file being replaced
                        long itemSize = item.FileSize;
                        if (item.FileSize % DatWad.FileAlignment != 0)
                            itemSize += (DatWad.FileAlignment - (item.FileSize % DatWad.FileAlignment));

                        if (itemSize < fsi.Length)
                            fsi.Seek(itemSize - (24 + 2 + filenameLen), SeekOrigin.Current);

                    }

                    diff = (int)(fso.Position - fsi.Position);

                    //copy the rest of the file
                    copy(fsi, fso, fsi.Length - fsi.Position);
                }
                fso.Flush();
            }

            //rename the temp wad file
            FileHelper.Delete(_wadFilename);

            //save dat headers
            //int diff = (int)fileSize - (int)item.FileSize;
            foreach (DatItem di in _datItems.Values)
            {
                if (di == item)
                    di.FileSize = fileSize;
                else
                    di.FileOffset = (uint)((int)di.FileOffset + (di.FileOffset > item.FileOffset ? diff : 0));
            }
            _headerFileSize = (uint)((int)_headerFileSize + diff);
            this.save();

            File.Move(tempWadFn, _wadFilename);
        }