/// <summary>
        /// Write the file.
        /// </summary>
        /// <param name="w2">The file writer.</param>
        public override void Write(FileWriter w2)
        {
            //Use a RIFF writer.
            using (RiffWriter w = new RiffWriter(w2.BaseStream)) {
                //Init file.
                w.InitFile("DLS ");

                //Instrument count.
                w.StartChunk("colh");
                w.Write((uint)Instruments.Count);
                w.EndChunk();

                //Instruments.
                w.StartListChunk("lins");
                foreach (var inst in Instruments)
                {
                    w.StartListChunk("ins ");
                    w.StartChunk("insh");
                    w.Write((uint)inst.Regions.Count);
                    w.Write(inst.BankId);
                    w.Write(inst.InstrumentId);
                    w.EndChunk();
                    w.StartListChunk("lrgn");
                    foreach (Region r in inst.Regions)
                    {
                        w.StartListChunk("rgn2");
                        w.StartChunk("rgnh");
                        w.Write(r.NoteLow);
                        w.Write(r.NoteHigh);
                        w.Write(r.VelocityLow);
                        w.Write(r.VelocityHigh);
                        w.Write((ushort)(r.DoublePlayback ? 1 : 0));
                        w.Write((ushort)r.KeyGroup);
                        w.Write(r.Layer);
                        w.EndChunk();
                        w.StartChunk("wsmp");
                        w.Write((uint)0x14);
                        w.Write((ushort)r.RootNote);
                        w.Write(r.Tuning);
                        w.Write(r.Gain);
                        uint flags = 0;
                        if (r.NoTruncation)
                        {
                            flags |= 0b1;
                        }
                        if (r.NoCompression)
                        {
                            flags |= 0b10;
                        }
                        w.Write(flags);
                        w.Write((uint)(r.Loops ? 1 : 0));
                        if (r.Loops)
                        {
                            w.Write((uint)0x10);
                            w.Write((uint)(r.LoopAndRelease ? 1 : 0));
                            w.Write(r.LoopStart);
                            w.Write(r.LoopLength);
                        }
                        w.EndChunk();
                        w.StartChunk("wlnk");
                        ushort flg = 0;
                        if (r.PhaseMaster)
                        {
                            flg |= 0b1;
                        }
                        if (r.MultiChannel)
                        {
                            flg |= 0b10;
                        }
                        w.Write(flg);
                        w.Write(r.PhaseGroup);
                        w.Write(r.ChannelFlags);
                        w.Write(r.WaveId);
                        w.EndChunk();
                        w.StartListChunk("lar2");
                        foreach (var a in r.Articulators)
                        {
                            w.StartChunk("art2");
                            w.Write((uint)8);
                            w.Write((uint)a.Connections.Count);
                            foreach (var c in a.Connections)
                            {
                                w.Write((ushort)c.SourceConnection);
                                w.Write(c.ControlConnection);
                                w.Write((ushort)c.DestinationConnection);
                                w.Write((ushort)c.TransformConnection);
                                w.Write(c.Scale);
                            }
                            w.EndChunk();
                        }
                        w.EndChunk();
                        w.EndChunk();
                    }
                    w.EndChunk();
                    if (inst.Name != "")
                    {
                        w.StartListChunk("INFO");
                        w.StartChunk("INAM");
                        w.Write(inst.Name.ToCharArray());
                        w.Write("\0".ToCharArray());
                        int len = inst.Name.Length + 1;
                        while (len % 4 != 0)
                        {
                            w.Write((byte)0);
                            len++;
                        }
                        w.EndChunk();
                        w.EndChunk();
                    }
                    w.EndChunk();
                }
                w.EndChunk();

                //Pointer table initializing.
                w.StartChunk("ptbl");
                w.Write((uint)8);
                w.Write((uint)Waves.Count);
                long ptblStart = w.BaseStream.Position;
                w.Write(new byte[Waves.Count * 4]);
                w.EndChunk();

                //Write waves.
                w.StartListChunk("wvpl");
                long waveTableStart = w.BaseStream.Position;
                int  waveNum        = 0;
                foreach (var wav in Waves)
                {
                    long wBak = w.BaseStream.Position;
                    w.BaseStream.Position = ptblStart + waveNum++ *4;
                    w.Write((uint)(wBak - waveTableStart));
                    w.BaseStream.Position = wBak;
                    w.WriteWave(wav);
                }
                w.EndChunk();

                //Write info.
                w.StartListChunk("INFO");
                w.StartChunk("INAM");
                w.Write("Instrument Set".ToCharArray());
                w.EndChunk();
                w.EndChunk();

                //Close file.
                w.CloseFile();
            }
        }
Example #2
0
        /// <summary>
        /// Write the file.
        /// </summary>
        /// <param name="w2">The writer.</param>
        public override void Write(FileWriter w2)
        {
            //Use a RIFF writer.
            using (RiffWriter w = new RiffWriter(w2.BaseStream)) {
                //Start file.
                w.InitFile("sfbk");

                //Start INFO.
                w.StartListChunk("INFO");

                //Version.
                w.StartChunk("ifil");
                w.Write((ushort)2);
                w.Write((ushort)1);
                w.EndChunk();

                //Sound engine.
                w.StartChunk("isng");
                w.WriteNullTerminated(SoundEngine);
                w.Align(2);
                w.EndChunk();

                //Bank name.
                w.StartChunk("INAM");
                w.WriteNullTerminated(BankName);
                w.Align(2);
                w.EndChunk();

                //ROM name.
                if (!RomName.Equals(""))
                {
                    w.StartChunk("irom");
                    w.WriteNullTerminated(RomName);
                    w.Align(2);
                    w.EndChunk();
                }

                //ROM version.
                if (RomVersion != null)
                {
                    w.StartChunk("iver");
                    w.Write(RomVersion.Item1);
                    w.Write(RomVersion.Item2);
                    w.EndChunk();
                }

                //Creation date.
                if (!CreationDate.Equals(""))
                {
                    w.StartChunk("ICRD");
                    w.WriteNullTerminated(CreationDate);
                    w.Align(2);
                    w.EndChunk();
                }

                //Sound designer.
                if (!SoundDesigner.Equals(""))
                {
                    w.StartChunk("IENG");
                    w.WriteNullTerminated(SoundDesigner);
                    w.Align(2);
                    w.EndChunk();
                }

                //Product.
                if (!Product.Equals(""))
                {
                    w.StartChunk("IPRD");
                    w.WriteNullTerminated(Product);
                    w.Align(2);
                    w.EndChunk();
                }

                //Copyright.
                if (!Copyright.Equals(""))
                {
                    w.StartChunk("ICOP");
                    w.WriteNullTerminated(Copyright);
                    w.Align(2);
                    w.EndChunk();
                }

                //Comment.
                if (!Comment.Equals(""))
                {
                    w.StartChunk("ICMT");
                    w.WriteNullTerminated(Comment);
                    w.Align(2);
                    w.EndChunk();
                }

                //Tools.
                if (!Tools.Equals(""))
                {
                    w.StartChunk("ISFT");
                    w.WriteNullTerminated(Tools);
                    w.Align(2);
                    w.EndChunk();
                }

                //End INFO.
                w.EndChunk();

                //Sample block.
                w.StartListChunk("sdta");
                w.StartChunk("smpl");
                long waveTableStart = w.Position;
                Dictionary <SampleItem, long> samplePositions = new Dictionary <SampleItem, long>();
                foreach (var s in Samples)
                {
                    samplePositions.Add(s, w.Position);
                    w.Write(new short[s.Wave.Audio.NumSamples]);
                    w.Write(new short[46]);
                }
                w.EndChunk();
                w.EndChunk();

                //The hydra.
                w.StartListChunk("pdta");

                //Presets.
                w.StartChunk("phdr");
                ushort      currBagIndex = 0;
                List <Zone> zones        = new List <Zone>();
                foreach (var p in Presets)
                {
                    p.ReadingBagIndex = currBagIndex;
                    currBagIndex     += (ushort)p.NumZones;
                    w.Write(p);
                    zones.AddRange(p.GetAllZones());
                }
                w.Write(new Preset()
                {
                    Name = "EOP", Bank = 255, PresetNumber = 255, ReadingBagIndex = currBagIndex
                });
                w.EndChunk();

                //Preset bags.
                w.StartChunk("pbag");
                ushort currGenIndex = 0;
                ushort currModIndex = 0;
                foreach (var z in zones)
                {
                    w.Write(currGenIndex);
                    w.Write(currModIndex);
                    currGenIndex += (ushort)z.Generators.Count;
                    currModIndex += (ushort)z.Modulators.Count;
                }
                w.Write(currGenIndex);
                w.Write(currModIndex);
                w.EndChunk();

                //Preset modulators.
                w.StartChunk("pmod");
                foreach (var z in zones)
                {
                    foreach (var v in z.Modulators)
                    {
                        w.Write(v);
                    }
                }
                w.Write(new Modulator());
                w.EndChunk();

                //Preset generators.
                w.StartChunk("pgen");
                foreach (var z in zones)
                {
                    foreach (var v in z.Generators)
                    {
                        w.Write(v);
                    }
                }
                w.Write(new Generator());
                w.EndChunk();

                //Instruments.
                w.StartChunk("inst");
                currBagIndex = 0;
                zones        = new List <Zone>();
                foreach (var p in Instruments)
                {
                    p.ReadingBagIndex = currBagIndex;
                    currBagIndex     += (ushort)p.NumZones;
                    w.Write(p);
                    zones.AddRange(p.GetAllZones());
                }
                w.Write(new Instrument()
                {
                    Name = "EOI", ReadingBagIndex = currBagIndex
                });
                w.EndChunk();

                //Instrument bags.
                w.StartChunk("ibag");
                currGenIndex = 0;
                currModIndex = 0;
                foreach (var z in zones)
                {
                    w.Write(currGenIndex);
                    w.Write(currModIndex);
                    currGenIndex += (ushort)z.Generators.Count;
                    currModIndex += (ushort)z.Modulators.Count;
                }
                w.Write(currGenIndex);
                w.Write(currModIndex);
                w.EndChunk();

                //Instrument modulators.
                w.StartChunk("imod");
                foreach (var z in zones)
                {
                    foreach (var v in z.Modulators)
                    {
                        w.Write(v);
                    }
                }
                w.Write(new Modulator());
                w.EndChunk();

                //Instrument generators.
                w.StartChunk("igen");
                foreach (var z in zones)
                {
                    foreach (var v in z.Generators)
                    {
                        w.Write(v);
                    }
                }
                w.Write(new Generator());
                w.EndChunk();

                //Samples.
                w.StartChunk("shdr");
                foreach (var s in Samples)
                {
                    w.CurrentOffset = samplePositions[s];
                    w.StructureOffsets.Push(waveTableStart);
                    w.Write(s);
                }
                w.Write("EOS".ToCharArray());
                w.Write(new byte[0x2B]);
                w.EndChunk();

                //End the hydra.
                w.EndChunk();

                //Close file.
                w.CloseFile();
            }
        }