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; } }
internal M4ASMulti(M4AVoice ks) : base(ks) { Table = VoiceTable.LoadTable <M4AVoiceTable>(ks.Table, true); var keys = ROM.Instance.ReadBytes(256, ks.Keys); var loading = new List <Triple <byte, byte, byte> >(); // Key, min, max int prev = -1; for (int i = 0; i < 256; 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(); }
void AddTable(M4AVoiceTable table, bool saveAfter7F, bool isNewInst) { int amt = saveAfter7F ? 0xFF : 0x7F; for (ushort i = 0; i <= amt; i++) { var voice = table[i]; if (instruments.Contains(voice)) { continue; } instruments.Add(voice); if (isNewInst) { string name = "Instrument " + i; AddPreset(name, i); sf2.AddInstrument(name); } if (voice is M4ASDirect direct) { if (!isNewInst) { AddDirect(direct, (byte)i, (byte)i); sf2.AddINSTGenerator(SF2Generator.overridingRootKey, new GenAmountType((ushort)(i - (direct.Voice.GetRootNote() - 60)))); } else { AddDirect(direct); } } else if (voice.Voice is M4APSG_Square_1 || voice.Voice is M4APSG_Square_2 || voice.Voice is M4APSG_Wave || voice.Voice is M4APSG_Noise) { var m4 = (M4AVoice)voice.Voice; if (!isNewInst) { if (voice.Voice is M4APSG_Noise) { AddPSG(m4, (byte)i, (byte)i); sf2.AddINSTGenerator(SF2Generator.overridingRootKey, new GenAmountType((ushort)(i - (m4.RootNote - 60)))); } } else { AddPSG(m4); if (!(voice.Voice is M4APSG_Noise)) { sf2.AddINSTGenerator(SF2Generator.overridingRootKey, new GenAmountType(69)); } } } else if (isNewInst && voice is M4ASMulti multi) { foreach (var key in multi.Keys) { if (key.Item1 > amt || key.Item2 > amt) { continue; } var subvoice = multi.Table[key.Item1]; if (subvoice is M4ASDirect subdirect) { AddDirect(subdirect, key.Item2, key.Item3); } } } else if (voice is M4ASDrum drum) { AddTable(drum.Table, saveAfter7F, false); } } }
internal M4ASDrum(M4AVoice d) : base(d) { Table = VoiceTable.LoadTable <M4AVoiceTable>(d.Table, true); }
void AddTable(M4AVoiceTable table, bool saveAfter7F, bool fromDrum) { int tableOffset = table.GetOffset(); if (addedTables.Contains(tableOffset)) { return; } addedTables.Add(tableOffset); int amt = saveAfter7F ? 0xFF : 0x7F; for (int i = 0; i <= amt; i++) { var voice = table[i]; //Console.WriteLine("{0} {1} {2}", i, fromDrum, voice); if (!fromDrum) { string name = "Instrument " + i; sf2.AddPreset(name, (ushort)i, 0); //sf2.AddPreset(name, (ushort)i, (ushort)(voice is M4AWrappedDrum ? 128 : 0)); sf2.AddPresetBag(); sf2.AddPresetGenerator(SF2Generator.Instrument, new SF2GeneratorAmount { Amount = (short)sf2.AddInstrument(name) }); } if (voice is M4AWrappedDirect direct) { if (fromDrum) { AddDirect(direct, (byte)i, (byte)i); sf2.AddInstrumentGenerator(SF2Generator.OverridingRootKey, new SF2GeneratorAmount { Amount = (short)(i - (direct.Voice.GetRootNote() - 60)) }); } else { AddDirect(direct); } } else if (voice is M4AWrappedKeySplit keySplit) { if (fromDrum) { Console.WriteLine("Skipping nested key split within a drum at table 0x{0:X7} index {1}.", tableOffset, i); continue; } foreach (var key in keySplit.Keys) { if (key.Item1 > amt || key.Item2 >= 0x80) { continue; } var subvoice = keySplit.Table[key.Item1]; var m4 = (M4AVoiceEntry)voice.Voice; if (subvoice is M4AWrappedDirect subdirect) { AddDirect(subdirect, key.Item2, key.Item3); } else if (m4.Type == (int)M4AVoiceFlags.KeySplit) { Console.WriteLine("Skipping nested key split within a key split at table 0x{0:X7} index {1}.", tableOffset, i); } else if (m4.Type == (int)M4AVoiceFlags.Drum) { Console.WriteLine("Skipping nested drum within a key split at table 0x{0:X7} index {1}.", tableOffset, i); } else if (m4.IsGBInstrument()) { AddPSG(m4); } else // Invalid { Console.WriteLine("Skipping invalid instrument within a key split at table 0x{0:X7} index {1}.", tableOffset, i); } } } else if (voice is M4AWrappedDrum drum) { if (fromDrum) { Console.WriteLine("Skipping nested drum within a drum at table 0x{0:X7} index {1}.", tableOffset, i); continue; } AddTable(drum.Table, saveAfter7F, true); } else { var m4 = (M4AVoiceEntry)voice.Voice; if (m4.IsInvalid()) { Console.WriteLine("Skipping invalid instrument at table 0x{0:X7} index {1}.", tableOffset, i); continue; } if (fromDrum) { AddPSG(m4, (byte)i, (byte)i); sf2.AddInstrumentGenerator(SF2Generator.OverridingRootKey, new SF2GeneratorAmount { Amount = (short)(i - (m4.GetRootNote() - 60)) }); } else { AddPSG(m4); } } } }