/// <summary> /// Handles finish of header chunk reading. Called after header chunk is read. /// </summary> /// <param name="timeDivision">Time division of the file is being read.</param> public override void OnFinishHeaderChunkReading(TimeDivision timeDivision) { _tempoMap = new TempoMap(timeDivision) { IsTempoMapReady = false }; }
public void WriteToDisk(long maxLength, string filenamePrefix, TimeDivision timeDivision) { var countsPerInstrument = _writers .GroupBy(x => x.Instrument) .ToDictionary( x => x.Key, x => x.Count()); var currentIndexByInstrument = _writers .Select(x => x.Instrument) .Distinct() .ToDictionary( x => x, x => 1); foreach (var writer in _writers.Where(x => x != _emptyWriter)) { if (countsPerInstrument[writer.Instrument] == 1) { writer.WriteToDisk(maxLength, $"{filenamePrefix}.ch{_channelNumber}", -1, timeDivision); } else { var index = currentIndexByInstrument[writer.Instrument]; writer.WriteToDisk(maxLength, $"{filenamePrefix}.ch{_channelNumber}", index, timeDivision); currentIndexByInstrument[writer.Instrument] = index + 1; } } }
private void SplitByChunks_WithSettings( ICollection <MidiChunk> chunks, ICollection <MidiChunk> expectedChunks, SplitFileByChunksSettings settings, TimeDivision timeDivision = null) { var midiFile = new MidiFile(chunks); if (timeDivision != null) { midiFile.TimeDivision = timeDivision; } var midiFilesByChunks = midiFile.SplitByChunks(settings).ToList(); Assert.AreEqual(expectedChunks.Count, midiFilesByChunks.Count, "Invalid count of new files."); var i = 0; foreach (var chunk in expectedChunks) { MidiAsserts.AreEqual( new MidiFile(chunk) { TimeDivision = midiFile.TimeDivision }, midiFilesByChunks[i], false, $"File {i} is invalid."); i++; } }
private void SplitByChannel( ICollection <TimedEvent> timedEvents, ICollection <ICollection <TimedEvent> > expectedTimedEvents, TimeDivision timeDivision = null) { var midiFile = timedEvents.ToFile(); if (timeDivision != null) { midiFile.TimeDivision = timeDivision; } var midiFilesByChannel = midiFile.SplitByChannel().ToList(); Assert.AreEqual(expectedTimedEvents.Count, midiFilesByChannel.Count, "Invalid count of new files."); var expectedTimedEventsEnumerator = expectedTimedEvents.GetEnumerator(); var newMidiFilesEnumerator = midiFilesByChannel.GetEnumerator(); var i = 0; while (expectedTimedEventsEnumerator.MoveNext() && newMidiFilesEnumerator.MoveNext()) { var expectedEvents = expectedTimedEventsEnumerator.Current; var actualEvents = newMidiFilesEnumerator.Current.GetTimedEvents(); MidiAsserts.AreEqual(expectedEvents, actualEvents, $"Invalid events of file {i}."); Assert.AreEqual(midiFile.TimeDivision, newMidiFilesEnumerator.Current.TimeDivision, $"Invalid time division of file {i}."); i++; } }
protected override void Update() { base.Update(); if (beatmap == null) { return; } playback.Position = audioTrack.CurrentTime / 1000.0; // ms -> s gameView.renderer.Position = playback.Position; effectController.Update(); foreach (var measure in playback.MeasuresInView) { for (int i = 0; i < measure.TimingPoint.Numerator; i++) { var div = new TimeDivision(i, measure.TimingPoint.Numerator); gameView.renderer.UpdateSplit(new TimeDivisionReference(div, measure)); } } foreach (var obj in playback.ObjectsInView) { gameView.renderer.UpdateObject(obj); } }
/// <summary> /// Creates an instance of the <see cref="TempoMapManager" /> initializing it with the /// specified events collections and time division. /// </summary> /// <param name="eventsCollections"> /// Collection of <see cref="EventsCollection" /> which hold events /// that represent tempo map of a MIDI file. /// </param> /// <param name="timeDivision"> /// MIDI file time division which specifies the meaning of the time /// used by events of the file. /// </param> /// <returns> /// An instance of the <see cref="TempoMapManager" /> that can be used to manage /// tempo map represented by the <paramref name="eventsCollections" /> and <paramref name="timeDivision" />. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="eventsCollections" /> is null. -or- /// <paramref name="timeDivision" /> is null. /// </exception> public static TempoMapManager ManageTempoMap(this IEnumerable <EventsCollection> eventsCollections, TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(eventsCollections), eventsCollections); ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); return(new TempoMapManager(timeDivision, eventsCollections)); }
/// <summary> /// Creates an instance of the <see cref="TempoMapManager" /> initializing it with the /// specified time division and events collections of the specified track chunks. /// </summary> /// <param name="trackChunks"> /// Collection of <see cref="TrackChunk" /> which hold events /// that represent tempo map of a MIDI file. /// </param> /// <param name="timeDivision"> /// MIDI file time division which specifies the meaning of the time /// used by events of the file. /// </param> /// <returns> /// An instance of the <see cref="TempoMapManager" /> that can be used to manage /// tempo map represented by the <paramref name="trackChunks" /> and <paramref name="timeDivision" />. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="trackChunks" /> is null. -or- /// <paramref name="timeDivision" /> is null. /// </exception> public static TempoMapManager ManageTempoMap(this IEnumerable <TrackChunk> trackChunks, TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); return(trackChunks.Select(c => c.Events).ManageTempoMap(timeDivision)); }
/// <summary> /// Initializes a new instance of the <see cref="TempoMap"/> with the specified time division /// of a MIDI file. /// </summary> /// <param name="timeDivision">MIDI file time division which specifies the meaning of the time /// used by events of the file.</param> /// <exception cref="ArgumentNullException"><paramref name="timeDivision"/> is null.</exception> internal TempoMap(TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); TimeDivision = timeDivision; Tempo = new ValueLine <Tempo>(Interaction.Tempo.Default); TimeSignature = new ValueLine <TimeSignature>(Interaction.TimeSignature.Default); }
/// <summary> /// Clones the current <see cref="TempoMap"/>. /// </summary> /// <returns>An instance of the <see cref="TempoMap"/> which is a clone of the current one.</returns> public TempoMap Clone() { var tempoMap = new TempoMap(TimeDivision.Clone()); tempoMap.Tempo.ReplaceValues(Tempo); tempoMap.TimeSignature.ReplaceValues(TimeSignature); return(tempoMap); }
/// <summary> /// Gets tempo map represented by the specified events collections and time division. /// </summary> /// <param name="eventsCollections"> /// Collection of <see cref="EventsCollection" /> which hold events /// that represent tempo map of a MIDI file. /// </param> /// <param name="timeDivision"> /// MIDI file time division which specifies the meaning of the time /// used by events of the file. /// </param> /// <returns> /// Tempo map represented by the <paramref name="eventsCollections" /> and /// <paramref name="timeDivision" />. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="eventsCollections" /> is null. -or- /// <paramref name="timeDivision" /> is null. /// </exception> public static TempoMap GetTempoMap(this IEnumerable <EventsCollection> eventsCollections, TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(eventsCollections), eventsCollections); ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); return(eventsCollections.Any() ? eventsCollections.ManageTempoMap(timeDivision).TempoMap : new TempoMap(timeDivision)); }
/// <summary> /// Creates an instance of the <see cref="TempoMap"/> with the specified time division and /// time signature using default tempo (120 BPM). /// </summary> /// <param name="timeDivision">Time division of the tempo map.</param> /// <param name="timeSignature">Time signature of the tempo map.</param> /// <returns><see cref="TempoMap"/> with the specified time division and time signature.</returns> /// <exception cref="ArgumentNullException"><paramref name="timeDivision"/> is null. -or- /// <paramref name="timeSignature"/> is null.</exception> public static TempoMap Create(TimeDivision timeDivision, TimeSignature timeSignature) { ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); ThrowIfArgument.IsNull(nameof(timeSignature), timeSignature); var tempoMap = new TempoMap(timeDivision); SetGlobalTimeSignature(tempoMap, timeSignature); return(tempoMap); }
/// <summary> /// Initializes a new instance of the <see cref="TempoMapManager"/> with the specified time division /// and events collections. /// </summary> /// <param name="timeDivision">MIDI file time division which specifies the meaning of the time /// used by events of the file.</param> /// <param name="eventsCollections">Collection of <see cref="EventsCollection"/> which hold events that /// represent tempo map of a MIDI file.</param> /// <exception cref="ArgumentNullException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="timeDivision"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="eventsCollections"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> /// <exception cref="ArgumentException"><paramref name="eventsCollections"/> is empty.</exception> public TempoMapManager(TimeDivision timeDivision, IEnumerable <EventsCollection> eventsCollections) { ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); ThrowIfArgument.IsNull(nameof(eventsCollections), eventsCollections); ThrowIfArgument.IsEmptyCollection(nameof(eventsCollections), eventsCollections, $"Collection of {nameof(EventsCollection)} is empty."); _timedEventsManagers = eventsCollections.Where(events => events != null) .Select(events => events.ManageTimedEvents()) .ToList(); // TempoMap = new TempoMap(timeDivision); CollectTimeSignatureChanges(); CollectTempoChanges(); }
public void GetAverage_StateUnderTest_ExpectedBehavior() { // Arrange var averageValues = this.CreateAverageValues(); TimeDivision timeDivisionHour = TimeDivision.PerHour; TimeDivision timeDivisionMinute = TimeDivision.PerMinute; TimeDivision timeDivisionSecond = TimeDivision.PerSecond; // Act var resultHour = averageValues.GetAverage(testData, timeDivisionHour); var resultMinute = averageValues.GetAverage(testData, timeDivisionMinute); var resultSecond = averageValues.GetAverage(testData, timeDivisionSecond); // Assert Assert.AreEqual(278, resultHour); Assert.AreEqual(278, resultMinute); Assert.AreEqual(55, resultSecond); this.mockRepository.VerifyAll(); }
private static void TestSimpleTempoMap(TempoMap tempoMap, TimeDivision expectedTimeDivision, Tempo expectedTempo, TimeSignature expectedTimeSignature) { Assert.AreEqual(expectedTimeDivision, tempoMap.TimeDivision, "Unexpected time division."); Assert.AreEqual(expectedTempo, tempoMap.Tempo.AtTime(0), "Unexpected tempo at the start of tempo map."); Assert.AreEqual(expectedTempo, tempoMap.Tempo.AtTime(1000), "Unexpected tempo at the arbitrary time of tempo map."); Assert.AreEqual(expectedTimeSignature, tempoMap.TimeSignature.AtTime(0), "Unexpected time signature at the start of tempo map."); Assert.AreEqual(expectedTimeSignature, tempoMap.TimeSignature.AtTime(1000), "Unexpected time signature at the arbitrary time of tempo map."); }
public double GetAverage(List <ProcessedTweet> records, TimeDivision timeDivision) { try { if (records.Count > 0) { switch (timeDivision) { case TimeDivision.PerSecond: var groupSec = records.GroupBy(o => new { o.YearMonthDay, o.Hour, o.Minute, o.Second }).Select(o => new { key = o.Key, count = o.Count() }); var sumSec = groupSec.Select(o => o.count).Sum <int>(sel => sel); var totalSec = groupSec.Count(); return(sumSec / totalSec); case TimeDivision.PerMinute: var groupMin = records.GroupBy(o => new { o.YearMonthDay, o.Hour, o.Minute }).Select(o => new { key = o.Key, count = o.Count() }); var sumMin = groupMin.Select(o => o.count).Sum <int>(sel => sel); var totalMin = groupMin.Count(); return(sumMin / totalMin); case TimeDivision.PerHour: var groupHr = records.GroupBy(o => new { o.YearMonthDay, o.Hour }).Select(o => new { key = o.Key, count = o.Count() }); var sumHr = groupHr.Select(o => o.count).Sum <int>(sel => sel); var totalHr = groupHr.Count(); return(sumHr / totalHr); default: return(0.0); } } return(0.0); } catch (Exception) { throw; } }
public DivisionTimeParameter(int numerator, int denominator) { Division = new TimeDivision(numerator, denominator); }
internal static void IsNotSupportedForTimeConversion(TimeDivision timeDivision) { throw new NotSupportedException($"{timeDivision} is not supported for time conversion."); }
public DivisionTimeParameter(TimeDivision division) { Division = division; }
/// <summary> /// Creates an instance of the <see cref="TempoMap"/> with the specified time division using /// default tempo (120 BPM) and default time signature (4/4). /// </summary> /// <param name="timeDivision">Time division of the tempo map.</param> /// <returns><see cref="TempoMap"/> with the specified time division.</returns> /// <exception cref="ArgumentNullException"><paramref name="timeDivision"/> is null.</exception> public static TempoMap Create(TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); return(new TempoMap(timeDivision)); }
/// <summary> /// Initializes a new instance of the <see cref="TempoMapManager"/> with the /// specified time division. /// </summary> /// <param name="timeDivision">Time division of a new tempo that will be managed by this manager.</param> /// <exception cref="ArgumentNullException"><paramref name="timeDivision"/> is <c>null</c>.</exception> public TempoMapManager(TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); TempoMap = new TempoMap(timeDivision); }
/// <summary> /// Gets tempo map represented by the specified time division and events collections of /// the specified track chunks. /// </summary> /// <param name="trackChunks">Collection of <see cref="TrackChunk"/> which hold events /// that represent tempo map of a MIDI file.</param> /// <param name="timeDivision">MIDI file time division which specifies the meaning of the time /// used by events of the file.</param> /// <returns>Tempo map represented by the <paramref name="trackChunks"/> and <paramref name="timeDivision"/>.</returns> /// <exception cref="ArgumentNullException"> /// <para>One of the following errors occured:</para> /// <list type="bullet"> /// <item> /// <description><paramref name="trackChunks"/> is <c>null</c>.</description> /// </item> /// <item> /// <description><paramref name="timeDivision"/> is <c>null</c>.</description> /// </item> /// </list> /// </exception> public static TempoMap GetTempoMap(this IEnumerable <TrackChunk> trackChunks, TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); var eventsCollections = trackChunks.Where(c => c != null).Select(c => c.Events).ToArray(); var eventsCount = eventsCollections.Sum(c => c.Count); var result = new TempoMap(timeDivision); foreach (var timedEventTuple in eventsCollections.GetTimedEventsLazy(eventsCount)) { var timedEvent = timedEventTuple.Item1; var midiEvent = timedEvent.Event; switch (midiEvent.EventType) { case MidiEventType.TimeSignature: { var timeSignatureEvent = (TimeSignatureEvent)midiEvent; result.TimeSignatureLine.SetValue( timedEvent.Time, new TimeSignature( timeSignatureEvent.Numerator, timeSignatureEvent.Denominator)); } break; case MidiEventType.SetTempo: { var setTempoEvent = (SetTempoEvent)midiEvent; result.TempoLine.SetValue( timedEvent.Time, new Tempo(setTempoEvent.MicrosecondsPerQuarterNote)); } break; } } return(result); }
void InitialiseSong() { f = MidiFile.Read(Application.dataPath + "/Midi/" + MidiName); tMap = f.GetTempoMap(); audioSource = GetComponent <AudioSource>(); //MAYBE WE SHOULD LOOK FOR ONE IN THE SCENE? MAKES LOGIC CLEANER Debug.Log(Song.name); audioSource.clip = Song; //1000000 microseconds in a second, this lets us set our fixed deltatime logic. if (tMap.TimeSignature.Values.Count() != 0) { timeSigBars = tMap.TimeSignature.Values.First().Value.Denominator; timeSigBeats = tMap.TimeSignature.Values.First().Value.Numerator; } var seconds = tMap.Tempo.Values.ToArray().First().Value.MicrosecondsPerQuarterNote / (1000000f * timeSigBars); TimeDivision t = tMap.TimeDivision; Debug.Log(t.ToString()); Time.fixedDeltaTime = seconds; songLengthMicroseconds = (f.GetTimedEvents().LastOrDefault(e => e.Event is NoteOffEvent)?.TimeAs <MetricTimeSpan>(tMap) ?? new MetricTimeSpan()).TotalMicroseconds; notes = f.GetNotes(); chords = f.GetChords(); if (songLengthMicroseconds == 0) { songLengthMicroseconds = Math.Max(notes.Max(x => x.Time), chords.Max(x => x.Time)); } for (int i = 1; i < 5; i++) { NotesInSong[(SongDifficulty)i] = new Dictionary <long, Chord>(); } foreach (Melanchall.DryWetMidi.Smf.Interaction.Note note in notes) { SongDifficulty d = (SongDifficulty)note.Octave; var difficultDictionary = NotesInSong[d]; if (difficultDictionary.ContainsKey(note.Time)) { //check if the chord at the target time contains us: if (difficultDictionary[note.Time].Notes.Contains(note)) { continue; } else { //if (d == difficulty) // Debug.Log("Adding note at time: " + note.Time); difficultDictionary[note.Time].Notes.Add(note); } } else { //if (d == difficulty) // Debug.Log("Adding note at time: " + note.Time); difficultDictionary[note.Time] = new Chord(new Melanchall.DryWetMidi.Smf.Interaction.Note[] { note }); } } if (!audioSource.isPlaying) { audioSource.Play(); } // Debug.Log(v.NoteNumber); }
/// <summary> /// Gets tempo map represented by the specified time division and events collections of /// the specified track chunks. /// </summary> /// <param name="trackChunks"> /// Collection of <see cref="TrackChunk" /> which hold events /// that represent tempo map of a MIDI file. /// </param> /// <param name="timeDivision"> /// MIDI file time division which specifies the meaning of the time /// used by events of the file. /// </param> /// <returns>Tempo map represented by the <paramref name="trackChunks" /> and <paramref name="timeDivision" />.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="trackChunks" /> is null. -or- /// <paramref name="timeDivision" /> is null. /// </exception> public static TempoMap GetTempoMap(this IEnumerable <TrackChunk> trackChunks, TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); return(trackChunks.Any() ? trackChunks.ManageTempoMap(timeDivision).TempoMap : new TempoMap(timeDivision)); }
private static TempoMap GetTempoMap(IEnumerable <TimedMidiEvent> timedMidiEvents, TimeDivision timeDivision) { using (var tempoMapManager = new TempoMapManager(timeDivision)) { var setTempoEvents = timedMidiEvents.Where(e => e.Event is SetTempoEvent) .OrderBy(e => e.Time, new TimeSpanComparer()); foreach (var timedMidiEvent in setTempoEvents) { var setTempoEvent = (SetTempoEvent)timedMidiEvent.Event; tempoMapManager.SetTempo(timedMidiEvent.Time, new Tempo(setTempoEvent.MicrosecondsPerQuarterNote)); } var timeSignatureEvents = timedMidiEvents.Where(e => e.Event is TimeSignatureEvent) .OrderBy(e => e.Time, new TimeSpanComparer()); foreach (var timedMidiEvent in timeSignatureEvents) { var timeSignatureEvent = (TimeSignatureEvent)timedMidiEvent.Event; tempoMapManager.SetTimeSignature(timedMidiEvent.Time, new TimeSignature(timeSignatureEvent.Numerator, timeSignatureEvent.Denominator)); } return(tempoMapManager.TempoMap); } }
public override void OnFinishHeaderChunkReading(TimeDivision timeDivision) { FileTimeDivision = timeDivision; }
public override void OnFinishHeaderChunkReading(TimeDivision timeDivision) { BadHandledCount++; }
private MidiFileSlicer(TimeDivision timeDivision, IEnumerator <TimedEvent>[] timedEventsEnumerators) { _timedEventsHolders = timedEventsEnumerators.Select(e => new TimedEventsHolder(e)).ToArray(); _timeDivision = timeDivision; }
/// <summary> /// Initializes a new instance of the <see cref="TempoMap"/> with the specified time division /// of a MIDI file. /// </summary> /// <param name="timeDivision">MIDI file time division which specifies the meaning of the time /// used by events of the file.</param> /// <exception cref="ArgumentNullException"><paramref name="timeDivision"/> is null.</exception> internal TempoMap(TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); TimeDivision = timeDivision; }
public DivisionTimeParameter() { Division = TimeDivision.Start; }
public static void ShiftEvents(this IEnumerable <TrackChunk> trackChunks, ITimeSpan distance, TimeDivision timeDivision) { ThrowIfArgument.IsNull(nameof(trackChunks), trackChunks); ThrowIfArgument.IsNull(nameof(distance), distance); ThrowIfArgument.IsNull(nameof(timeDivision), timeDivision); foreach (var trackChunk in trackChunks) { trackChunk.ShiftEvents(distance, timeDivision); } }