Exemple #1
0
        /// <summary>
        /// Convert the bank to downloadable sounds.
        /// </summary>
        /// <param name="a">The sound archive.</param>
        /// <param name="b">The bank info.</param>
        /// <returns>The bank as DLS.</returns>
        public DownloadableSounds ToDLS(SoundArchive a, BankInfo b)
        {
            //New DLS.
            DownloadableSounds d = new DownloadableSounds();

            //Wave map.
            Dictionary <uint, RiffWave>   waveMap  = new Dictionary <uint, RiffWave>();
            Dictionary <ushort, RiffWave> psgMap   = new Dictionary <ushort, RiffWave>();
            Dictionary <ushort, RiffWave> noiseMap = new Dictionary <ushort, RiffWave>();

            d.Waves.Add(new RiffWave("Hardware/Null.wav"));

            //Add each instrument.
            foreach (var inst in Instruments)
            {
                //New instrument.
                GotaSoundBank.DLS.Instrument im = new GotaSoundBank.DLS.Instrument();
                im.BankId       = (uint)(inst.Index / 128);
                im.InstrumentId = (uint)(inst.Index % 128);
                im.Name         = "Instrument " + im.InstrumentId;

                //Add regions.
                byte lastNote = inst as DrumSetInstrument != null ? (inst as DrumSetInstrument).Min : (byte)0;
                foreach (var n in inst.NoteInfo)
                {
                    //New region.
                    Region r = new Region();

                    //Set note info.
                    r.VelocityLow    = 0;
                    r.VelocityHigh   = 127;
                    r.NoteLow        = lastNote;
                    r.NoteHigh       = (inst as DirectInstrument != null) ? (byte)127 : (byte)n.Key;
                    lastNote         = (byte)(n.Key + 1);
                    r.ChannelFlags   = 1;
                    r.DoublePlayback = true;
                    r.Layer          = 1;
                    r.NoTruncation   = true;
                    r.RootNote       = (byte)n.BaseNote;

                    //Wave data.
                    int wavInd = 0;
                    switch (n.InstrumentType)
                    {
                    case InstrumentType.PCM:
                        uint key = 0xFFFFFFFF;
                        try {
                            var p = b.WaveArchives[n.WarId].File.Waves[n.WaveId];
                            key = (uint)(b.WaveArchives[n.WarId].Index << 16) | n.WaveId;
                        } catch { }
                        if (key != 0xFFFFFFFF)
                        {
                            if (!waveMap.ContainsKey(key))
                            {
                                RiffWave pcm = new RiffWave();
                                pcm.FromOtherStreamFile(b.WaveArchives[n.WarId].File.Waves[n.WaveId]);
                                waveMap.Add(key, pcm);
                                d.Waves.Add(pcm);
                            }
                            wavInd = d.Waves.IndexOf(waveMap[key]);
                        }
                        break;

                    case InstrumentType.PSG:
                        if (!psgMap.ContainsKey(n.WaveId))
                        {
                            RiffWave psg = new RiffWave("Hardware/DutyCycle" + (n.WaveId + 1) + ".wav");
                            psgMap.Add(n.WaveId, psg);
                            d.Waves.Add(psg);
                        }
                        wavInd = d.Waves.IndexOf(psgMap[n.WaveId]);
                        break;

                    case InstrumentType.Noise:
                        if (!noiseMap.ContainsKey(0))
                        {
                            RiffWave noise = new RiffWave("Hardware/WhiteNoise.wav");
                            noiseMap.Add(0, noise);
                            d.Waves.Add(noise);
                            wavInd = d.Waves.IndexOf(noise);
                        }
                        else
                        {
                            wavInd = d.Waves.IndexOf(noiseMap[0]);
                        }
                        break;
                    }

                    //Set wave data.
                    r.WaveId = (uint)wavInd;
                    r.Loops  = d.Waves[wavInd].Loops;
                    if (r.Loops)
                    {
                        r.LoopStart  = d.Waves[wavInd].LoopStart;
                        r.LoopLength = d.Waves[wavInd].LoopEnd - d.Waves[wavInd].LoopStart;
                        if (r.LoopLength < 0)
                        {
                            r.LoopLength = 0;
                        }
                    }

                    //Articulator.
                    Articulator ar = new Articulator();
                    ar.Connections.Add(new Connection()
                    {
                        DestinationConnection = DestinationConnection.EG1AttackTime, Scale = n.Attack >= 127 ? int.MinValue : MillisecondsToTimecents(AttackTable[n.Attack]) * 65536
                    });
                    ar.Connections.Add(new Connection()
                    {
                        DestinationConnection = DestinationConnection.EG1DecayTime, Scale = n.Decay >= 127 ? int.MinValue : MillisecondsToTimecents(MaxReleaseTimes[n.Decay]) * 65536
                    });
                    ar.Connections.Add(new Connection()
                    {
                        DestinationConnection = DestinationConnection.EG1SustainLevel, Scale = (int)Math.Round(Sustain2Fraction(n.Sustain) * 1000, MidpointRounding.AwayFromZero) * 65536
                    });
                    ar.Connections.Add(new Connection()
                    {
                        DestinationConnection = DestinationConnection.EG1ReleaseTime, Scale = n.Release >= 127 ? int.MinValue : MillisecondsToTimecents(MaxReleaseTimes[n.Release]) * 65536
                    });
                    ar.Connections.Add(new Connection()
                    {
                        DestinationConnection = DestinationConnection.Pan, Scale = GetPan(n.Pan) * 65536
                    });
                    r.Articulators.Add(ar);

                    //Add region.
                    im.Regions.Add(r);
                }

                //Add the instrument.
                d.Instruments.Add(im);
            }

            //Return the DLS.
            return(d);
        }
Exemple #2
0
        /// <summary>
        /// Create a sound font from a downloadable sounds file.
        /// </summary>
        /// <param name="dls">A DLS file.</param>
        public SoundFont(DownloadableSounds dls)
        {
            //Get samples.
            Dictionary <int, int> waveLink;

            dls.AssignLoops();
            CreateSampleTable(dls.Waves, out waveLink);

            //Get instruments.
            foreach (var i in dls.Instruments)
            {
                Instrument inst = new Instrument();
                inst.Name = i.Name;
                foreach (var r in i.Regions)
                {
                    //New zone.
                    Zone z = new Zone();

                    //Key range.
                    if (r.NoteHigh != 127 || r.NoteLow != 0)
                    {
                        z.Generators.Add(new Generator()
                        {
                            Gen = SF2Generators.KeyRange, Amount = new SF2GeneratorAmount()
                            {
                                LowByte = (byte)r.NoteLow, HighByte = (byte)r.NoteHigh
                            }
                        });
                    }

                    //Velocity range.
                    if (r.VelocityHigh != 127 || r.VelocityLow != 0)
                    {
                        z.Generators.Add(new Generator()
                        {
                            Gen = SF2Generators.VelRange, Amount = new SF2GeneratorAmount()
                            {
                                LowByte = (byte)r.VelocityLow, HighByte = (byte)r.VelocityHigh
                            }
                        });
                    }

                    //Root key.
                    z.Generators.Add(new Generator()
                    {
                        Gen = SF2Generators.OverridingRootKey, Amount = new SF2GeneratorAmount()
                        {
                            UAmount = r.RootNote
                        }
                    });

                    //Pitch correction.
                    Samples[waveLink[(int)r.WaveId]].PitchCorrection = (sbyte)(r.Tuning / 65536);

                    //Sample Id.
                    z.Generators.Add(new Generator()
                    {
                        Gen = SF2Generators.SampleID, Amount = new SF2GeneratorAmount()
                        {
                            UAmount = (ushort)waveLink[(int)r.WaveId]
                        }
                    });
                    if (dls.Waves[(int)r.WaveId].Loops)
                    {
                        z.Generators.Add(new Generator()
                        {
                            Gen = SF2Generators.SampleModes, Amount = new SF2GeneratorAmount()
                            {
                                Amount = 1
                            }
                        });
                    }

                    //Articulators.
                    foreach (var a in r.Articulators)
                    {
                        foreach (var c in a.Connections)
                        {
                            //Generator.
                            SF2Generators      gen    = (SF2Generators)100;
                            SF2GeneratorAmount amount = new SF2GeneratorAmount();

                            //Switch connection type.
                            switch (c.DestinationConnection)
                            {
                            case DestinationConnection.Chorus:
                                gen           = SF2Generators.ChorusEffectsSend;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.EG1AttackTime:
                                gen           = SF2Generators.AttackVolEnv;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.EG1DecayTime:
                                gen           = SF2Generators.DecayVolEnv;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.EG1DelayTime:
                                gen           = SF2Generators.DelayVolEnv;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.EG1HoldTime:
                                gen           = SF2Generators.HoldVolEnv;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.EG1ReleaseTime:
                                gen           = SF2Generators.ReleaseVolEnv;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.EG1SustainLevel:
                                gen           = SF2Generators.SustainVolEnv;
                                amount.Amount = (short)((1 - c.Scale / 65536d / 1000) * 1000);
                                break;

                            case DestinationConnection.KeyNumber:
                                gen           = SF2Generators.Keynum;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.Pan:
                                gen           = SF2Generators.Pan;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.LFOFrequency:
                                gen           = SF2Generators.FreqModLFO;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;

                            case DestinationConnection.LFOStartDelayTime:
                                gen           = SF2Generators.DelayModLFO;
                                amount.Amount = (short)(c.Scale / 65536);
                                break;
                            }

                            //Add generator.
                            if ((int)gen != 100)
                            {
                                z.Generators.Add(new Generator()
                                {
                                    Gen = gen, Amount = amount
                                });
                            }

                            //Modulator used.
                            if (c.TransformConnection != TransformConnection.None)
                            {
                                //Nah, I'm lazy.
                            }
                        }
                    }

                    //Add zone.
                    inst.Zones.Add(z);
                }
                Instruments.Add(inst);
            }

            //Set presets.
            ushort instNum = 0;

            foreach (var i in dls.Instruments)
            {
                Presets.Add(new Preset()
                {
                    Bank = (ushort)i.BankId, Name = i.Name, PresetNumber = (ushort)i.InstrumentId, Zones = new List <Zone>()
                    {
                        new Zone()
                        {
                            Generators = new List <Generator>()
                            {
                                new Generator()
                                {
                                    Gen = SF2Generators.Instrument, Amount = new SF2GeneratorAmount()
                                    {
                                        UAmount = instNum++
                                    }
                                }
                            }
                        }
                    }
                });
            }
        }