예제 #1
0
        /// <summary>
        /// Update the file.
        /// </summary>
        public void Update(UInt16 endian)
        {
            //Update info.
            info.magic = "INFO".ToCharArray();
            info.streamSoundInfoRef = new Reference(ReferenceTypes.STRM_Info_StreamSound, 0x18);

            //Stream sound info.
            UInt32 infoBaseOffet = 0x18;

            info.streamSoundInfo.channelCount       = (byte)info.channels.Count;
            info.streamSoundInfo.regionCount        = (byte)(region != null ? region.regions.Length : 0);
            info.streamSoundInfo.regionDataOffset   = new Reference(0, 0x18);
            info.streamSoundInfo.regionInfoBytesize = 0x100;
            info.streamSoundInfo.sampleDataOffset   = new Reference(ReferenceTypes.General_ByteStream, 0x18);
            info.streamSoundInfo.padding            = 0;
            info.streamSoundInfo.sizeOfSeekInfo     = 4;

            infoBaseOffet += 56;
            if (fileHeader.vMajor >= regionInfo)
            {
                infoBaseOffet += 12;
            }
            if (fileHeader.vMajor >= originalLoopInfo)
            {
                infoBaseOffet += 8;
            }
            if (fileHeader.vMajor >= secretInfo)
            {
                infoBaseOffet += 4;
            }

            //Reference table for track info ref.
            info.trackInfoTableRef = new Reference(0x0101, (int)infoBaseOffet);

            //Skip ref table coords.
            infoBaseOffet += (uint)(info.tracks != null ? (info.tracks.Count * 8 + 4) : 0);

            info.channelInfoTableRef = new Reference(0x0101, (int)infoBaseOffet);

            List <Reference> trackRefs = new List <Reference>();

            //Track info.
            UInt32 trackBaseOffset = (uint)((info.tracks != null ? (info.tracks.Count * 8 + 4) : 0) + (info.channels.Count * 8 + 4));

            if (info.tracks != null)
            {
                for (int i = 0; i < info.tracks.Count; i++)
                {
                    trackRefs.Add(new Reference(ReferenceTypes.STRM_Info_Track, (int)trackBaseOffset));

                    infoBaseOffet   += 12;
                    trackBaseOffset += 12;
                    if (info.tracks[i].globalChannelIndexTable != null)
                    {
                        info.tracks[i].globalChannelIndexTableRef    = new Reference(0x100, 0xC);
                        info.tracks[i].globalChannelIndexTable.count = (uint)info.tracks[i].globalChannelIndexTable.entries.Count;
                        infoBaseOffet   += 4 + info.tracks[i].globalChannelIndexTable.count;
                        trackBaseOffset += 4 + info.tracks[i].globalChannelIndexTable.count;
                        while (infoBaseOffet % 4 != 0)
                        {
                            infoBaseOffet++;
                            trackBaseOffset++;
                        }
                    }
                    else
                    {
                        info.tracks[i].globalChannelIndexTableRef = new Reference(0, Reference.NULL_PTR);
                    }
                }
                info.trackInfoRefTable = new ReferenceTable(trackRefs);
            }
            else
            {
                info.trackInfoTableRef = new Reference(0, Reference.NULL_PTR);
                info.trackInfoRefTable = null;
            }

            //Channel info.
            UInt32 channelBaseOffset = (uint)(4 + 8 * info.channels.Count() + trackBaseOffset - ((uint)((info.tracks != null ? (info.tracks.Count * 8 + 4) : 0) + (info.channels.Count * 8 + 4))));

            infoBaseOffet += (uint)(4 + 8 * info.channels.Count());
            List <Reference> channelRefs = new List <Reference>();

            for (int i = 0; i < info.channels.Count; i++)
            {
                channelRefs.Add(new Reference(ReferenceTypes.STRM_Info_Channel, (int)channelBaseOffset));
                channelBaseOffset += 8;
                infoBaseOffet     += 8;
            }

            info.channelInfoRefTable = new ReferenceTable(channelRefs);

            channelBaseOffset = (uint)(8 * info.channels.Count());
            for (int i = 0; i < info.channels.Count; i++)
            {
                info.channels[i].dspAdpcmInfoRef = new Reference(0, Reference.NULL_PTR);
                if (info.channels[i].dspAdpcmInfo != null)
                {
                    info.channels[i].dspAdpcmInfoRef = new Reference(0x300, (int)channelBaseOffset);
                    channelBaseOffset += 0x2E;
                    infoBaseOffet     += 0x2E;
                }
                channelBaseOffset -= 8;
            }

            //Make offsets, depeding on what blocks exist, and on the sizes of the blocks.
            List <SizedReference> blocks = new List <SizedReference>();

            //Can't forget about magic and size.
            infoBaseOffet += 8;

            while (infoBaseOffet % 0x20 != 0)
            {
                infoBaseOffet++;
            }
            info.blockSize = infoBaseOffet;

            blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Info, 0, info.blockSize));
            if (seek != null)
            {
                blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Seek, (int)info.blockSize, seek.GetSize()));
            }
            if (region != null)
            {
                blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Region, (int)info.blockSize + (seek != null ? (int)seek.GetSize() : 0), region.GetSize()));
            }
            blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Data, (int)info.blockSize + (seek != null ? (int)seek.GetSize() : 0) + (region != null ? (int)region.GetSize() : 0), data.GetSize(info.streamSoundInfo.encoding, ref info)));

            fileHeader = new FileHeader(endian == ByteOrder.LittleEndian ? "CSTM" : "FSTM", endian, fileHeader.vMajor, fileHeader.vMinor, fileHeader.vRevision, (uint)(info.blockSize + (seek != null ? (int)seek.GetSize() : 0) + (region != null ? (int)region.GetSize() : 0) + data.GetSize(info.streamSoundInfo.encoding, ref info)), blocks);

            if (region == null)
            {
                info.streamSoundInfo.regionDataOffset = new Reference(0, Reference.NULL_PTR);
            }

            //Update stuff.
            MemoryStream     o  = new MemoryStream();
            BinaryDataWriter bw = new BinaryDataWriter(o);

            if (seek != null)
            {
                seek.Write(ref bw, fileHeader);
            }
            if (region != null)
            {
                region.Write(ref bw);
            }
            data.WriteSTM(ref bw, info, info.streamSoundInfo.sampleCount);
        }
예제 #2
0
        /// <summary>
        /// Load a file.
        /// </summary>
        /// <param name="b">The file.</param>
        public void Load(byte[] b)
        {
            //Set up the reader.
            MemoryStream     src = new MemoryStream(b);
            BinaryDataReader br  = new BinaryDataReader(src);

            //Read the header.
            fileHeader = new FileHeader(ref br);

            //Read blocks.
            foreach (SizedReference s in fileHeader.blockOffsets)
            {
                if (s.offset != Reference.NULL_PTR)
                {
                    br.Position = s.offset;
                    switch (s.typeId)
                    {
                    //Info block.
                    case ReferenceTypes.STRM_Block_Info:
                        long basePos = br.Position + 8;
                        info = new InfoBlock()
                        {
                            magic               = br.ReadChars(4),
                            blockSize           = br.ReadUInt32(),
                            streamSoundInfoRef  = new Reference(ref br),
                            trackInfoTableRef   = new Reference(ref br),
                            channelInfoTableRef = new Reference(ref br),
                            streamSoundInfo     = null,
                            trackInfoRefTable   = null,
                            channelInfoRefTable = null,
                            tracks              = null,
                            channels            = null
                        };

                        //Stream sound info.
                        if (info.streamSoundInfoRef.typeId == ReferenceTypes.STRM_Info_StreamSound && info.streamSoundInfoRef.offset != Reference.NULL_PTR)
                        {
                            br.Position          = basePos + info.streamSoundInfoRef.offset;
                            info.streamSoundInfo = new StreamSoundInfo()
                            {
                                encoding                = br.ReadByte(),
                                isLoop                  = br.ReadBoolean(),
                                channelCount            = br.ReadByte(),
                                regionCount             = br.ReadByte(),
                                sampleRate              = br.ReadUInt32(),
                                loopStart               = br.ReadUInt32(),
                                sampleCount             = br.ReadUInt32(),
                                blockCount              = br.ReadUInt32(),
                                oneBlockBytesize        = br.ReadUInt32(),
                                oneBlockSamples         = br.ReadUInt32(),
                                lastBlockBytesize       = br.ReadUInt32(),
                                lastBlockSamples        = br.ReadUInt32(),
                                lastBlockPaddedBytesize = br.ReadUInt32(),
                                sizeOfSeekInfo          = br.ReadUInt32(),
                                seekInfoIntervalSamples = br.ReadUInt32(),
                                sampleDataOffset        = new Reference(ref br),
                                regionInfoBytesize      = 0x100,
                                padding                 = 0,
                                regionDataOffset        = new Reference(0, 0x18),
                                originalLoopStart       = 0,
                                originalLoopEnd         = 0,
                                secretInfo              = 0
                            };

                            if (fileHeader.vMajor >= regionInfo)
                            {
                                info.streamSoundInfo.regionInfoBytesize = br.ReadUInt16();
                                info.streamSoundInfo.padding            = br.ReadUInt16();
                                info.streamSoundInfo.regionDataOffset   = new Reference(ref br);
                            }

                            if (fileHeader.vMajor >= originalLoopInfo)
                            {
                                info.streamSoundInfo.originalLoopStart = br.ReadUInt32();
                                info.streamSoundInfo.originalLoopEnd   = br.ReadUInt32();
                            }

                            if (fileHeader.vMajor >= secretInfo)
                            {
                                info.streamSoundInfo.secretInfo = br.ReadUInt32();
                            }
                        }

                        //Track info.
                        if (info.trackInfoTableRef.typeId == ReferenceTypes.Tables + 1 && info.trackInfoTableRef.offset != Reference.NULL_PTR)
                        {
                            br.Position = basePos + info.trackInfoTableRef.offset;
                            long newPos = br.Position;
                            info.trackInfoRefTable = new ReferenceTable(ref br);

                            //Get tracks.
                            info.tracks = new List <TrackInfo>();
                            foreach (Reference r in info.trackInfoRefTable.references)
                            {
                                TrackInfo t = null;
                                if (r.typeId == ReferenceTypes.STRM_Info_Track && r.offset != Reference.NULL_PTR)
                                {
                                    br.Position = newPos + r.offset;
                                    t           = new TrackInfo()
                                    {
                                        volume       = br.ReadByte(),
                                        pan          = br.ReadByte(),
                                        span         = br.ReadByte(),
                                        surroundMode = br.ReadByte(),
                                        globalChannelIndexTableRef = new Reference(ref br),
                                        globalChannelIndexTable    = null
                                    };

                                    if (t.globalChannelIndexTableRef.offset != Reference.NULL_PTR)
                                    {
                                        br.Position = newPos + r.offset + t.globalChannelIndexTableRef.offset;
                                        t.globalChannelIndexTable         = new Table <byte>();
                                        t.globalChannelIndexTable.count   = br.ReadUInt32();
                                        t.globalChannelIndexTable.entries = new List <byte>();
                                        for (int i = 0; i < t.globalChannelIndexTable.count; i++)
                                        {
                                            t.globalChannelIndexTable.entries.Add(br.ReadByte());
                                        }
                                    }
                                }
                                info.tracks.Add(t);
                            }
                        }

                        //Channel info.
                        if (info.channelInfoTableRef.typeId == ReferenceTypes.Tables + 1 && info.channelInfoTableRef.offset != Reference.NULL_PTR)
                        {
                            br.Position = basePos + info.channelInfoTableRef.offset;
                            long newPos = br.Position;
                            info.channelInfoRefTable = new ReferenceTable(ref br);

                            //Get channels.
                            info.channels = new List <ChannelInfo>();
                            foreach (Reference r in info.channelInfoRefTable.references)
                            {
                                ChannelInfo c = null;
                                if (r.offset != Reference.NULL_PTR)
                                {
                                    br.Position = newPos + r.offset;
                                    c           = new ChannelInfo()
                                    {
                                        dspAdpcmInfoRef = new Reference(ref br),
                                        dspAdpcmInfo    = null
                                    };

                                    if (c.dspAdpcmInfoRef.offset != Reference.NULL_PTR)
                                    {
                                        br.Position    = newPos + r.offset + c.dspAdpcmInfoRef.offset;
                                        c.dspAdpcmInfo = new DspAdpcmInfo();
                                        c.dspAdpcmInfo = new DspAdpcmInfo()
                                        {
                                            coefs = new short[8][]
                                        };
                                        c.dspAdpcmInfo.coefs[0]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.coefs[1]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.coefs[2]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.coefs[3]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.coefs[4]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.coefs[5]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.coefs[6]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.coefs[7]        = br.ReadInt16s(2);
                                        c.dspAdpcmInfo.pred_scale      = br.ReadUInt16();
                                        c.dspAdpcmInfo.yn1             = br.ReadInt16();
                                        c.dspAdpcmInfo.yn2             = br.ReadInt16();
                                        c.dspAdpcmInfo.loop_pred_scale = br.ReadUInt16();
                                        c.dspAdpcmInfo.loop_yn1        = br.ReadInt16();
                                        c.dspAdpcmInfo.loop_yn2        = br.ReadInt16();
                                    }
                                }
                                info.channels.Add(c);
                            }
                        }

                        break;

                    //Seek block.
                    case ReferenceTypes.STRM_Block_Seek:
                        seek = new SoundNStreamSeekBlock(ref br, info.streamSoundInfo, fileHeader);
                        break;

                    //Region block.
                    case ReferenceTypes.STRM_Block_Region:
                        region = new SoundNStreamRegionBlock(ref br, info.streamSoundInfo);
                        break;

                    //Data block.
                    case ReferenceTypes.STRM_Block_Data:
                        data = new SoundNStreamDataBlock(ref br, info);
                        break;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Load a file.
        /// </summary>
        /// <param name="b">The file.</param>
        public void Load(byte[] b)
        {
            //Set up the reader.
            MemoryStream     src = new MemoryStream(b);
            BinaryDataReader br  = new BinaryDataReader(src);

            //Read file header.
            fileHeader = new FileHeader(ref br);

            //Read info block.
            info = null;
            if (fileHeader.blockOffsets[0].offset != Reference.NULL_PTR && fileHeader.blockOffsets[0].typeId == ReferenceTypes.WAV_Block_Info)
            {
                br.Position = fileHeader.blockOffsets[0].offset;
                info        = new InfoBlock
                {
                    magic               = br.ReadChars(4),
                    blockSize           = br.ReadUInt32(),
                    encoding            = br.ReadByte(),
                    isLoop              = br.ReadBoolean(),
                    padding             = br.ReadUInt16(),
                    sampleRate          = br.ReadUInt32(),
                    loopStart           = br.ReadUInt32(),
                    loopEnd             = br.ReadUInt32(),
                    originalLoopStart   = br.ReadUInt32(),
                    channelInfoRefTable = new ReferenceTable(ref br),
                    channelInfo         = new List <InfoBlock.ChannelInfo>()
                };

                //Read channel info.
                foreach (Reference r in info.channelInfoRefTable.references)
                {
                    //Set position.
                    br.Position = 0x5C + r.offset;

                    //New channel info.
                    InfoBlock.ChannelInfo c = new InfoBlock.ChannelInfo()
                    {
                        samplesRef      = new Reference(ref br),
                        dspAdpcmInfoRef = new Reference(ref br),
                        reserved        = br.ReadUInt32(),
                        dspAdpcmInfo    = null
                    };

                    //Read Dsp-Apdcm info.
                    if (c.dspAdpcmInfoRef.offset != Reference.NULL_PTR)
                    {
                        br.Position = 0x5C + r.offset + c.dspAdpcmInfoRef.offset;

                        c.dspAdpcmInfo                 = new DspAdpcmInfo();
                        c.dspAdpcmInfo.coefs           = new Int16[8][];
                        c.dspAdpcmInfo.coefs[0]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.coefs[1]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.coefs[2]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.coefs[3]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.coefs[4]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.coefs[5]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.coefs[6]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.coefs[7]        = br.ReadInt16s(2);
                        c.dspAdpcmInfo.pred_scale      = br.ReadUInt16();
                        c.dspAdpcmInfo.yn1             = br.ReadInt16();
                        c.dspAdpcmInfo.yn2             = br.ReadInt16();
                        c.dspAdpcmInfo.loop_pred_scale = br.ReadUInt16();
                        c.dspAdpcmInfo.loop_yn1        = br.ReadInt16();
                        c.dspAdpcmInfo.loop_yn2        = br.ReadInt16();
                    }

                    info.channelInfo.Add(c);
                }
            }

            //Read data block.
            if (fileHeader.blockOffsets[1].offset != Reference.NULL_PTR && fileHeader.blockOffsets[1].typeId == ReferenceTypes.WAV_Block_Data)
            {
                br.Position = fileHeader.blockOffsets[1].offset;
                data        = new SoundNStreamDataBlock(ref br, info);
            }
        }
예제 #4
0
        /// <summary>
        /// Update the file.
        /// </summary>
        public void Update(UInt16 byteOrder, Int32 wavOffset = 0x18)
        {
            //Find the size.
            UInt32 fileSize = 0;
            UInt32 infoSize = 32;
            UInt32 dataSize = data.GetSize(info.encoding, ref info, wavOffset);

            fileSize += dataSize;

            //Get size of info.
            info.magic = "INFO".ToCharArray();
            info.channelInfoRefTable       = new ReferenceTable(new List <Reference>());
            info.channelInfoRefTable.count = (UInt32)info.channelInfo.Count();

            //Ref pointer.
            Int32 refPointer = 4 + 8 * (Int32)info.channelInfoRefTable.count;

            infoSize += 8 * info.channelInfoRefTable.count;

            //Channel info.
            for (int i = 0; i < info.channelInfoRefTable.count; i++)
            {
                //Add pointer.
                info.channelInfoRefTable.references.Add(new Reference(ReferenceTypes.WAV_ItemInfos, refPointer));

                refPointer += 20;
                infoSize   += 20;
            }

            //Channel info.
            Int32 dspAdpcmOffset = 20 * info.channelInfo.Count();

            for (int i = 0; i < info.channelInfoRefTable.count; i++)
            {
                if (info.channelInfo[i].dspAdpcmInfo != null)
                {
                    info.channelInfo[i].dspAdpcmInfoRef = new Reference(0x300, dspAdpcmOffset);
                    refPointer     += 46;
                    infoSize       += 46;
                    dspAdpcmOffset += 46;
                }
                else
                {
                    info.channelInfo[i].dspAdpcmInfoRef = new Reference(0, Reference.NULL_PTR);
                }

                dspAdpcmOffset -= 20;
            }

            //Padding.
            while ((infoSize % 0x20) != 0)
            {
                infoSize += 1;
            }

            fileSize      += infoSize;
            info.blockSize = infoSize;

            //Update the file header.
            string magic = "FWAV";

            if (byteOrder == ByteOrder.LittleEndian)
            {
                magic = "CWAV";
            }
            fileHeader = new FileHeader(magic, byteOrder, fileHeader.vMajor, fileHeader.vMinor, fileHeader.vRevision, fileSize, new List <SizedReference>()
            {
                new SizedReference(ReferenceTypes.WAV_Block_Info, 0, infoSize), new SizedReference(ReferenceTypes.WAV_Block_Data, (Int32)infoSize, dataSize)
            });
        }
예제 #5
0
        /// <summary>
        /// Update the file.
        /// </summary>
        /// <param name="endian">Endian.</param>
        public void Update(UInt16 endian)
        {
            //Update info.
            info.magic = "INFO".ToCharArray();
            info.streamSoundInfoRef = new Reference(ReferenceTypes.STRM_Info_StreamSound, 0x18);

            //Stream sound info.
            UInt32 infoBaseOffet = 0x18;

            info.streamSoundInfo.channelCount       = (byte)info.channels.Count;
            info.streamSoundInfo.regionCount        = 0;
            info.streamSoundInfo.regionDataOffset   = new Reference(0, Reference.NULL_PTR);
            info.streamSoundInfo.regionInfoBytesize = 0x100;
            info.streamSoundInfo.sampleDataOffset   = new Reference(ReferenceTypes.General_ByteStream, 0x18);
            info.streamSoundInfo.padding            = 0;
            info.streamSoundInfo.sizeOfSeekInfo     = 4;

            infoBaseOffet += 56;
            if (fileHeader.vMajor >= b_stm.regionInfo)
            {
                infoBaseOffet += 12;
            }
            if (fileHeader.vMajor >= b_stm.originalLoopInfo)
            {
                infoBaseOffet += 8;
            }
            if (fileHeader.vMajor >= b_stm.secretInfo)
            {
                infoBaseOffet += 4;
            }

            //Reference table for track info ref.
            info.trackInfoTableRef = new Reference(0x0101, (int)infoBaseOffet);

            //Skip ref table coords.
            infoBaseOffet += (uint)(info.tracks != null ? (info.tracks.Count * 8 + 4) : 0);

            info.channelInfoTableRef = new Reference(0x0101, (int)infoBaseOffet);

            List <Reference> trackRefs = new List <Reference>();

            //Track info.
            UInt32 trackBaseOffset = (uint)((info.tracks != null ? (info.tracks.Count * 8 + 4) : 0) + (info.channels.Count * 8 + 4));

            if (info.tracks != null)
            {
                for (int i = 0; i < info.tracks.Count; i++)
                {
                    trackRefs.Add(new Reference(ReferenceTypes.STRM_Info_Track, (int)trackBaseOffset));

                    infoBaseOffet   += 12;
                    trackBaseOffset += 12;
                    if (info.tracks[i].globalChannelIndexTable != null)
                    {
                        info.tracks[i].globalChannelIndexTableRef    = new Reference(0x100, 0xC);
                        info.tracks[i].globalChannelIndexTable.count = (uint)info.tracks[i].globalChannelIndexTable.entries.Count;
                        infoBaseOffet   += 4 + info.tracks[i].globalChannelIndexTable.count;
                        trackBaseOffset += 4 + info.tracks[i].globalChannelIndexTable.count;
                        while (infoBaseOffet % 4 != 0)
                        {
                            infoBaseOffet++;
                            trackBaseOffset++;
                        }
                    }
                    else
                    {
                        info.tracks[i].globalChannelIndexTableRef = new Reference(0, Reference.NULL_PTR);
                    }
                }
                info.trackInfoRefTable = new ReferenceTable(trackRefs);
            }
            else
            {
                info.trackInfoTableRef = new Reference(0, Reference.NULL_PTR);
            }

            //Channel info.
            UInt32 channelBaseOffset = (uint)(4 + 8 * info.channels.Count + trackBaseOffset - ((uint)((info.tracks != null ? (info.tracks.Count * 8 + 4) : 0) + (info.channels.Count * 8 + 4))));

            infoBaseOffet += (uint)(4 + 8 * info.channels.Count);
            List <Reference> channelRefs = new List <Reference>();

            for (int i = 0; i < info.channels.Count; i++)
            {
                channelRefs.Add(new Reference(ReferenceTypes.STRM_Info_Channel, (int)channelBaseOffset));
                channelBaseOffset += 8;
                infoBaseOffet     += 8;
            }

            info.channelInfoRefTable = new ReferenceTable(channelRefs);

            channelBaseOffset = (uint)(8 * info.channels.Count);
            for (int i = 0; i < info.channels.Count; i++)
            {
                info.channels[i].dspAdpcmInfoRef = new Reference(0, Reference.NULL_PTR);
                if (info.channels[i].dspAdpcmInfo != null)
                {
                    info.channels[i].dspAdpcmInfoRef = new Reference(0x300, (int)channelBaseOffset);
                    channelBaseOffset += 0x2E;
                    infoBaseOffet     += 0x2E;
                }
                channelBaseOffset -= 8;
            }

            //Update pdat.
            pdat.magic = "PDAT".ToCharArray();
            pdat.size  = pdat.GetSize();
            pdat.prefetchData.count = (uint)pdat.prefetchData.entries.Count;
            Int32 offset = 0x34;

            for (int i = 0; i < pdat.prefetchData.count; i++)
            {
                pdat.prefetchData.entries[i].reserved         = 0;
                pdat.prefetchData.entries[i].toPrefetchSample = new Reference(0, offset);
            }

            //Make offsets, depeding on what blocks exist, and on the sizes of the blocks.
            List <SizedReference> blocks = new List <SizedReference>();

            //Can't forget about magic and size.
            infoBaseOffet += 8;

            while (infoBaseOffet % 0x20 != 0)
            {
                infoBaseOffet++;
            }
            info.blockSize = infoBaseOffet;

            blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_Info, 0, info.blockSize));
            blocks.Add(new SizedReference(ReferenceTypes.STRM_Block_PrefetchData, (int)info.blockSize, pdat.GetSize()));

            fileHeader = new FileHeader(endian == ByteOrder.LittleEndian ? "CSTM" : "FSTM", endian, fileHeader.vMajor, fileHeader.vMinor, fileHeader.vRevision, (uint)(info.blockSize + pdat.GetSize()), blocks);
        }