public List <Event> Generate(AudioMetadata audioMetadata) { var redColorTheme = StaticRandom.Rng.Next(2) == 0; var blueColorTheme = !redColorTheme; var lightEffects = new List <Event>(); var bpm = audioMetadata.BeatDetectorResult.BeatsPerMinute; var songIntensity = audioMetadata.BeatDetectorResult.SongIntensities; var continuousSongIntensity = new ContinuousLine2D(songIntensity.Select(x => new Point2D(x.SampleIndex, x.Intensity))); for (var beatIdx = 0; beatIdx < audioMetadata.BeatDetectorResult.RegularBeats.Count; beatIdx++) { if (beatIdx.IsOdd()) { continue; // Skip every second beat } var regularBeat = audioMetadata.BeatDetectorResult.RegularBeats[beatIdx]; var time = TimeConversion.SampleIndexToRealTime(regularBeat.SampleIndex, audioMetadata.SampleRate); var timeAsBeatIndex = TimeConversion.SampleIndexToBeatIndex(regularBeat.SampleIndex, audioMetadata.SampleRate, bpm); if (time > audioMetadata.Length - TimeSpan.FromSeconds(3)) { lightEffects.AddRange(TurnOffAllLights(timeAsBeatIndex)); break; } var currentIntensity = continuousSongIntensity.ValueAtX(regularBeat.SampleIndex); if (currentIntensity < 0.5) { var tunnelMove = StaticRandom.Rng.Next(2) == 0 ? EventType.TunnelRotation : EventType.TunnelZooming; lightEffects.Add(new Event { Time = timeAsBeatIndex, Type = tunnelMove, Value = StaticRandom.Rng.Next(10) }); } else { lightEffects.Add(new Event { Time = timeAsBeatIndex, Type = EventType.LightEffect0, Value = (int)(redColorTheme ? LightColor.RedFadeOut : LightColor.BlueFadeOut) }); lightEffects.Add(new Event { Time = timeAsBeatIndex, Type = EventType.LightEffect1, Value = (int)(redColorTheme ? LightColor.RedFadeOut : LightColor.BlueFadeOut) }); } } return(lightEffects); }
private List <Note> FilterNotesByDifficulty(IEnumerable <Note> baseNotes, AudioMetadata audioMetadata, Difficulty difficulty) { var songIntensities = audioMetadata.BeatDetectorResult.SongIntensities; var bpm = audioMetadata.BeatDetectorResult.BeatsPerMinute; var sampleRate = audioMetadata.SampleRate; var continuousSongIntensity = new ContinuousLine2D(songIntensities.Select(x => new Point2D(x.SampleIndex, x.Intensity))); var minimumTimeBetweenNotes = DetermineTimeBetweenNotes(difficulty); var notes = new List <Note>(); Note lastNote = null; foreach (var baseNote in baseNotes) { var noteTime = TimeConversion.BeatIndexToRealTime(baseNote.Time, bpm); var noteTimeInSamples = noteTime.TotalSeconds * sampleRate; if (noteTime < TimeSpan.FromSeconds(3)) { continue; // Stop a few seconds before song ends } if (noteTime > audioMetadata.Length - TimeSpan.FromSeconds(3)) { break; // Stop a few seconds before song ends } var currentIntensity = continuousSongIntensity.ValueAtX(noteTimeInSamples); if (lastNote != null) { var timeSinceLastBeat = noteTime - TimeConversion.BeatIndexToRealTime(lastNote.Time, bpm); if (currentIntensity.IsNaN()) { currentIntensity = 0; } var intensityAdjustment = TimeSpan.FromSeconds(0.5 * (1 - currentIntensity)); if (timeSinceLastBeat < minimumTimeBetweenNotes + intensityAdjustment && !AreSimultaneous(baseNote, lastNote)) { continue; } } var noteProbability = currentIntensity < 0.3 ? 0 : currentIntensity; if (StaticRandom.Rng.NextDouble() > noteProbability) { continue; } notes.Add(baseNote); lastNote = baseNote; } return(notes); }
private static Dictionary <char, ContinuousLine2D> LoadInverseAngleDistributions() { var angleDirectory = @"G:\Projects\HumanGenome\Protein-PDBs\HumanProteins\AminoAcidPositions\InterAminoAcidAngles"; var angleDistributionFilePattern = "*_probabilityDistribution.csv"; var probabilityDistributionFiles = Directory.EnumerateFiles(angleDirectory, angleDistributionFilePattern); var aminoAcidLetterPattern = "aminoAcid_([A-Z])_probabilityDistribution\\.csv"; var angleInverseDistributions = new Dictionary <char, ContinuousLine2D>(); foreach (var probabilityDistributionFile in probabilityDistributionFiles) { var match = Regex.Match(Path.GetFileName(probabilityDistributionFile), aminoAcidLetterPattern); var aminoAcidLetter = match.Groups[1].Value[0]; var angleDistributionPoints = File.ReadAllLines(probabilityDistributionFile) .Select(line => line.Split(';')) .Select(splittedLine => new Point2D(double.Parse(splittedLine[0]) / 100, Math.PI * double.Parse(splittedLine[1]) / 180)); var angleInverseDistribution = new ContinuousLine2D(angleDistributionPoints); angleInverseDistributions.Add(aminoAcidLetter, angleInverseDistribution); } return(angleInverseDistributions); }
private List <double> ComputeDynamicThreshold(IList <double> signal, int windowSize, int minPeakCount, int maxPeakCount) { var thresholdPoints = new List <Point2D>(); var startIdx = 0; while (startIdx + windowSize <= signal.Count) { var valuesInWindow = signal.SubArray(startIdx, windowSize); var orderedValues = valuesInWindow.OrderByDescending(x => x).ToList(); var minPeakValue = orderedValues[minPeakCount - 1]; var maxPeakValue = orderedValues[maxPeakCount - 1]; var combinedThreshold = 0.8 * minPeakValue + 0.2 * maxPeakValue; thresholdPoints.Add(new Point2D(startIdx + windowSize / 2, combinedThreshold)); startIdx += windowSize / 2; } thresholdPoints.Add(new Point2D(double.NegativeInfinity, thresholdPoints.First().Y)); thresholdPoints.Add(new Point2D(double.PositiveInfinity, thresholdPoints.Last().Y)); var continuousThreshold = new ContinuousLine2D(thresholdPoints); var dynamicThreshold = Enumerable.Range(0, signal.Count) .Select(idx => continuousThreshold.ValueAtX(idx)) .ToList(); return(dynamicThreshold); }