private void Start() { random = new System.Random(); sequenceGeneration = new SequenceGeneration(); wallSequenceGeneration = new WallSequenceGeneration(); AddWallGenerationTimer(); }
private List <Beat> MicroAlignBeats(IList <float> signal, List <Beat> strengthFilteredBeats, int stepSizeOfOriginalSearch) { //original found beats are detected with a window size of 1024, resulting in a precision of 1024/44100=23ms //this is sometimes big enough to feel being 'off-beat' //perform a more precise search with smaller window to find the best place to put the beat //128/44100=3ms var alignedBeats = new List <Beat>(); var stftWindowSize = 1024; //not sure about this number var stepSize = 128; var stft = new Stft(windowSize: stftWindowSize, hopSize: stepSize, window: WindowTypes.Hamming); var spectrogram = stft.Spectrogram(signal.ToArray()); var windowPositions = SequenceGeneration .Linspace(stftWindowSize / 2.0, signal.Count - stftWindowSize / 2.0, spectrogram.Count) .ToList(); foreach (var beat in strengthFilteredBeats) { var alignedBeat = new Beat(); alignedBeat.Strength = beat.Strength; var searchSampleIndexStart = Math.Max(0, beat.SampleIndex - (stepSizeOfOriginalSearch / 2)); var searchSampleIndexEnd = Math.Min(signal.Count, beat.SampleIndex + (stepSizeOfOriginalSearch / 2)); var searchIndexStart = windowPositions.FindIndex(x => x >= searchSampleIndexStart); var searchIndexEnd = windowPositions.FindLastIndex(x => x < searchSampleIndexEnd); var bestMatchingIndex = searchIndexStart; var strengthOfBestMatch = 0.0; for (int timeIndex = searchIndexStart + 1; timeIndex <= searchIndexEnd; ++timeIndex) { var strengthOfTimeIndex = 0.0; for (int frequency = 0; frequency < spectrogram[0].Length; ++frequency) { var diff = spectrogram[timeIndex][frequency] - spectrogram[timeIndex - 1][frequency]; if (diff > 0) { strengthOfTimeIndex += diff; } } if (strengthOfTimeIndex > strengthOfBestMatch) { bestMatchingIndex = timeIndex; strengthOfBestMatch = strengthOfTimeIndex; } } alignedBeat.SampleIndex = (int)windowPositions[bestMatchingIndex]; alignedBeats.Add(alignedBeat); } return(alignedBeats); }
public void ConstantPointsAreFittedWithoutSlope() { var expectedSlope = 0; var expectedOffset = 32.2; var points = SequenceGeneration.FixedStep(-5, 5, 1) .Select(x => new Point2D(x, expectedOffset)) .ToList(); var actual = points.FitLine(); Assert.That(actual, Is.Not.Null); Assert.That(actual.Slope, Is.EqualTo(expectedSlope).Within(Tolerance)); Assert.That(actual.Offset, Is.EqualTo(expectedOffset).Within(Tolerance)); Assert.That(actual.MeanSquareError, Is.EqualTo(0).Within(Tolerance)); }
public void PolynomialIsAdjustedToNumberOfPoints() { var pointCount = 3; // Max order can hence be 2 (parabola) var expectedBeta = new[] { 1, 2, -0.5, 0, 0, 0 }; var points = SequenceGeneration.Linspace(-1, 1, pointCount) .Select(x => new Point2D(x, expectedBeta[0] + expectedBeta[1] * x + expectedBeta[2] * x * x)) .ToList(); var actual = points.FitPolynomial(5); Assert.That(actual, Is.Not.Null); for (int order = 0; order < expectedBeta.Length; order++) { Assert.That(actual.Beta[order], Is.EqualTo(expectedBeta[order]).Within(Tolerance)); } }
public void SerializationRoundtripBatchTest() { var allValidUnits = Unit.Effective.AllUnits; var exponentsToTest = SequenceGeneration.FixedStep(-12, 12, 3).ToList(); foreach (var unit in allValidUnits) { foreach (var exponent in exponentsToTest) { var value = 1.3 * Math.Pow(10, (int)exponent); var unitValue = new UnitValue(unit, value); var unitValueString = unitValue.ToString(); var roundTripUnitValue = UnitValue.Parse(unitValueString); Assert.That(roundTripUnitValue.Unit, Is.EqualTo(unitValue.Unit)); Assert.That(roundTripUnitValue.Value, Is.EqualTo(unitValue.Value).Within(1e-3 * unitValue.Value)); } } }
/// <summary> /// Takes an audio signal, detects the beats and returns a list of all times (in seconds) where a beat is located /// </summary> /// <param name="signal">Expected to be normalized to -1 to 1</param> /// <param name="sampleRate">Sample rate of signal</param> /// <returns>Sample indices of beats</returns> public BeatDetectorResult DetectBeats(IList <float> signal, int sampleRate) { var stftWindowSize = 4096; var stepSize = 1024; var lowerLimit = 0.1 * sampleRate; var upperLimit = 1.0 * sampleRate; var stft = new Stft(windowSize: stftWindowSize, hopSize: stepSize, window: WindowTypes.Hamming); var spectrogram = stft.Spectrogram(signal.ToArray()); var windowPositions = SequenceGeneration .Linspace(stftWindowSize / 2.0, signal.Count - stftWindowSize / 2.0, spectrogram.Count) .ToList(); var fftMagnitudeIncreaseSeries = ComputeFftMagnitudeIncreaseSeries(spectrogram, windowPositions); var candidateBeats = FindCandidateBeats(fftMagnitudeIncreaseSeries, sampleRate, stepSize, out var songIntensity); var filteredBeats = FilterBeats(candidateBeats, lowerLimit); var beatsPerMinute = DetermineBeatsPerMinute(filteredBeats, sampleRate, upperLimit); var regularBeats = GenerateRegularBeats(filteredBeats, beatsPerMinute, sampleRate, signal.Count); var beatsPerBar = 4; return(new BeatDetectorResult(beatsPerMinute, beatsPerBar, filteredBeats, regularBeats, songIntensity)); }
private static Shape GenerateCircleWithCalibration(Annotation annotation, Calibration calibration, double lineThickness) { var pinholeProjection = new PinholeToPlaneProjection(calibration); var realWorldCircle = RealWorldAnnotationHelpers.ConstructRealWorldCircles(new [] { annotation }, pinholeProjection).Single(); var imageCirclePoints = new PointCollection(100); foreach (var angle in SequenceGeneration.Linspace(-Math.PI, Math.PI, 100)) { var realWorldCirclePoint = realWorldCircle.Center + new Vector2D( realWorldCircle.Radius * Math.Cos(angle), realWorldCircle.Radius * Math.Sin(angle)); var imageCirclePoint = pinholeProjection.InverseTransform(realWorldCirclePoint); imageCirclePoints.Add(new Point(imageCirclePoint.X, imageCirclePoint.Y)); } var polygon = new Polygon { Points = imageCirclePoints, Stroke = Brushes.Red, StrokeThickness = lineThickness }; return(polygon); }
/// <summary> /// Takes an audio signal, detects the beats and returns a list of all times (in seconds) where a beat is located /// </summary> /// <param name="signal">Expected to be normalized to -1 to 1</param> /// <param name="sampleRate">Sample rate of signal</param> /// <returns>Sample indices of beats</returns> public BeatDetectorResult DetectBeats(IList <float> signal, int sampleRate) { var stftWindowSize = 4096; var stepSize = 1024; var stft = new Stft(windowSize: stftWindowSize, hopSize: stepSize, window: WindowTypes.Hamming); var spectrogram = stft.Spectrogram(signal.ToArray()); var windowPositions = SequenceGeneration .Linspace(stftWindowSize / 2.0, signal.Count - stftWindowSize / 2.0, spectrogram.Count) .ToList(); var focusedFrequency = DetermineFocusedFrequency(sampleRate, spectrogram, windowPositions); var beatCandidates = GetBeatCandidates(spectrogram, focusedFrequency, windowPositions); var strengthFilteredBeats = MergeBeatsByStrength(sampleRate, beatCandidates); var alignedBeats = MicroAlignBeats(signal, strengthFilteredBeats, stepSize); var songIntensity = GetSongIntensity(spectrogram, windowPositions, sampleRate, stepSize); var bpm = 60 * strengthFilteredBeats.Count() / (signal.Count / (double)sampleRate); return(new BeatDetectorResult(bpm, alignedBeats, songIntensity)); }