Ejemplo n.º 1
0
        void AddPSG(M4AVoice voice, byte low = 0, byte high = 127)
        {
            dynamic v = voice;
            int     sample;

            if (voice is M4APSG_Square_1 || voice is M4APSG_Square_2)
            {
                sample = AddSample(SongPlayer.Sounds[SongPlayer.SQUARE12_ID - v.Pattern], "Square Wave " + v.Pattern);
            }
            else if (voice is M4APSG_Wave wave)
            {
                sample = AddSample(SongPlayer.Sounds[wave.Address], string.Format("PSG Wave 0x{0:X}", wave.Address));
            }
            else
            {
                sample = AddSample(SongPlayer.Sounds[SongPlayer.NOISE0_ID - v.Pattern], "Noise " + v.Pattern);
            }

            sf2.AddINSTBag();

            // ADSR
            if (v.A != 0)
            {
                // Compute attack time - the sound engine is called 60 times per second
                // and adds "attack" to envelope every time the engine is called
                double att_time = v.A / 5.0;
                double att      = 1200 * Math.Log(att_time, 2);
                sf2.AddINSTGenerator(SF2Generator.attackVolEnv, new GenAmountType((ushort)att));
            }
            if (v.S != 15)
            {
                double sus;
                // Compute attenuation in cB if sustain is non-zero
                if (v.S != 0)
                {
                    sus = 100 * Math.Log(15d / v.S);
                }
                // Special case where attenuation is infinite -> use max value
                else
                {
                    sus = 1000;
                }

                sf2.AddINSTGenerator(SF2Generator.sustainVolEnv, new GenAmountType((ushort)sus));

                double dec_time = v.D / 5d;
                double dec      = 1200 * Math.Log(dec_time + 1, 2);
                sf2.AddINSTGenerator(SF2Generator.decayVolEnv, new GenAmountType((ushort)dec));
            }
            if (v.R != 0)
            {
                double rel_time = v.R / 5d;
                double rel      = 1200 * Math.Log(rel_time, 2);
                sf2.AddINSTGenerator(SF2Generator.releaseVolEnv, new GenAmountType((ushort)rel));
            }

            high = Math.Min((byte)127, high);
            if (!(low == 0 && high == 127))
            {
                sf2.AddINSTGenerator(SF2Generator.keyRange, new GenAmountType(low, high));
            }
            if (voice is M4APSG_Noise noise && noise.Panpot != 0)
            {
                sf2.AddINSTGenerator(SF2Generator.pan, new GenAmountType((ushort)((noise.Panpot - 0xC0) * (500d / 0x80))));
            }
            sf2.AddINSTGenerator(SF2Generator.sampleModes, new GenAmountType(1));
            sf2.AddINSTGenerator(SF2Generator.sampleID, new GenAmountType((ushort)(sample)));
        }