public Sequence(SequenceGroup sequenceGroup, string name, byte[] data) { this.sequenceGroup = sequenceGroup; this.name = name; this.data = data; this.messages = null; }
// Parse sequence from ascii string public static Sequence BuildSequence(SequenceGroup sequenceGroup, string name, string byteStr) { var data = new List <byte>(); // Parse ascii hex byte values var split = byteStr.Trim().Split(new char[] { ' ', '\t' }); foreach (var bs in split) { data.Add(byte.Parse(bs, System.Globalization.NumberStyles.AllowHexSpecifier)); } return(new Sequence(sequenceGroup, name, data.ToArray())); }
private static void BuildSequences(SequenceGroup sequenceGroup, string sequenceGroupName, List <ParsedItem> items) { var sequenceItem = items.Find(pi => pi.Section == Section.Sequences && pi.Name == sequenceGroupName); if (sequenceItem == null) { throw new InvalidDataException("Reference to unknown sequence group name " + sequenceGroupName); } foreach (var kv in sequenceItem.Values) { string name = kv.Key; string bytes = kv.Value; var sequence = Sequence.BuildSequence(sequenceGroup, name, bytes); sequenceGroup.Sequences.Add(sequence); } }
// Traverses the list of parsed items to build the instruments private static List <Instrument> ConvertItemsToInstruments(List <ParsedItem> items) { var instruments = new List <Instrument>(); // Process all instruments ParsedItem instrumentItem; while ((instrumentItem = ExtractParsedItemBySection(items, Section.Instrument)) != null) { var drumBanks = new List <int>(); // First pass over the attributes to retreive the bank select method and which banks are drum var patchSelMethod = EPatchSelectionMethod.Normal; var overlapSupport = EOverlapSupport.None; bool supportsPitchBend = false; bool supportsAfterTouch = false; string vstiName = null; foreach (var kvp in instrumentItem.Values) { if (kvp.Key == "BankSelMethod") { patchSelMethod = (EPatchSelectionMethod)int.Parse(kvp.Value); } else if (kvp.Key == "OverlapSupport") { overlapSupport = (EOverlapSupport)int.Parse(kvp.Value); } else if (kvp.Key == "SupportsPitchBend") { supportsPitchBend = int.Parse(kvp.Value) != 0; } else if (kvp.Key == "SupportsAfterTouch") { supportsAfterTouch = int.Parse(kvp.Value) != 0; } else if (kvp.Key == "VSTIName") { vstiName = kvp.Value; } else if (kvp.Key.StartsWith("Drum[") && kvp.Value == "1") { // Note: we only support whole banks defined as drum, not individual patches within a bank var drumargs = kvp.Key.Substring(5); var split = drumargs.Split(new char[] { ',', ']' }); int bank = (split[0] == "*") ? -1 : int.Parse(split[0]); // ignore split[1], which is the patch number. Assume it is '*' drumBanks.Add(bank); } } // Create the instrument var instrument = new Instrument(instrumentItem.Name, patchSelMethod, overlapSupport, supportsAfterTouch, supportsPitchBend, vstiName); // Populate it based on the name/value entries foreach (var kv in instrumentItem.Values) { string kw = kv.Key; string val = kv.Value; if (kw.StartsWith("Drum[")) { // Already processed above continue; } if (kw.StartsWith("Patch[")) { var numStr = kw.Substring(6); numStr = numStr.Split(']')[0]; if (numStr == "*") { // Patch[*] defines the default bank for unknown bank numbers. // It can be either a bank name or a special string like 0...127 // We ignore it. } else { uint bankNumber = uint.Parse(numStr); string bankName = val; // Find if this is a drum bank bool drumBank = drumBanks.Contains(-1) || drumBanks.Contains((int)bankNumber); // Create the bank var bank = new Bank(instrument, bankName, bankNumber, drumBank); // Populate the patches BuildBank(bank, bankName, items); // Add it to the instrument instrument.Banks.Add(bank); } continue; } if (kw.StartsWith("Sequence[")) { var numStr = kw.Substring(9); numStr = numStr.Split(']')[0]; uint seqGrpNum = uint.Parse(numStr); var sequenceGroup = new SequenceGroup(instrument, val, seqGrpNum); instrument.SequenceGroups.Add(sequenceGroup); BuildSequences(sequenceGroup, val, items); continue; } switch (kw) { case "Control": BuildControllers(instrument, val, items); break; case "RPN": BuildProgramNumbers(instrument, val, items, true); break; case "NRPN": BuildProgramNumbers(instrument, val, items, false); break; case "Patch": BuildControllers(instrument, val, items); break; case "BankSelMethod": case "OverlapSupport": case "SupportsPitchBend": case "SupportsAfterTouch": case "VSTIName": // Already processed above break; default: throw new InvalidDataException("Unknown directive in instrument section: " + kw); } } // If no patches are defined, define a dummy one if (instrument.Banks.Count == 0) { instrument.Banks.Add(new Bank(instrument, "Default", 0, false)); } if (instrument.Banks[0].Patches.Count == 0) { instrument.Banks[0].Patches.Add(new Patch(instrument.Banks[0], "[No patches]", 0)); } // Add it to the collection instruments.Add(instrument); } return(instruments); }