public IList <IEvent> Decode(TimingChunk timingChunk) { IEnumerable <IEvent> Do() { var timings = timingChunk.Timings; var ticksPerSecond = timingChunk.Rate; var orderedTimings = timings .OrderBy(t => t.LinearOffset) .ThenBy(t => t.MetricOffset) .ToArray(); var firstOrderedTiming = orderedTimings.First(); var previous = new { firstOrderedTiming.MetricOffset, firstOrderedTiming.LinearOffset }; foreach (var timing in orderedTimings.Skip(1)) { var ev = new Event { [NumericData.MetricOffset] = (BigRational)previous.MetricOffset / SsqConstants.MeasureLength, [NumericData.LinearOffset] = (BigRational)previous.LinearOffset / ticksPerSecond }; BigRational deltaOffset = timing.MetricOffset - previous.MetricOffset; BigRational deltaTicks = timing.LinearOffset - previous.LinearOffset; if (deltaOffset == 0) { ev[NumericData.Stop] = deltaTicks / ticksPerSecond; } else if (deltaTicks == 0) { ev[NumericData.Bpm] = BigRational.PositiveInfinity; } else { ev[NumericData.Bpm] = deltaOffset / SsqConstants.MeasureLength / (deltaTicks / ticksPerSecond / 240); } yield return(ev); previous = new { timing.MetricOffset, timing.LinearOffset }; } } return(Do().ToList()); }
public IList <IEvent> Decode( TimingChunk timings, IEnumerable <Step> steps, IEnumerable <Trigger> triggers, IPanelMapper panelMapper) { return(_timingEventDecoder.Decode(timings) .Concat(_stepEventDecoder.Decode(steps, panelMapper)) .Concat(_triggerEventDecoder.Decode(triggers)) .OrderBy(ev => ev[NumericData.MetricOffset]) .AsList()); }
public TimingChunk GetTimings(IEnumerable <SsqChunk> chunks) { int?rate = null; var result = new TimingChunk { Timings = chunks.Where(c => c.Parameter0 == Parameter0.Timings) .SelectMany(tc => { rate = rate ?? tc.Parameter1; return(_timingChunkDecoder.Convert(tc.Data)); }) .AsList(), Rate = rate ?? 75 }; _logger.Debug($"BPM precision is {result.Rate} ticks/second"); return(result); }
public void Decode_ConvertsTimingsCorrectly() { // Arrange. var data = new[] { new Timing { LinearOffset = 0, MetricOffset = 0 }, new Timing { LinearOffset = 100, MetricOffset = 4096 }, new Timing { LinearOffset = 150, MetricOffset = 8192 } }; var timings = new TimingChunk { Timings = data, Rate = 100 }; var expected = new[] { new Event { [NumericData.Bpm] = 240, [NumericData.LinearOffset] = 0, [NumericData.MetricOffset] = 0 }, new Event { [NumericData.Bpm] = 480, [NumericData.LinearOffset] = 1, [NumericData.MetricOffset] = 1 } }; // Act. var result = Subject.Decode(timings).ToArray(); // Assert. result.Should().HaveCount(expected.Length); var resultMatches = Enumerable.Range(0, expected.Length) .Select(i => ((Event)result[i]).MetadataEquals(expected[i])); resultMatches.Should().BeEquivalentTo(Enumerable.Repeat(true, expected.Length)); }