Beispiel #1
0
        /// <summary>
        /// Write the data.
        /// </summary>
        /// <param name="writeMode">Write mode.</param>
        /// <param name="bw">The writer.</param>
        public void Write(WriteMode writeMode, BinaryDataWriter bw)
        {
            //In case STM is null.
            if (Stream == null)
            {
                bw.Write(BackupSTP);
                return;
            }

            //Set write mode.
            this.writeMode = writeMode;

            //Write the prefetch file.
            FileWriter FileWriter = new FileWriter();

            FileWriter.InitFile(bw, writeMode, "STP", 2, Version);

            //Open the info block.
            FileWriter.InitBlock(bw, ReferenceTypes.STRM_Block_Info, "INFO");

            //Write the stream file, to steal data from later.
            MemoryStream     src = new MemoryStream();
            BinaryDataReader br  = new BinaryDataReader(src);
            BinaryDataWriter bw2 = new BinaryDataWriter(src);

            br.ByteOrder  = bw.ByteOrder;
            bw2.ByteOrder = bw.ByteOrder;
            Stream.Write(writeMode, bw2);

            //Get the info block to copy.
            br.Position = 0x18;
            Int32  infoOffset = br.ReadInt32();
            UInt32 infoSize   = br.ReadUInt32();

            br.Position = infoOffset + 8;
            bw.Write(br.ReadBytes((int)infoSize - 8));

            //Highjack the data pointer in the info.
            br.Position = infoOffset + 0xC;
            Int32 dataOffset     = br.ReadInt32();
            long  trueDataOffset = dataOffset + infoOffset + 8 + 52;

            //Close the info block.
            FileWriter.CloseBlock(bw);

            //Open the prefetch data block.
            FileWriter.InitBlock(bw, ReferenceTypes.STRM_Block_PrefetchData, "PDAT");

            //Write the prefetch data table.
            bw.Write((UInt32)1);

            //Prefetch start frame.
            bw.Write((UInt32)0);

            //Write the prefetch size.
            bw.Write((UInt32)(Stream.Stm.info.channels.Count * 0xA000));

            //Write reserved.
            bw.Write((UInt32)0);

            //Write the prefetch reference.
            bw.Write((UInt32)0);
            bw.Write((UInt32)0x34);

            //Write padding.
            bw.Write(new byte[0x20]);

            //Go to offset in stream.
            br.Position = 0x30;
            Int32 someDataOffset = br.ReadInt32();

            br.Position = someDataOffset + Stream.Stm.info.streamSoundInfo.sampleDataOffset.offset + 8;

            //Take backup.
            long back = bw.Position;

            //Set data position.
            bw.Position = trueDataOffset;
            bw.Write((UInt32)back);
            bw.Position = back;

            //Add the b_stm data.
            bw.Write(br.ReadBytes(Stream.Stm.info.channels.Count * 0xA000));

            //Close prefetch data block.
            FileWriter.CloseBlock(bw);

            //Close the prefetch file.
            FileWriter.CloseFile(bw);
        }
Beispiel #2
0
        /// <summary>
        /// Write a bank file.
        /// </summary>
        /// <param name="writeMode">Write mode.</param>
        /// <param name="bw">The writer.</param>
        public void Write(WriteMode writeMode, BinaryDataWriter bw)
        {
            //Set the write mode.
            this.writeMode = writeMode;

            //Init the bank file.
            FileWriter FileWriter = new FileWriter();

            FileWriter.InitFile(bw, writeMode, "BNK", 1, Version);

            //Init info block.
            FileWriter.InitBlock(bw, ReferenceTypes.BNK_Block_Info, "INFO");

            //Init the reference to the wave id table.
            FileWriter.InitReference(bw, "WaveIdTableRef");

            //Init the reference to the instrument reference table.
            FileWriter.InitReference(bw, "InstrumentReferenceTableRef");

            //Write the instrument reference table.
            if (Instruments != null)
            {
                //Write the reference.
                FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "InstrumentReferenceTableRef");

                //Reference table is a structure.
                FileWriter.StartStructure(bw);

                //Init the instrument reference table.
                FileWriter.InitReferenceTable(bw, Instruments.Count, "InstrumentReferenceTable");

                //Write each instrument.
                for (int i = 0; i < Instruments.Count; i++)
                {
                    //If instrument is null.
                    if (Instruments[i] == null)
                    {
                        //Write the null reference.
                        FileWriter.AddReferenceTableNullReferenceWithType(ReferenceTypes.BNK_Info_Null, "InstrumentReferenceTable");
                    }

                    //Instrument is not null.
                    else
                    {
                        //Add reference.
                        FileWriter.AddReferenceTableReference(bw, ReferenceTypes.BNK_Info_Instrument, "InstrumentReferenceTable");

                        //Instrument is a new structure.
                        FileWriter.StartStructure(bw);

                        //Instrument type reference.
                        FileWriter.InitReference(bw, "InstType");

                        //Get the type of reference.
                        switch (Instruments[i].GetInstrumentType())
                        {
                        //Direct.
                        case InstrumentType.Direct:
                            FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Direct, "InstType");
                            break;

                        //Index.
                        case InstrumentType.Index:
                            FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Index, "InstType");
                            break;

                        //Range.
                        case InstrumentType.Range:
                            FileWriter.CloseReference(bw, ReferenceTypes.BNK_RefTable_Range, "InstType");
                            break;
                        }

                        //Instrument is a new structure.
                        FileWriter.StartStructure(bw);

                        //Switch the type of reference.
                        switch (Instruments[i].GetInstrumentType())
                        {
                        //Direct.
                        case InstrumentType.Direct:

                            //Direct.
                            DirectInstrument d = ((DirectInstrument)Instruments[i]);

                            //Write key region reference.
                            FileWriter.InitReference(bw, "KeyRegion");

                            //Null region.
                            if (d.KeyRegion == null)
                            {
                                FileWriter.CloseNullReference(bw, "KeyRegion");
                            }

                            //Not null.
                            else
                            {
                                //Close the reference.
                                FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_KeyRegion, "KeyRegion");

                                //Write key region.
                                WriteKeyRegion(bw, d.KeyRegion, FileWriter);
                            }
                            break;

                        //Ranged.
                        case InstrumentType.Range:

                            //Set range info.
                            RangeInstrument ran = (RangeInstrument)Instruments[i];

                            //Write stuff.
                            bw.Write((byte)ran.StartNote);
                            bw.Write((byte)ran.EndNote);
                            bw.Write((UInt16)0);

                            //Init each reference.
                            for (int j = 0; j < ran.NoteCount; j++)
                            {
                                FileWriter.InitReference(bw, "Ran" + j);
                            }

                            //Write each key region.
                            for (int j = 0; j < ran.NoteCount; j++)
                            {
                                //Null region.
                                if (ran[j] == null)
                                {
                                    FileWriter.CloseNullReference(bw, "Ran" + j);
                                }

                                //Write key region.
                                else
                                {
                                    //Key region reference.
                                    FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_KeyRegion, "Ran" + j);

                                    //Write the key region.
                                    WriteKeyRegion(bw, ran[j], FileWriter);
                                }
                            }
                            break;

                        //Index.
                        case InstrumentType.Index:

                            //Set index data.
                            IndexInstrument ind = (IndexInstrument)Instruments[i];

                            //Write the table of indices.
                            bw.Write((uint)ind.Count);
                            for (int j = 0; j < ind.Count; j++)
                            {
                                bw.Write((byte)ind.Keys.ElementAt(j));
                            }

                            //Write padding.
                            FileWriter.Align(bw, 4);

                            //Init each index reference.
                            for (int j = 0; j < ind.Count; j++)
                            {
                                FileWriter.InitReference(bw, "Ind" + j);
                            }

                            //Write each index.
                            for (int j = 0; j < ind.Count; j++)
                            {
                                //Null index.
                                if (ind.Values.ElementAt(j) == null)
                                {
                                    FileWriter.CloseNullReference(bw, "Ind" + j);
                                }

                                //Index exist.
                                else
                                {
                                    //Close reference.
                                    FileWriter.CloseReference(bw, ReferenceTypes.BNK_Info_KeyRegion, "Ind" + j);

                                    //Write the key region.
                                    WriteKeyRegion(bw, ind.Values.ElementAt(j), FileWriter);
                                }
                            }
                            break;
                        }

                        //End the instrument.
                        FileWriter.EndStructure();

                        //End the instrument structure.
                        FileWriter.EndStructure();
                    }
                }

                //Close the instrument reference table.
                FileWriter.CloseReferenceTable(bw, "InstrumentReferenceTable");

                //End the instrument reference table structure.
                FileWriter.EndStructure();
            }
            else
            {
                //Write null offset.
                FileWriter.CloseNullReference(bw, "InstrumentReferenceTableRef");
            }

            //Write the wave id table.
            if (Waves != null)
            {
                //Write the reference.
                FileWriter.CloseReference(bw, ReferenceTypes.Tables, "WaveIdTableRef");

                //Write the wave id table.
                bw.Write((uint)Waves.Count);
                for (int i = 0; i < Waves.Count; i++)
                {
                    Id warId = new Id(SoundTypes.WaveArchive, (uint)Waves[i].WarIndex);
                    warId.Write(ref bw);
                    bw.Write((uint)Waves[i].WaveIndex);
                }
            }

            //Null wave ids.
            else
            {
                FileWriter.CloseNullReference(bw, "WaveIdTableRef");
            }

            //Close the info block.
            FileWriter.CloseBlock(bw);

            //Close the bank file.
            FileWriter.CloseFile(bw);
        }
Beispiel #3
0
        /// <summary>
        /// Write the file.
        /// </summary>
        /// <param name="writeMode">Write mode.</param>
        /// <param name="bw">The writer.</param>
        public void Write(WriteMode writeMode, BinaryDataWriter bw)
        {
            //Set write mode.
            this.writeMode = writeMode;

            //Init file.
            FileWriter FileWriter = new FileWriter();

            FileWriter.InitFile(bw, writeMode, "GRP", Version > new FileWriter.Version(1, 0, 0) ? 3 : 2, Version);

            //Info block.
            FileWriter.InitBlock(bw, ReferenceTypes.GRP_Block_Info, "INFO");

            //Reference table to group items.
            FileWriter.InitReferenceTable(bw, SoundFiles.Count, "FileRefs");

            //Write each sound thing.
            for (int i = 0; i < SoundFiles.Count; i++)
            {
                //Null.
                if (SoundFiles[i] == null)
                {
                    FileWriter.AddReferenceTableNullReference("FileRefs");
                }

                //Exists.
                else
                {
                    //Add reference.
                    FileWriter.AddReferenceTableReference(bw, ReferenceTypes.GRP_Info_Item, "FileRefs");

                    //Write data.
                    bw.Write((uint)SoundFiles[i].FileId);
                    FileWriter.InitSizedReference(bw, "FileRef" + i);
                }
            }

            //Align.
            FileWriter.Align(bw, 0x20);

            //Close reference table.
            FileWriter.CloseReferenceTable(bw, "FileRefs");

            //Close info block.
            FileWriter.CloseBlock(bw);

            //File block.
            FileWriter.InitBlock(bw, ReferenceTypes.GRP_Block_File, "FILE");

            //Align to 0x20 bytes.
            FileWriter.Align(bw, 0x20);

            //Write each file and align.
            for (int i = 0; i < SoundFiles.Count; i++)
            {
                //Null.
                if (SoundFiles[i] == null)
                {
                    FileWriter.CloseSizedNullReference(bw, "FileRef" + i);
                }

                //Not null.
                else
                {
                    //If the file is embedded.
                    if (SoundFiles[i].Embed)
                    {
                        //Keep track of position.
                        long pos = bw.Position;

                        //Write file.
                        FileWriter.WriteFile(bw, SoundFiles[i].File, 0x20, writeMode);

                        //Close reference.
                        FileWriter.CloseSizedReference(bw, ReferenceTypes.General, (uint)(bw.Position - pos), "FileRef" + i);
                    }

                    //Don't write data.
                    else
                    {
                        FileWriter.CloseSizedNullReference(bw, "FileRef" + i);
                    }
                }
            }

            //Close file block.
            FileWriter.CloseBlock(bw);

            //Extra info exists if the version is greater than one.
            if (Version > new FileWriter.Version(1, 0, 0))
            {
                //Extra info block.
                FileWriter.InitBlock(bw, ReferenceTypes.GRP_Block_Infx, "INFX");

                //Ex table.
                FileWriter.InitReferenceTable(bw, ExtraInfo.Count, "Ex");

                //Write each info entry.
                for (int i = 0; i < ExtraInfo.Count; i++)
                {
                    //Null.
                    if (ExtraInfo[i] == null)
                    {
                        FileWriter.AddReferenceTableNullReference("Ex");
                    }

                    //Not null.
                    else
                    {
                        //Add reference.
                        FileWriter.AddReferenceTableReference(bw, ReferenceTypes.GRP_Infx_Item, "Ex");

                        //Write the data.
                        InfoExEntry e     = ExtraInfo[i];
                        UInt32      flags = 0;
                        switch (e.LoadFlags)
                        {
                        case InfoExEntry.ELoadFlags.All:
                            flags = 0xFFFFFFFF;
                            break;

                        case InfoExEntry.ELoadFlags.Bank:
                            flags = 0b100;
                            break;

                        case InfoExEntry.ELoadFlags.BankAndWarc:
                            flags = 0b1100;
                            break;

                        case InfoExEntry.ELoadFlags.Seq:
                            flags = 0b1;
                            break;

                        case InfoExEntry.ELoadFlags.SeqAndBank:
                            flags = 0b101;
                            break;

                        case InfoExEntry.ELoadFlags.SeqAndWarc:
                            flags = 0b1100;
                            break;

                        case InfoExEntry.ELoadFlags.Warc:
                            flags = 0b1000;
                            break;

                        case InfoExEntry.ELoadFlags.Wsd:
                            flags = 0b10;
                            break;
                        }

                        //Get type.
                        byte type = 0;
                        switch (e.ItemType)
                        {
                        case InfoExEntry.EItemType.Bank:
                            type = SoundTypes.Bank;
                            break;

                        case InfoExEntry.EItemType.Sound:
                            type = SoundTypes.Sound;
                            break;

                        case InfoExEntry.EItemType.SequenceSetOrWaveData:
                            type = SoundTypes.SoundGroup;
                            break;

                        case InfoExEntry.EItemType.WaveArchive:
                            type = SoundTypes.WaveArchive;
                            break;
                        }

                        //Item id.
                        Id id = new Id(type, (uint)e.ItemIndex);
                        id.Write(ref bw);

                        //Write flags.
                        bw.Write(flags);
                    }
                }

                //Close Ex table.
                FileWriter.CloseReferenceTable(bw, "Ex");

                //Close extra info block.
                FileWriter.CloseBlock(bw);
            }

            //Close file.
            FileWriter.CloseFile(bw);
        }
Beispiel #4
0
        /// <summary>
        /// Write the sequence file.
        /// </summary>
        /// <param name="writeMode">Write mode.</param>
        /// <param name="bw">The writer.</param>
        public void Write(WriteMode writeMode, BinaryDataWriter bw)
        {
            //Update sequence data if write mode changed.
            if (this.writeMode != writeMode)
            {
                UpdateSeqData(writeMode);
            }

            //Set write mode.
            this.writeMode = writeMode;

            //Init file.
            FileWriter FileWriter = new FileWriter();

            FileWriter.InitFile(bw, writeMode, "SEQ", 2, Version);

            //Data block.
            FileWriter.InitBlock(bw, ReferenceTypes.SEQ_Block_Data, "DATA");

            //Write sequence data.
            Syroot.BinaryData.ByteOrder bo = Syroot.BinaryData.ByteOrder.BigEndian;
            if (writeMode == WriteMode.NX || writeMode == WriteMode.C_BE)
            {
                bo = Syroot.BinaryData.ByteOrder.LittleEndian;
            }
            //bw.Write(SequenceData.ToBytes(bo));
            bw.Write(goodData);

            //Align.
            FileWriter.Align(bw, 0x20);

            //Close data block.
            FileWriter.CloseBlock(bw);

            //Label block.
            FileWriter.InitBlock(bw, ReferenceTypes.SEQ_Block_Label, "LABL");

            //Label table.
            FileWriter.InitReferenceTable(bw, Labels.Count, "Labels");

            //Write each label.
            foreach (SequenceLabel l in Labels)
            {
                //Label is null.
                if (l == null)
                {
                    FileWriter.AddReferenceTableNullReference("Labels");
                }

                //Not null.
                else
                {
                    //Add reference.
                    FileWriter.AddReferenceTableReference(bw, ReferenceTypes.SEQ_LabelInfo, "Labels");

                    //Write data.
                    bw.Write(ReferenceTypes.General);
                    bw.Write((UInt16)0);
                    bw.Write(l.Offset);
                    bw.Write((UInt32)l.Label.Length);
                    bw.Write(l.Label.ToCharArray());

                    //Add null terminator.
                    bw.Write('\0');

                    //Align to 4 bytes.
                    FileWriter.Align(bw, 4);
                }
            }

            //Close labels.
            FileWriter.CloseReferenceTable(bw, "Labels");

            //Align.
            FileWriter.Align(bw, 0x20);

            //Close label block.
            FileWriter.CloseBlock(bw);

            //Close file.
            FileWriter.CloseFile(bw);
        }
Beispiel #5
0
        /// <summary>
        /// Write the file.
        /// </summary>
        /// <param name="writeMode">Write mode.</param>
        /// <param name="bw">The writer.</param>
        public void Write(WriteMode writeMode, BinaryDataWriter bw)
        {
            //Set write mode.
            this.writeMode = writeMode;

            //Init file.
            FileWriter FileWriter = new FileWriter();

            FileWriter.InitFile(bw, writeMode, "WSD", 1, Version);

            //Init info block.
            FileWriter.InitBlock(bw, ReferenceTypes.WAR_Blocks, "INFO");

            //Init wave id table reference.
            FileWriter.InitReference(bw, "ToWaveIdTableRef");

            //Init wave sound data table reference.
            FileWriter.InitReference(bw, "ToWaveSoundDataRefTable");

            //Close wave id reference table reference.
            if (Waves != null)
            {
                FileWriter.CloseReference(bw, ReferenceTypes.Tables, "ToWaveIdTableRef");
            }
            else
            {
                FileWriter.CloseNullReference(bw, "ToWaveIdTableRef");
            }

            //Write the table.
            if (Waves != null)
            {
                //Write count.
                bw.Write((uint)Waves.Count);

                //Write each id.
                for (int i = 0; i < Waves.Count; i++)
                {
                    //Write id.
                    Id id = new Id(SoundTypes.WaveArchive, (uint)Waves[i].WarIndex);
                    id.Write(ref bw);
                    bw.Write((uint)Waves[i].WaveIndex);
                }
            }

            //Close the wave sound table reference.
            if (DataItems != null)
            {
                FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "ToWaveSoundDataRefTable");
            }
            else
            {
                FileWriter.CloseNullReference(bw, "ToWaveSoundDataRefTable");
            }

            //Write the reference table.
            if (DataItems != null)
            {
                //Start structure.
                FileWriter.StartStructure(bw);

                //Init the table.
                FileWriter.InitReferenceTable(bw, DataItems.Count, "WaveSoundDataTable");

                //Write each entry.
                for (int i = 0; i < DataItems.Count; i++)
                {
                    //Entry is null.
                    if (DataItems[i] == null)
                    {
                        FileWriter.AddReferenceTableNullReference("WaveSoundDataTable");
                    }

                    //Valid entry.
                    else
                    {
                        //Add the reference.
                        FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_ItemInfos, "WaveSoundDataTable");

                        //New structure.
                        FileWriter.StartStructure(bw);

                        //Init wave sound info reference.
                        FileWriter.InitReference(bw, "WaveSoundInfoRef");

                        //Track info reference table reference.
                        FileWriter.InitReference(bw, "TrackInfoRefTableRef");

                        //Note info reference table reference.
                        FileWriter.InitReference(bw, "NoteInfoRefTableRef");

                        //Close wave sound info reference.
                        FileWriter.CloseReference(bw, ReferenceTypes.WSF_WaveSoundInfo, "WaveSoundInfoRef");

                        //Write the wave sound info.
                        Dictionary <int, uint> flags = new Dictionary <int, uint>();

                        //Flag list:

                        /*
                         * 0 - Pan info. 0x0000SSPP  S-Span P-Pan.
                         * 1 - Pitch, float.
                         * 2 - Biquad and LPF info. 0x00VVTTLL  L-LPF T-Biquad Type V-Biquad Value.
                         * 8 - Offset to send value.
                         * 9 - Offset to ADSHR curve offset.
                         */

                        //Pan info.
                        uint panInfo = 0;
                        panInfo += (uint)(DataItems[i].SurroundPan << 8);
                        panInfo += (uint)DataItems[i].Pan;
                        flags.Add(0, panInfo);

                        //Pitch.
                        flags.Add(1, BitConverter.ToUInt32(BitConverter.GetBytes(DataItems[i].Pitch), 0));

                        //Biquad and LPF.
                        if (DataItems[i].BiquadType != WaveSoundDataItem.EBiquadType.Unused)
                        {
                            uint bL = 0;
                            bL += (uint)(DataItems[i].BiquadValue << 16);
                            bL += (uint)((byte)DataItems[i].BiquadType << 8);
                            bL += (uint)DataItems[i].LpfFrequency;
                            flags.Add(2, bL);
                        }

                        //Offset to send value.
                        flags.Add(8, (uint)(DataItems[i].BiquadType != WaveSoundDataItem.EBiquadType.Unused ? 0x18 : 0x14));

                        //Offset to ADSHR curve offset.
                        flags.Add(9, (uint)(DataItems[i].BiquadType != WaveSoundDataItem.EBiquadType.Unused ? 0x20 : 0x1C));

                        //Write flag sound info.
                        FlagParameters f = new FlagParameters(flags);
                        f.Write(ref bw);

                        //Send value for 3.
                        if (writeMode == WriteMode.Cafe || writeMode == WriteMode.NX)
                        {
                            bw.Write(DataItems[i].SendValue[0]);
                            bw.Write((byte)3);
                            bw.Write(DataItems[i].SendValue[1]);
                            bw.Write(DataItems[i].SendValue[2]);
                            bw.Write(DataItems[i].SendValue[3]);
                            bw.Write(new byte[3]);
                        }

                        //Send value for 2.
                        else
                        {
                            bw.Write(DataItems[i].SendValue[0]);
                            bw.Write((byte)2);
                            bw.Write(DataItems[i].SendValue[1]);
                            bw.Write(DataItems[i].SendValue[2]);
                            bw.Write(new byte[4]);
                        }

                        //Write the ADSHR curve.
                        bw.Write((UInt32)0);
                        bw.Write((UInt32)8);
                        bw.Write(DataItems[i].Attack);
                        bw.Write(DataItems[i].Decay);
                        bw.Write(DataItems[i].Sustain);
                        bw.Write(DataItems[i].Hold);
                        bw.Write(DataItems[i].Release);
                        bw.Write(new byte[3]);

                        //Close track info reference table reference.
                        if (DataItems[i].NoteEvents == null)
                        {
                            FileWriter.CloseNullReference(bw, "TrackInfoRefTableRef");
                        }
                        else
                        {
                            //Close it properly.
                            FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "TrackInfoRefTableRef");

                            //New structure.
                            FileWriter.StartStructure(bw);

                            //Init the track info reference table.
                            FileWriter.InitReferenceTable(bw, DataItems[i].NoteEvents.Count, "TrackInfoRefTable");

                            //Write each track.
                            for (int j = 0; j < DataItems[i].NoteEvents.Count; j++)
                            {
                                //Add reference. (There is ambiguity between these note events, and the ones below. Should be fine?
                                if (DataItems[i].NoteEvents[j] == null)
                                {
                                    FileWriter.AddReferenceTableNullReference("TrackInfoRefTable");
                                }
                                else
                                {
                                    //Add reference.
                                    FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_TrackInfo, "TrackInfoRefTable");

                                    //Start structure.
                                    FileWriter.StartStructure(bw);

                                    //Reference to data.
                                    FileWriter.InitReference(bw, "TracksRef");

                                    //Write the track reference table.
                                    FileWriter.CloseReference(bw, 0, "TracksRef");

                                    //Start structure.
                                    FileWriter.StartStructure(bw);

                                    //Reference table.
                                    FileWriter.InitReferenceTable(bw, DataItems[i].NoteEvents[j].Count, "Tracks");

                                    //Write each track.
                                    for (int k = 0; k < DataItems[i].NoteEvents[j].Count; k++)
                                    {
                                        //Write the info.
                                        if (DataItems[i].NoteEvents[j][k] == null)
                                        {
                                            FileWriter.AddReferenceTableNullReference("Tracks");
                                        }
                                        else
                                        {
                                            //Proper reference.
                                            FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_NoteEvent, "Tracks");

                                            //Write data.
                                            bw.Write(DataItems[i].NoteEvents[j][k].Position);
                                            bw.Write(DataItems[i].NoteEvents[j][k].Length);
                                            bw.Write((uint)DataItems[i].NoteEvents[j][k].NoteIndex);
                                            bw.Write((uint)0);
                                        }
                                    }

                                    //Close reference table.
                                    FileWriter.CloseReferenceTable(bw, "Tracks");

                                    //End structure.
                                    FileWriter.EndStructure();

                                    //End structure. (Yes, again. There is that pointless reference from earlier.)
                                    FileWriter.EndStructure();
                                }
                            }

                            //Close the track info reference table.
                            FileWriter.CloseReferenceTable(bw, "TrackInfoRefTable");

                            //End structure.
                            FileWriter.EndStructure();
                        }

                        //Close note info reference table reference.
                        if (DataItems[i].Notes == null)
                        {
                            FileWriter.CloseNullReference(bw, "NoteInfoRefTableRef");
                        }
                        else
                        {
                            //Close it properly.
                            FileWriter.CloseReference(bw, ReferenceTypes.Table_Reference, "NoteInfoRefTableRef");

                            //New structure.
                            FileWriter.StartStructure(bw);

                            //Init the note info reference table.
                            FileWriter.InitReferenceTable(bw, DataItems[i].Notes.Count, "Notes");
                            for (int j = 0; j < DataItems[i].Notes.Count; j++)
                            {
                                //Add reference.
                                if (DataItems[i].Notes[j] == null)
                                {
                                    FileWriter.AddReferenceTableNullReference("Notes");
                                }
                                else
                                {
                                    //Add reference.
                                    FileWriter.AddReferenceTableReference(bw, ReferenceTypes.WSF_NoteInfo, "Notes");

                                    //Write data. TEMPORARY UNTIL DATA IS FOUND.
                                    bw.Write((uint)DataItems[i].Notes[j].WaveIndex);
                                    bw.Write((uint)0);
                                }
                            }

                            //Close reference table.
                            FileWriter.CloseReferenceTable(bw, "Notes");

                            //End structure.
                            FileWriter.EndStructure();
                        }
                    }
                }

                //Close the table.
                FileWriter.CloseReferenceTable(bw, "WaveSoundDataTable");

                //End structure.
                FileWriter.EndStructure();
            }

            //Close info block.
            FileWriter.CloseBlock(bw);

            //Close file.
            FileWriter.CloseFile(bw);
        }