public M4AWrappedKeySplit(M4AVoiceEntry keySplit) : base(keySplit)
        {
            try
            {
                Table = VoiceTable.LoadTable <M4AVoiceTable>(keySplit.Address - ROM.Pak, true);

                var keys    = ROM.Instance.Reader.ReadBytes(128, keySplit.Keys - ROM.Pak);
                var loading = new List <Triple <byte, byte, byte> >(); // Key, min, max
                int prev    = -1;
                for (int i = 0; i < 128; i++)
                {
                    byte a  = keys[i];
                    byte bi = (byte)i;
                    if (prev == a)
                    {
                        loading[loading.Count - 1].Item3 = bi;
                    }
                    else
                    {
                        prev = a;
                        loading.Add(new Triple <byte, byte, byte>(a, bi, bi));
                    }
                }
                Keys = loading.ToArray();
            }
            catch
            {
                Table = null;
                Keys  = null;
            }
        }
 public M4AWrappedDrum(M4AVoiceEntry drum) : base(drum)
 {
     try
     {
         Table = VoiceTable.LoadTable <M4AVoiceTable>(drum.Address - ROM.Pak, true);
     }
     catch
     {
         Table = null;
     }
 }
 public M4AWrappedDirect(M4AVoiceEntry direct) : base(direct) => Sample = new M4AWrappedSample(direct.Address - ROM.Pak);
Beispiel #4
0
            void AddPSG(M4AVoiceEntry entry, byte low = 0, byte high = 0x7F)
            {
                int sample;

                M4AVoiceType type = (M4AVoiceType)(entry.Type & 0x7);

                if (type == M4AVoiceType.Square1 || type == M4AVoiceType.Square2)
                {
                    sample = (int)entry.SquarePattern;
                }
                else if (type == M4AVoiceType.Wave)
                {
                    sample = AddWave(entry.Address - ROM.Pak);
                }
                else if (type == M4AVoiceType.Noise)
                {
                    sample = (int)entry.NoisePattern + 4;
                }
                else
                {
                    return;
                }

                sf2.AddInstrumentBag();

                high = Math.Min((byte)0x7F, high);
                if (!(low == 0 && high == 0x7F))
                {
                    sf2.AddInstrumentGenerator(SF2Generator.KeyRange, new SF2GeneratorAmount {
                        LowByte = low, HighByte = high
                    });
                }

                // ADSR
                if (entry.ADSR.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 = entry.ADSR.A / 5d;
                    double att      = 1200 * Math.Log(att_time, 2);
                    sf2.AddInstrumentGenerator(SF2Generator.AttackVolEnv, new SF2GeneratorAmount {
                        Amount = (short)att
                    });
                }
                if (entry.ADSR.S != 15)
                {
                    double sus;
                    // Compute attenuation in cB if sustain is non-zero
                    if (entry.ADSR.S != 0)
                    {
                        sus = 100 * Math.Log(15d / entry.ADSR.S);
                    }
                    // Special case where attenuation is infinite -> use max value
                    else
                    {
                        sus = 1000;
                    }

                    sf2.AddInstrumentGenerator(SF2Generator.SustainVolEnv, new SF2GeneratorAmount {
                        Amount = (short)sus
                    });

                    double dec_time = entry.ADSR.D / 5d;
                    double dec      = 1200 * Math.Log(dec_time + 1, 2);
                    sf2.AddInstrumentGenerator(SF2Generator.DecayVolEnv, new SF2GeneratorAmount {
                        Amount = (short)dec
                    });
                }
                if (entry.ADSR.R != 0)
                {
                    double rel_time = entry.ADSR.R / 5d;
                    double rel      = 1200 * Math.Log(rel_time, 2);
                    sf2.AddInstrumentGenerator(SF2Generator.ReleaseVolEnv, new SF2GeneratorAmount {
                        Amount = (short)rel
                    });
                }

                if (type == M4AVoiceType.Noise && entry.Panpot != 0)
                {
                    sf2.AddInstrumentGenerator(SF2Generator.Pan, new SF2GeneratorAmount {
                        Amount = (short)((entry.Panpot - 0xC0) * (500d / 0x80))
                    });
                }
                sf2.AddInstrumentGenerator(SF2Generator.SampleModes, new SF2GeneratorAmount {
                    Amount = 1
                });
                sf2.AddInstrumentGenerator(SF2Generator.SampleID, new SF2GeneratorAmount {
                    Amount = (short)sample
                });
            }