public override async Task DoScan() { InitializeInternal(); var parser = new KoaBankFileParser(ExportConfig.KoaFileHeader, ExportConfig.KoaPresetNameLength, ExportConfig.KoaPresetLength, ExportConfig.KoaNumPresets); var converter = new RolandConverter(ExportConfig); converter.LoadDefinitionFromCsvString(Encoding.UTF8.GetString(GetDefinitionData())); foreach (var presetFile in PresetFiles) { var presets = parser.Parse(presetFile); var presetBankName = Path.GetFileNameWithoutExtension(presetFile); foreach (var parsedPreset in presets) { converter.SetFileMemory(parsedPreset.PresetData); var preset = new PresetParserMetadata { PresetName = parsedPreset.PresetName.Trim(), Plugin = PluginInstance.Plugin, BankPath = presetBankName, SourceFile = presetFile + ":" + parsedPreset.Index }; PostProcessPreset(preset, converter); await DataPersistence.PersistPreset(preset, converter.Export()); } } await base.DoScan(); }
protected virtual void PostProcessPreset(PresetParserMetadata metadata, RolandConverter converter) { }
protected override void PostProcessPreset(PresetParserMetadata metadata, RolandConverter converter) { string typeName = null; string subTypeName = null; string characteristicName = null; switch (converter.GetMemoryValue("fm.pat.com.patCategory")) { case 1: // AC.PIANO typeName = "Piano / Keys"; characteristicName = "Acoustic"; break; case 2: // EL.PIANO typeName = "Piano / Keys"; subTypeName = "Electric Piano"; break; case 3: // KEYBOARDS typeName = "Piano / Keys"; break; case 4: // BELL typeName = "Mallet Instruments"; subTypeName = "Bell"; break; case 5: // MALLET typeName = "Mallet Instruments"; break; case 6: // ORGAN typeName = "Organ"; break; case 7: // ACCORDION typeName = "Organ"; subTypeName = "Accordion"; break; case 8: // HARMONICA typeName = "Reed Instruments"; subTypeName = "Harmonica"; break; case 9: // AC.GUITAR typeName = "Guitar"; subTypeName = "Acoustic"; characteristicName = "Acoustic"; break; case 10: // EL.GUITAR typeName = "Guitar"; subTypeName = "Electric"; characteristicName = "Electric"; break; case 11: // DIST.GUITAR typeName = "Guitar"; subTypeName = "Electric"; characteristicName = "Distorted"; break; case 12: // BASS typeName = "Bass"; break; case 13: // SYNTH BASS typeName = "Synth Bass"; break; case 14: // STRINGS typeName = "Bowed Strings"; break; case 15: // ORCHESTRA typeName = "Gerne"; subTypeName = "Orchestral"; break; case 16: // HIT&STAB characteristicName = "Stabs & Hits"; break; case 17: // WIND typeName = "Ethnic World"; subTypeName = "Flutes & Wind"; break; case 18: // FLUTE typeName = "Flute"; break; case 19: // AC.BRASS typeName = "Brass"; break; case 20: // SYNTH BRASS typeName = "Brass"; subTypeName = "Synth"; characteristicName = "Synthetic"; break; case 21: // SAX typeName = "Reed Instruments"; subTypeName = "Saxophone"; break; case 22: // HARD LEAD typeName = "Synth Lead"; characteristicName = "Hard"; break; case 23: // SOFT LEAD typeName = "Synth Lead"; characteristicName = "Soft / Warm"; break; case 24: // TECHNO SYNTH typeName = "Genre"; subTypeName = "Techno"; break; case 25: // PULSATING typeName = "Arp/Sequence"; subTypeName = "Pulsing"; break; case 26: // SYNTH FX typeName = "Synth Misc"; subTypeName = "FX"; break; case 27: // OTHER SYNTH typeName = "Synth Misc"; break; case 28: // BRIGHT PAD typeName = "Synth Pad"; characteristicName = "Bright"; break; case 29: // SOFT PAD typeName = "Synth Pad"; characteristicName = "Soft / Warm"; break; case 30: // VOX characteristicName = "Vox"; break; case 31: // PLUCKED characteristicName = "Pluck"; break; case 32: // ETHNIC typeName = "Ethnic World"; break; case 33: // FRETTED break; case 34: // PERCUSSION typeName = "Percussion"; break; case 35: // SOUND FX typeName = "Sound Effects"; break; case 36: // BEAT&GROOVE break; case 37: // DRUMS typeName = "Drums"; break; case 38: // COMBINATION typeName = "Combination"; break; } if (typeName != null) { metadata.Types.Add(new Type() { TypeName = typeName, SubTypeName = subTypeName }); } if (characteristicName != null) { metadata.Characteristics.Add(new Characteristic() { CharacteristicName = characteristicName }); } }
static void Main() { /* var b = new byte[] {0x46, 0x61}; * * Debug.WriteLine(RolandMemory.DecodeValueAsInt(b, 2, 7)); * return;*/ var culture = CultureInfo.GetCultureInfo("en-US"); //Culture for any thread CultureInfo.DefaultThreadCurrentCulture = culture; //Culture for UI in any thread CultureInfo.DefaultThreadCurrentUICulture = culture; CultureInfo.CurrentUICulture = culture; CultureInfo.CurrentCulture = culture; var doStructureDump = false; foreach (var configFile in Directory.EnumerateFiles( @"DevData\Roland", "TestConfig.json", SearchOption.AllDirectories)) { /*if (!configFile.Contains("SYSTEM-1")) * { * continue; * }*/ var rolandTestConfig = RolandTestConfig.LoadTestConfig(configFile); var serviceLocator = ServiceLocator.Default; FrontendInitializer.RegisterTypes(serviceLocator); FrontendInitializer.Initialize(serviceLocator); var remoteVstService = serviceLocator.ResolveType <RemoteVstService>(); var plugin = new Plugin { PluginLocation = new PluginLocation { DllPath = rolandTestConfig.Plugin } }; var pluginInstance = remoteVstService.GetInteractivePluginInstance(plugin, false); pluginInstance.LoadPlugin().Wait(); var koaParser = new KoaBankFileParser(rolandTestConfig.ExportConfig.KoaFileHeader, rolandTestConfig.ExportConfig.KoaPresetNameLength, rolandTestConfig.ExportConfig.KoaPresetLength, rolandTestConfig.ExportConfig.KoaNumPresets); Directory.CreateDirectory(rolandTestConfig.OutputDirectory); var definitionCsv = Path.Combine(rolandTestConfig.OutputDirectory, "RolandScript.csv"); var rolandScript = ParseScript(rolandTestConfig, rolandTestConfig.ExportConfig); rolandScript.ConvertToCsv(definitionCsv); var converter = new RolandConverter(rolandTestConfig.ExportConfig); converter.LoadDefinitionFromCsvFile(definitionCsv); var hadOriginal = false; foreach (var patchDirectory in rolandTestConfig.PresetDirectories) { Debug.WriteLine($"Processing patch directory {patchDirectory}"); foreach (var patchFile in Directory.EnumerateFiles( patchDirectory, "*.bin", SearchOption.AllDirectories)) { var presets = koaParser.Parse(patchFile); Debug.WriteLine($"Processed patch file {patchFile}, found {presets.Count} patches"); foreach (var preset in presets) { var currentPreset = $"{Path.GetFileName(preset.BankFile)}.{preset.Index}.{PathUtils.SanitizeFilename(preset.PresetName.Trim())}"; var outputFile = Path.Combine(rolandTestConfig.OutputDirectory, currentPreset); var originalPatchDump = outputFile + ".originalpatchdump"; var okPluginPatchDumpFile = outputFile + ".okpluginpatchdump"; converter.SetFileMemory(preset.PresetData); var memory = new RolandMemory(); memory.SetFileData(preset.PresetData); Debug.WriteLine($"Processed {currentPreset}"); var sw = new Stopwatch(); sw.Start(); var exportedData = converter.Export(); try { var sortedDump = RolandPatchDump.SortDump(exportedData); byte[] sortedPluginDump; if (File.Exists(okPluginPatchDumpFile)) { sortedPluginDump = RolandPatchDump.SortDump(File.ReadAllBytes(okPluginPatchDumpFile)); } else { pluginInstance.SetChunk(sortedDump, false); sortedPluginDump = RolandPatchDump.SortDump(pluginInstance.GetChunk(false)); } var pluginDumpVsGeneratedDumpErrors = RolandPatchDump.ComparePatchDumps(sortedPluginDump, sortedDump, rolandTestConfig, rolandScript); var sortedDumpEqual = pluginDumpVsGeneratedDumpErrors.Count == 0; var sortedOriginalDumpEqual = true; var sortedOriginalDumpEqualToPluginDump = false; var originalDumpVsGeneratedDumpErrors = new List <string>(); if (File.Exists(originalPatchDump)) { var sortedOriginal = RolandPatchDump.SortDump(File.ReadAllBytes(originalPatchDump)); originalDumpVsGeneratedDumpErrors = RolandPatchDump.ComparePatchDumps(sortedOriginal, sortedDump, rolandTestConfig, rolandScript); sortedOriginalDumpEqual = originalDumpVsGeneratedDumpErrors.Count == 0; hadOriginal = true; } var patchDumpFile = outputFile + ".patchdump"; var structureDumpFile = outputFile + ".structure"; var pluginPatchDumpFile = outputFile + ".pluginpatchdump"; var presetDataFile = outputFile + ".presetdata"; File.WriteAllBytes(patchDumpFile, sortedDump); File.WriteAllBytes(pluginPatchDumpFile, sortedPluginDump); File.WriteAllBytes(presetDataFile, preset.PresetData); if (File.Exists(originalPatchDump)) { memory.Load(originalPatchDump); var sortedOriginal = RolandPatchDump.SortDump(File.ReadAllBytes(originalPatchDump)); File.WriteAllBytes(originalPatchDump + ".sorted", sortedOriginal); } if (doStructureDump || (!sortedDumpEqual || !sortedOriginalDumpEqual)) { File.WriteAllText(structureDumpFile, rolandScript.Dump(memory)); } if ((!sortedDumpEqual || !sortedOriginalDumpEqual) && !sortedOriginalDumpEqualToPluginDump) { // Last resort: Compare the plugin dump against the sorted original dump because of "if float goes in, float comes out slightly different" Debug.WriteLine("Plugin Dump vs Generated Dump Errors"); Debug.WriteLine("------------------------------------"); Debug.WriteLine(string.Join(Environment.NewLine, pluginDumpVsGeneratedDumpErrors)); Debug.WriteLine("Original Dump vs Generated Dump Errors"); Debug.WriteLine("------------------------------------"); Debug.WriteLine(string.Join(Environment.NewLine, originalDumpVsGeneratedDumpErrors)); throw new Exception( $"Dumps not equal. sortedDumpEqual {sortedDumpEqual} sortedOriginalDumpEqual {sortedOriginalDumpEqual}"); } if (!File.Exists(okPluginPatchDumpFile)) { File.Copy(pluginPatchDumpFile, okPluginPatchDumpFile); } } catch (Exception e) { var structureDumpFile = outputFile + ".structure"; File.WriteAllText(structureDumpFile, rolandScript.Dump(memory)); throw e; } Debug.WriteLine($"{sw.Elapsed.TotalMilliseconds} ms"); } } } if (!hadOriginal) { throw new Exception($"Had no original to test against for config {configFile}"); } } // return; }