private string Copy_Hitsounds(HitsoundCopierVm arg, BackgroundWorker worker) { var doMutedIndex = arg.MutedIndex >= 0; var paths = arg.PathTo.Split('|'); var mapsDone = 0; var sampleSchema = new SampleSchema(); var reader = EditorReaderStuff.GetFullEditorReaderOrNot(); foreach (var pathTo in paths) { BeatmapEditor editorTo = EditorReaderStuff.GetNewestVersionOrNot(pathTo, reader);; Beatmap beatmapTo = editorTo.Beatmap; Beatmap beatmapFrom; if (!string.IsNullOrEmpty(arg.PathFrom)) { var editorFrom = EditorReaderStuff.GetNewestVersionOrNot(arg.PathFrom, reader); beatmapFrom = editorFrom.Beatmap; } else { // Copy from an empty beatmap similar to the map to copy to beatmapFrom = beatmapTo.DeepCopy(); beatmapFrom.HitObjects.Clear(); beatmapFrom.BeatmapTiming.Clear(); } Timeline processedTimeline; if (arg.CopyMode == 0) { // Every defined hitsound and sampleset on hitsound gets copied to their copyTo destination // Timelines var tlTo = beatmapTo.GetTimeline(); var tlFrom = beatmapFrom.GetTimeline(); var volumeMuteTimes = arg.CopyVolumes && arg.AlwaysPreserve5Volume ? new List <double>() : null; if (arg.CopyHitsounds) { ResetHitObjectHitsounds(beatmapTo); CopyHitsounds(arg, tlFrom, tlTo); } // Save tlo times where timingpoint volume is 5% // Timingpointchange all the undefined tlo from copyFrom volumeMuteTimes?.AddRange(from tloTo in tlTo.TimelineObjects where tloTo.CanCopy && Math.Abs(tloTo.SampleVolume) < Precision.DOUBLE_EPSILON && Math.Abs(tloTo.FenoSampleVolume - 5) < Precision.DOUBLE_EPSILON select tloTo.Time); // Volumes and samplesets and customindices greenlines get copied with timingpointchanges and allafter enabled var timingPointsChanges = beatmapFrom.BeatmapTiming.TimingPoints.Select(tp => new TimingPointsChange(tp, sampleset: arg.CopySampleSets, index: arg.CopySampleSets, volume: arg.CopyVolumes)).ToList(); // Apply the timingpoint changes TimingPointsChange.ApplyChanges(beatmapTo.BeatmapTiming, timingPointsChanges, true); processedTimeline = tlTo; // Return 5% volume to tlo that had it before if (volumeMuteTimes != null) { var timingPointsChangesMute = new List <TimingPointsChange>(); processedTimeline.GiveTimingPoints(beatmapTo.BeatmapTiming); // Exclude objects which use their own sample volume property instead foreach (var tloTo in processedTimeline.TimelineObjects.Where(o => Math.Abs(o.SampleVolume) < Precision.DOUBLE_EPSILON)) { if (volumeMuteTimes.Contains(tloTo.Time)) { // Add timingpointschange to copy timingpoint hitsounds var tp = tloTo.HitsoundTimingPoint.Copy(); tp.Offset = tloTo.Time; tp.Volume = 5; timingPointsChangesMute.Add(new TimingPointsChange(tp, volume: true)); } else { // Add timingpointschange to preserve index and volume var tp = tloTo.HitsoundTimingPoint.Copy(); tp.Offset = tloTo.Time; tp.Volume = tloTo.FenoSampleVolume; timingPointsChangesMute.Add(new TimingPointsChange(tp, volume: true)); } } // Apply the timingpoint changes TimingPointsChange.ApplyChanges(beatmapTo.BeatmapTiming, timingPointsChangesMute); } } else { // Smarty mode // Copy the defined hitsounds literally (not feno, that will be reserved for cleaner). Only the tlo that have been defined by copyFrom get overwritten. var tlTo = beatmapTo.GetTimeline(); var tlFrom = beatmapFrom.GetTimeline(); var timingPointsChanges = new List <TimingPointsChange>(); var mode = (GameMode)beatmapTo.General["Mode"].IntValue; var mapDir = editorTo.GetParentFolder(); var firstSamples = HitsoundImporter.AnalyzeSamples(mapDir); if (arg.CopyHitsounds) { CopyHitsounds(arg, beatmapTo, tlFrom, tlTo, timingPointsChanges, mode, mapDir, firstSamples, ref sampleSchema); } if (arg.CopyBodyHitsounds) { // Remove timingpoints in beatmapTo that are in a sliderbody/spinnerbody for both beatmapTo and BeatmapFrom foreach (var tp in from ho in beatmapTo.HitObjects from tp in ho.BodyHitsounds where beatmapFrom.HitObjects.Any(o => o.Time <tp.Offset && o.EndTime> tp.Offset) where !tp.Uninherited select tp) { beatmapTo.BeatmapTiming.Remove(tp); } // Get timingpointschanges for every timingpoint from beatmapFrom that is in a sliderbody/spinnerbody for both beatmapTo and BeatmapFrom timingPointsChanges.AddRange(from ho in beatmapFrom.HitObjects from tp in ho.BodyHitsounds where beatmapTo.HitObjects.Any(o => o.Time <tp.Offset && o.EndTime> tp.Offset) select new TimingPointsChange(tp.Copy(), sampleset: arg.CopySampleSets, index: arg.CopySampleSets, volume: arg.CopyVolumes)); } // Apply the timingpoint changes TimingPointsChange.ApplyChanges(beatmapTo.BeatmapTiming, timingPointsChanges); processedTimeline = tlTo; } if (arg.CopyStoryboardedSamples) { if (arg.CopyMode == 0) { beatmapTo.StoryboardSoundSamples.Clear(); } beatmapTo.GiveObjectsGreenlines(); processedTimeline.GiveTimingPoints(beatmapTo.BeatmapTiming); var mapDir = editorTo.GetParentFolder(); var firstSamples = HitsoundImporter.AnalyzeSamples(mapDir, true); var samplesTo = new HashSet <StoryboardSoundSample>(beatmapTo.StoryboardSoundSamples); var mode = (GameMode)beatmapTo.General["Mode"].IntValue; foreach (var sampleFrom in beatmapFrom.StoryboardSoundSamples) { if (arg.IgnoreHitsoundSatisfiedSamples) { var tloHere = processedTimeline.TimelineObjects.FindAll(o => Math.Abs(o.Time - sampleFrom.StartTime) <= arg.TemporalLeniency); var samplesHere = new HashSet <string>(); foreach (var tlo in tloHere) { foreach (var filename in tlo.GetPlayingFilenames(mode)) { var samplePath = Path.Combine(mapDir, filename); var fullPathExtLess = Path.Combine(Path.GetDirectoryName(samplePath), Path.GetFileNameWithoutExtension(samplePath)); if (firstSamples.Keys.Contains(fullPathExtLess)) { samplePath = firstSamples[fullPathExtLess]; } samplesHere.Add(samplePath); } } var sbSamplePath = Path.Combine(mapDir, sampleFrom.FilePath); var sbFullPathExtLess = Path.Combine(Path.GetDirectoryName(sbSamplePath), Path.GetFileNameWithoutExtension(sbSamplePath)); if (firstSamples.Keys.Contains(sbFullPathExtLess)) { sbSamplePath = firstSamples[sbFullPathExtLess]; } if (samplesHere.Contains(sbSamplePath)) { continue; } } // Add the StoryboardSoundSamples from beatmapFrom to beatmapTo if it doesn't already have the sample if (!samplesTo.Contains(sampleFrom)) { beatmapTo.StoryboardSoundSamples.Add(sampleFrom); } } // Sort the storyboarded samples beatmapTo.StoryboardSoundSamples.Sort(); } if (arg.MuteSliderends) { var timingPointsChanges = new List <TimingPointsChange>(); beatmapTo.GiveObjectsGreenlines(); processedTimeline.GiveTimingPoints(beatmapTo.BeatmapTiming); foreach (var tloTo in processedTimeline.TimelineObjects) { if (FilterMuteTlo(tloTo, beatmapTo, arg)) { // Set volume to 5%, remove all hitsounds, apply customindex and sampleset tloTo.SampleSet = arg.MutedSampleSet; tloTo.AdditionSet = 0; tloTo.Normal = false; tloTo.Whistle = false; tloTo.Finish = false; tloTo.Clap = false; tloTo.HitsoundsToOrigin(); // Add timingpointschange to copy timingpoint hitsounds var tp = tloTo.HitsoundTimingPoint.Copy(); tp.Offset = tloTo.Time; tp.SampleSet = arg.MutedSampleSet; tp.SampleIndex = arg.MutedIndex; tp.Volume = 5; timingPointsChanges.Add(new TimingPointsChange(tp, sampleset: true, index: doMutedIndex, volume: true)); } else { // Add timingpointschange to preserve index and volume and sampleset var tp = tloTo.HitsoundTimingPoint.Copy(); tp.Offset = tloTo.Time; timingPointsChanges.Add(new TimingPointsChange(tp, sampleset: true, index: doMutedIndex, volume: true)); } } // Apply the timingpoint changes TimingPointsChange.ApplyChanges(beatmapTo.BeatmapTiming, timingPointsChanges); } // Save the file editorTo.SaveFile(); // Export the sample schema if there are samples if (sampleSchema.Count > 0) { string exportFolder = MainWindow.ExportPath; DirectoryInfo di = new DirectoryInfo(exportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } HitsoundExporter.ExportSampleSchema(sampleSchema, exportFolder); System.Diagnostics.Process.Start(exportFolder); } // Update progressbar if (worker != null && worker.WorkerReportsProgress) { worker.ReportProgress(++mapsDone * 100 / paths.Length); } } return("Done!"); }
private string Make_Hitsounds(HitsoundStudioVm arg, BackgroundWorker worker, DoWorkEventArgs _) { string result = string.Empty; if (arg.HitsoundExportModeSetting == HitsoundStudioVm.HitsoundExportMode.Standard) { // Convert the multiple layers into packages that have the samples from all the layers at one specific time List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample); UpdateProgressBar(worker, 10); // Balance the volume between greenlines and samples HitsoundConverter.BalanceVolumes(samplePackages, 0, false); UpdateProgressBar(worker, 20); // Load the samples so validation can be done HashSet <SampleGeneratingArgs> allSampleArgs = new HashSet <SampleGeneratingArgs>(); foreach (SamplePackage sp in samplePackages) { allSampleArgs.UnionWith(sp.Samples.Select(o => o.SampleArgs)); } var loadedSamples = SampleImporter.ImportSamples(allSampleArgs); UpdateProgressBar(worker, 30); // Convert the packages to hitsounds that fit on an osu standard map CompleteHitsounds completeHitsounds = HitsoundConverter.GetCompleteHitsounds(samplePackages, loadedSamples); UpdateProgressBar(worker, 60); if (arg.ShowResults) { // Count the number of samples int samples = completeHitsounds.CustomIndices.SelectMany(ci => ci.Samples.Values) .Count(h => h.Any(SampleImporter.ValidateSampleArgs)); // Count the number of changes of custom index int greenlines = 0; int lastIndex = -1; foreach (var hit in completeHitsounds.Hitsounds.Where(hit => hit.CustomIndex != lastIndex)) { lastIndex = hit.CustomIndex; greenlines++; } result = $"Number of sample indices: {completeHitsounds.CustomIndices.Count}, " + $"Number of samples: {samples}, Number of greenlines: {greenlines}"; } if (arg.DeleteAllInExportFirst && (arg.ExportSamples || arg.ExportMap)) { // Delete all files in the export folder before filling it again DirectoryInfo di = new DirectoryInfo(arg.ExportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } } UpdateProgressBar(worker, 70); // Export the hitsound map and sound samples if (arg.ExportMap) { HitsoundExporter.ExportHitsounds(completeHitsounds.Hitsounds, arg.BaseBeatmap, arg.ExportFolder); } UpdateProgressBar(worker, 80); if (arg.ExportSamples) { HitsoundExporter.ExportCustomIndices(completeHitsounds.CustomIndices, arg.ExportFolder, loadedSamples); } UpdateProgressBar(worker, 99); } else if (arg.HitsoundExportModeSetting == HitsoundStudioVm.HitsoundExportMode.Coinciding) { List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample, 0, false); HitsoundConverter.BalanceVolumes(samplePackages, 0, false, true); UpdateProgressBar(worker, 20); Dictionary <SampleGeneratingArgs, SampleSoundGenerator> loadedSamples = null; Dictionary <SampleGeneratingArgs, string> sampleNames = null; Dictionary <SampleGeneratingArgs, Vector2> samplePositions = null; var hitsounds = HitsoundConverter.GetHitsounds(samplePackages, ref loadedSamples, ref sampleNames, ref samplePositions); // Load the samples so validation can be done UpdateProgressBar(worker, 50); if (arg.ShowResults) { result = "Number of sample indices: 0, " + $"Number of samples: {loadedSamples.Count}, Number of greenlines: 0"; } if (arg.DeleteAllInExportFirst && (arg.ExportSamples || arg.ExportMap)) { // Delete all files in the export folder before filling it again DirectoryInfo di = new DirectoryInfo(arg.ExportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } } UpdateProgressBar(worker, 60); if (arg.ExportMap) { HitsoundExporter.ExportHitsounds(hitsounds, arg.BaseBeatmap, arg.ExportFolder, false); } UpdateProgressBar(worker, 70); if (arg.ExportSamples) { HitsoundExporter.ExportLoadedSamples(loadedSamples, arg.ExportFolder, sampleNames); } } else if (arg.HitsoundExportModeSetting == HitsoundStudioVm.HitsoundExportMode.Storyboard) { List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample, 0, false); HitsoundConverter.BalanceVolumes(samplePackages, 0, false, true); UpdateProgressBar(worker, 20); Dictionary <SampleGeneratingArgs, SampleSoundGenerator> loadedSamples = null; Dictionary <SampleGeneratingArgs, string> sampleNames = null; Dictionary <SampleGeneratingArgs, Vector2> samplePositions = null; var hitsounds = HitsoundConverter.GetHitsounds(samplePackages, ref loadedSamples, ref sampleNames, ref samplePositions); // Load the samples so validation can be done UpdateProgressBar(worker, 50); if (arg.ShowResults) { result = "Number of sample indices: 0, " + $"Number of samples: {loadedSamples.Count}, Number of greenlines: 0"; } if (arg.DeleteAllInExportFirst && (arg.ExportSamples || arg.ExportMap)) { // Delete all files in the export folder before filling it again DirectoryInfo di = new DirectoryInfo(arg.ExportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } } UpdateProgressBar(worker, 60); if (arg.ExportMap) { HitsoundExporter.ExportHitsounds(hitsounds, arg.BaseBeatmap, arg.ExportFolder, false, true); } UpdateProgressBar(worker, 70); if (arg.ExportSamples) { HitsoundExporter.ExportLoadedSamples(loadedSamples, arg.ExportFolder, sampleNames); } } // Open export folder if (arg.ExportSamples || arg.ExportMap) { System.Diagnostics.Process.Start(arg.ExportFolder); } // Collect garbage GC.Collect(); UpdateProgressBar(worker, 100); return(result); }
private void Make_Hitsounds(Arguments arg, BackgroundWorker worker, DoWorkEventArgs _) { if (arg.Debug) { // Convert the multiple layers into packages that have the samples from all the layers at one specific time List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample); UpdateProgressBar(worker, 10); // Balance the volume between greenlines and samples HitsoundConverter.BalanceVolumes(samplePackages, new VolumeBalancingArgs(0, false)); UpdateProgressBar(worker, 20); // Load the samples so validation can be done HashSet <SampleGeneratingArgs> allSampleArgs = new HashSet <SampleGeneratingArgs>(); foreach (SamplePackage sp in samplePackages) { allSampleArgs.UnionWith(sp.Samples.Select(o => o.SampleArgs)); } var loadedSamples = SampleImporter.ImportSamples(allSampleArgs); UpdateProgressBar(worker, 40); // Convert the packages to hitsounds that fit on an osu standard map CompleteHitsounds completeHitsounds = HitsoundConverter.GetCompleteHitsounds(samplePackages, loadedSamples); UpdateProgressBar(worker, 60); int samples = completeHitsounds.CustomIndices.SelectMany(ci => ci.Samples.Values).Count(h => h.Any(SampleImporter.ValidateSampleArgs)); UpdateProgressBar(worker, 80); int greenlines = 0; int lastIndex = -1; foreach (var hit in completeHitsounds.Hitsounds.Where(hit => hit.CustomIndex != lastIndex)) { lastIndex = hit.CustomIndex; greenlines++; } UpdateProgressBar(worker, 100); MessageBox.Show( $"Number of sample indices: {completeHitsounds.CustomIndices.Count}, Number of samples: {samples}, Number of greenlines: {greenlines}"); } else { // Convert the multiple layers into packages that have the samples from all the layers at one specific time List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample); UpdateProgressBar(worker, 10); // Balance the volume between greenlines and samples HitsoundConverter.BalanceVolumes(samplePackages, new VolumeBalancingArgs(0, false)); UpdateProgressBar(worker, 20); // Load the samples so validation can be done HashSet <SampleGeneratingArgs> allSampleArgs = new HashSet <SampleGeneratingArgs>(); foreach (SamplePackage sp in samplePackages) { allSampleArgs.UnionWith(sp.Samples.Select(o => o.SampleArgs)); } var loadedSamples = SampleImporter.ImportSamples(allSampleArgs); UpdateProgressBar(worker, 30); // Convert the packages to hitsounds that fit on an osu standard map CompleteHitsounds completeHitsounds = HitsoundConverter.GetCompleteHitsounds(samplePackages, loadedSamples); UpdateProgressBar(worker, 60); // Delete all files in the export folder before filling it again DirectoryInfo di = new DirectoryInfo(arg.ExportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } UpdateProgressBar(worker, 80); // Export the hitsound .osu and sound samples HitsoundExporter.ExportCompleteHitsounds(arg.ExportFolder, arg.BaseBeatmap, completeHitsounds, loadedSamples); UpdateProgressBar(worker, 99); // Open export folder System.Diagnostics.Process.Start(arg.ExportFolder); } // Collect garbage GC.Collect(); UpdateProgressBar(worker, 100); }
private string Make_Hitsounds(HitsoundStudioVm arg, BackgroundWorker worker, DoWorkEventArgs _) { string result = string.Empty; bool validateSampleFile = !(arg.SingleSampleExportFormat == HitsoundExporter.SampleExportFormat.MidiChords || arg.MixedSampleExportFormat == HitsoundExporter.SampleExportFormat.MidiChords); var comparer = new SampleGeneratingArgsComparer(validateSampleFile); if (arg.HitsoundExportModeSetting == HitsoundStudioVm.HitsoundExportMode.Standard) { // Convert the multiple layers into packages that have the samples from all the layers at one specific time // Don't add default sample when exporting midi files because that's not a final export. List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample, arg.ZipLayersLeniency, validateSampleFile); UpdateProgressBar(worker, 10); // Balance the volume between greenlines and samples HitsoundConverter.BalanceVolumes(samplePackages, 0, false); UpdateProgressBar(worker, 20); // Load the samples so validation can be done HashSet <SampleGeneratingArgs> allSampleArgs = new HashSet <SampleGeneratingArgs>(comparer); foreach (SamplePackage sp in samplePackages) { allSampleArgs.UnionWith(sp.Samples.Select(o => o.SampleArgs)); } var loadedSamples = SampleImporter.ImportSamples(allSampleArgs, comparer); UpdateProgressBar(worker, 30); // Convert the packages to hitsounds that fit on an osu standard map CompleteHitsounds completeHitsounds = HitsoundConverter.GetCompleteHitsounds(samplePackages, loadedSamples, arg.UsePreviousSampleSchema ? arg.PreviousSampleSchema.GetCustomIndices() : null, arg.AllowGrowthPreviousSampleSchema, arg.FirstCustomIndex, validateSampleFile, comparer); UpdateProgressBar(worker, 60); // Save current sample schema if (!arg.UsePreviousSampleSchema) { arg.PreviousSampleSchema = new SampleSchema(completeHitsounds.CustomIndices); } else if (arg.AllowGrowthPreviousSampleSchema) { arg.PreviousSampleSchema.MergeWith(new SampleSchema(completeHitsounds.CustomIndices)); } if (arg.ShowResults) { // Count the number of samples int samples = completeHitsounds.CustomIndices.SelectMany(ci => ci.Samples.Values) .Count(h => h.Any(o => SampleImporter.ValidateSampleArgs(o, loadedSamples, validateSampleFile))); // Count the number of changes of custom index int greenlines = 0; int lastIndex = -1; foreach (var hit in completeHitsounds.Hitsounds.Where(hit => hit.CustomIndex != lastIndex)) { lastIndex = hit.CustomIndex; greenlines++; } result = $"Number of sample indices: {completeHitsounds.CustomIndices.Count}, " + $"Number of samples: {samples}, Number of greenlines: {greenlines}"; } if (arg.DeleteAllInExportFirst && (arg.ExportSamples || arg.ExportMap)) { // Delete all files in the export folder before filling it again DirectoryInfo di = new DirectoryInfo(arg.ExportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } } UpdateProgressBar(worker, 70); // Export the hitsound map and sound samples if (arg.ExportMap) { HitsoundExporter.ExportHitsounds(completeHitsounds.Hitsounds, arg.BaseBeatmap, arg.ExportFolder, arg.HitsoundDiffName, arg.HitsoundExportGameMode, true, false); } UpdateProgressBar(worker, 80); if (arg.ExportSamples) { HitsoundExporter.ExportCustomIndices(completeHitsounds.CustomIndices, arg.ExportFolder, loadedSamples, arg.SingleSampleExportFormat, arg.MixedSampleExportFormat, comparer); } UpdateProgressBar(worker, 99); } else if (arg.HitsoundExportModeSetting == HitsoundStudioVm.HitsoundExportMode.Coinciding) { List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample, 0, false); HitsoundConverter.BalanceVolumes(samplePackages, 0, false, true); UpdateProgressBar(worker, 20); Dictionary <SampleGeneratingArgs, SampleSoundGenerator> loadedSamples = null; Dictionary <SampleGeneratingArgs, string> sampleNames = arg.UsePreviousSampleSchema ? arg.PreviousSampleSchema?.GetSampleNames(comparer) : null; Dictionary <SampleGeneratingArgs, Vector2> samplePositions = null; var hitsounds = HitsoundConverter.GetHitsounds(samplePackages, ref loadedSamples, ref sampleNames, ref samplePositions, arg.HitsoundExportGameMode == GameMode.Mania, arg.AddCoincidingRegularHitsounds, arg.AllowGrowthPreviousSampleSchema, validateSampleFile, comparer); // Save current sample schema if (!arg.UsePreviousSampleSchema || arg.PreviousSampleSchema == null) { arg.PreviousSampleSchema = new SampleSchema(sampleNames); } else if (arg.AllowGrowthPreviousSampleSchema) { arg.PreviousSampleSchema.MergeWith(new SampleSchema(sampleNames)); } // Load the samples so validation can be done UpdateProgressBar(worker, 50); if (arg.ShowResults) { result = "Number of sample indices: 0, " + $"Number of samples: {loadedSamples.Count}, Number of greenlines: 0"; } if (arg.DeleteAllInExportFirst && (arg.ExportSamples || arg.ExportMap)) { // Delete all files in the export folder before filling it again DirectoryInfo di = new DirectoryInfo(arg.ExportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } } UpdateProgressBar(worker, 60); if (arg.ExportMap) { HitsoundExporter.ExportHitsounds(hitsounds, arg.BaseBeatmap, arg.ExportFolder, arg.HitsoundDiffName, arg.HitsoundExportGameMode, false, false); } UpdateProgressBar(worker, 70); if (arg.ExportSamples) { HitsoundExporter.ExportLoadedSamples(loadedSamples, arg.ExportFolder, sampleNames, arg.SingleSampleExportFormat, comparer); } } else if (arg.HitsoundExportModeSetting == HitsoundStudioVm.HitsoundExportMode.Storyboard) { List <SamplePackage> samplePackages = HitsoundConverter.ZipLayers(arg.HitsoundLayers, arg.DefaultSample, 0, false); HitsoundConverter.BalanceVolumes(samplePackages, 0, false, true); UpdateProgressBar(worker, 20); Dictionary <SampleGeneratingArgs, SampleSoundGenerator> loadedSamples = null; Dictionary <SampleGeneratingArgs, string> sampleNames = arg.UsePreviousSampleSchema ? arg.PreviousSampleSchema?.GetSampleNames(comparer) : null; Dictionary <SampleGeneratingArgs, Vector2> samplePositions = null; var hitsounds = HitsoundConverter.GetHitsounds(samplePackages, ref loadedSamples, ref sampleNames, ref samplePositions, false, false, arg.AllowGrowthPreviousSampleSchema, validateSampleFile, comparer); // Save current sample schema if (!arg.UsePreviousSampleSchema || arg.PreviousSampleSchema == null) { arg.PreviousSampleSchema = new SampleSchema(sampleNames); } else if (arg.AllowGrowthPreviousSampleSchema) { arg.PreviousSampleSchema.MergeWith(new SampleSchema(sampleNames)); } // Load the samples so validation can be done UpdateProgressBar(worker, 50); if (arg.ShowResults) { result = "Number of sample indices: 0, " + $"Number of samples: {loadedSamples.Count}, Number of greenlines: 0"; } if (arg.DeleteAllInExportFirst && (arg.ExportSamples || arg.ExportMap)) { // Delete all files in the export folder before filling it again DirectoryInfo di = new DirectoryInfo(arg.ExportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } } UpdateProgressBar(worker, 60); if (arg.ExportMap) { HitsoundExporter.ExportHitsounds(hitsounds, arg.BaseBeatmap, arg.ExportFolder, arg.HitsoundDiffName, arg.HitsoundExportGameMode, false, true); } UpdateProgressBar(worker, 70); if (arg.ExportSamples) { HitsoundExporter.ExportLoadedSamples(loadedSamples, arg.ExportFolder, sampleNames, arg.SingleSampleExportFormat, comparer); } } // Open export folder if (arg.ExportSamples || arg.ExportMap) { System.Diagnostics.Process.Start("explorer.exe", arg.ExportFolder); } // Collect garbage GC.Collect(); UpdateProgressBar(worker, 100); return(result); }