/// <summary> /// Makes a new smaller list of CustomIndices which still fits every CustomIndex /// </summary> /// <param name="customIndices">The CustomIndices that it has to support</param> /// <returns></returns> public static List <CustomIndex> OptimizeCustomIndices(List <CustomIndex> customIndices) { List <CustomIndex> newCustomIndices = new List <CustomIndex>(); // Try merging together CustomIndices as much as possible foreach (CustomIndex ci in customIndices) { CustomIndex mergingWith = newCustomIndices.Find(o => o.CanMerge(ci)); if (mergingWith != null) { mergingWith.MergeWith(ci); } else { // There is no CustomIndex to merge with so add a new one newCustomIndices.Add(ci.Copy()); } } // Remove any CustomIndices that might be obsolete newCustomIndices.RemoveAll(o => !IsUseful(o, newCustomIndices.Except(new[] { o }).ToList(), customIndices)); return(newCustomIndices); }
/// <summary> /// /// </summary> /// <returns></returns> public CustomIndex Copy() { CustomIndex ci = new CustomIndex(Index, Comparer); ci.MergeWith(this); return(ci); }
/// <summary> /// /// </summary> /// <param name="other"></param> public void MergeWith(CustomIndex other) { foreach (string key in AllKeys) { Samples[key].UnionWith(other.Samples[key]); } }
private static bool IsUseful(CustomIndex subject, List <CustomIndex> otherCustomIndices, List <CustomIndex> supportedCustomIndices) { // Subject is useful if it can fit a CustomIndex that no other can fit if (supportedCustomIndices.Any(ci => subject.Fits(ci) && !otherCustomIndices.Any(o => o.Fits(ci)))) { return(true); } return(false); }
/// <summary> /// /// </summary> /// <param name="other"></param> /// <returns></returns> public CustomIndex Merge(CustomIndex other) { CustomIndex ci = new CustomIndex(Math.Max(Index, other.Index)); foreach (string key in AllKeys) { ci.Samples[key].UnionWith(other.Samples[key]); } return(ci); }
/// <summary> /// /// </summary> /// <param name="other"></param> /// <returns></returns> public bool Fits(CustomIndex other) { // Every non-empty set from other == set from self // True until false bool support = true; foreach (KeyValuePair <string, HashSet <SampleGeneratingArgs> > kvp in Samples) { support = CheckSupport(kvp.Value, other.Samples[kvp.Key]) && support; } return(support); }
/// <summary> /// /// </summary> /// <param name="other"></param> public void MergeWith(CustomIndex other) { foreach (string key in AllKeys) { Samples[key].UnionWith(other.Samples[key]); } // If the other custom index has an assigned index and this one doesnt. Get the index, so optimised custom indices retain their indices. if (Index == -1 && other.Index != -1) { Index = other.Index; } }
public CustomIndex GetCustomIndex(SampleGeneratingArgsComparer comparer = null) { if (comparer == null) { comparer = new SampleGeneratingArgsComparer(); } SampleSet sampleSet = GetSampleSet(); SampleSet additions = GetAdditions(); HashSet <SampleGeneratingArgs> normals = new HashSet <SampleGeneratingArgs>(Samples.Where(o => o.Hitsound == Hitsound.Normal).Select(o => o.SampleArgs), comparer); HashSet <SampleGeneratingArgs> whistles = new HashSet <SampleGeneratingArgs>(Samples.Where(o => o.Hitsound == Hitsound.Whistle).Select(o => o.SampleArgs), comparer); HashSet <SampleGeneratingArgs> finishes = new HashSet <SampleGeneratingArgs>(Samples.Where(o => o.Hitsound == Hitsound.Finish).Select(o => o.SampleArgs), comparer); HashSet <SampleGeneratingArgs> claps = new HashSet <SampleGeneratingArgs>(Samples.Where(o => o.Hitsound == Hitsound.Clap).Select(o => o.SampleArgs), comparer); CustomIndex ci = new CustomIndex(comparer); if (sampleSet == SampleSet.Normal) { ci.Samples["normal-hitnormal"] = normals; } else if (sampleSet == SampleSet.Drum) { ci.Samples["drum-hitnormal"] = normals; } else { ci.Samples["soft-hitnormal"] = normals; } if (additions == SampleSet.Normal) { ci.Samples["normal-hitwhistle"] = whistles; ci.Samples["normal-hitfinish"] = finishes; ci.Samples["normal-hitclap"] = claps; } else if (additions == SampleSet.Drum) { ci.Samples["drum-hitwhistle"] = whistles; ci.Samples["drum-hitfinish"] = finishes; ci.Samples["drum-hitclap"] = claps; } else { ci.Samples["soft-hitwhistle"] = whistles; ci.Samples["soft-hitfinish"] = finishes; ci.Samples["soft-hitclap"] = claps; } return(ci); }
public List <CustomIndex> GetCustomIndices(SampleGeneratingArgsComparer comparer = null) { if (comparer == null) { comparer = new SampleGeneratingArgsComparer(); } var customIndices = new Dictionary <int, CustomIndex>(); foreach (var kvp in this) { var name = Path.GetFileNameWithoutExtension(kvp.Key); if (name == null) { continue; } var match = Regex.Match(name, "^(normal|soft|drum)-hit(normal|whistle|finish|clap)"); if (!match.Success) { continue; } var hitsound = match.Value; var remainder = name.Substring(match.Index + match.Length); int index = 1; if (!string.IsNullOrEmpty(remainder)) { if (!FileFormatHelper.TryParseInt(remainder, out index)) { continue; } } if (customIndices.ContainsKey(index)) { customIndices[index].Samples[hitsound] = new HashSet <SampleGeneratingArgs>(kvp.Value); } else { var ci = new CustomIndex(index, comparer); customIndices.Add(index, ci); ci.Samples[hitsound] = new HashSet <SampleGeneratingArgs>(kvp.Value, comparer); } } return(customIndices.Values.ToList()); }
/// <summary> /// Generates 1-to-1 <see cref="HitsoundEvent"/> of out <see cref="SamplePackage"/> using provided custom indices. /// </summary> /// <param name="samplePackages">The SamplePackages to get hitsounds out of</param> /// <param name="customIndices">The CustomIndices that fit all the packages</param> /// <param name="loadedSamples">Loaded samples for the validation of samples files from the sample packages.</param> /// <param name="validateSampleFile">Whether to validate sample files from the sample packages.</param> /// <param name="comparer">Comparer for <see cref="SampleGeneratingArgs"/></param> /// <returns></returns> public static List <HitsoundEvent> GetHitsounds(List <SamplePackage> samplePackages, List <CustomIndex> customIndices, Dictionary <SampleGeneratingArgs, SampleSoundGenerator> loadedSamples = null, bool validateSampleFile = true, SampleGeneratingArgsComparer comparer = null) { List <HitsoundEvent> hitsounds = new List <HitsoundEvent>(samplePackages.Count); List <CustomIndex> packageCustomIndices = GetCustomIndices(samplePackages, loadedSamples, validateSampleFile, comparer); int index = 0; while (index < packageCustomIndices.Count) { // Find CustomIndex that fits the most packages from here CustomIndex bestCustomIndex = null; int bestFits = 0; foreach (CustomIndex ci in customIndices) { int fits = NumSupportedPackages(packageCustomIndices, index, ci); if (fits <= bestFits) { continue; } bestCustomIndex = ci; bestFits = fits; } if (bestFits == 0) { throw new Exception("Custom indices can't fit the sample packages.\n" + "Maybe you are using an incompatible previous sample schema and growth is disabled."); } // Add all the fitted packages as hitsounds for (int i = 0; i < bestFits; i++) { if (bestCustomIndex != null) { hitsounds.Add(samplePackages[index + i].GetHitsound(bestCustomIndex.Index)); } } index += bestFits; } return(hitsounds); }
/// <summary> /// Generates 1-to-1 <see cref="HitsoundEvent"/> of out <see cref="SamplePackage"/> using provided custom indices. /// </summary> /// <param name="samplePackages">The SamplePackages to get hitsounds out of</param> /// <param name="customIndices">The CustomIndices that fit all the packages</param> /// <returns></returns> public static List <HitsoundEvent> GetHitsounds(List <SamplePackage> samplePackages, List <CustomIndex> customIndices) { List <HitsoundEvent> hitsounds = new List <HitsoundEvent>(samplePackages.Count); List <CustomIndex> packageCustomIndices = GetCustomIndices(samplePackages); int index = 0; while (index < packageCustomIndices.Count) { // Find CustomIndex that fits the most packages from here CustomIndex bestCustomIndex = null; int bestFits = 0; foreach (CustomIndex ci in customIndices) { int fits = NumSupportedPackages(packageCustomIndices, index, ci); if (fits > bestFits) { bestCustomIndex = ci; bestFits = fits; } } if (bestFits == 0) { throw new Exception("Custom indices can't fit the sample packages."); } else { // Add all the fitted packages as hitsounds for (int i = 0; i < bestFits; i++) { if (bestCustomIndex != null) { hitsounds.Add(samplePackages[index + i].GetHitsound(bestCustomIndex.Index)); } } index += bestFits; } } return(hitsounds); }
private static int NumSupportedPackages(List <CustomIndex> packageCustomIndices, int i, CustomIndex ci) { int supported = 0; int index = i; while (index < packageCustomIndices.Count) { if (ci.Fits(packageCustomIndices[index++])) { supported++; } else { return(supported); } } return(supported); }