Beispiel #1
0
        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);
        }