public void Read_Handler_AllHandlers() { var timeDivision = new TicksPerQuarterNoteTimeDivision(1000); var fileReadingHandler = new FileReadingHandler(); var trackChunkReadingHandler = new TrackChunkReadingHandler(); var eventReadingHandler = new EventReadingHandler(); MidiFileTestUtilities.ReadUsingHandlers( new MidiFile( new TrackChunk(new TextEvent("test"), new TextEvent("test 2")), new TrackChunk(), new TrackChunk(new SetTempoEvent(100000)), new TrackChunk()) { TimeDivision = timeDivision }, fileReadingHandler, trackChunkReadingHandler, eventReadingHandler); Assert.AreEqual(1, fileReadingHandler.StartHandledCount, "File: Start Handled Count is invalid."); Assert.AreEqual(1, fileReadingHandler.EndHandledCount, "File: End Handled Count is invalid."); Assert.AreEqual(timeDivision, fileReadingHandler.TimeDivision, "File: Time division is invalid."); Assert.AreEqual(0, fileReadingHandler.BadHandledCount, "File: Scope wasn't used correctly."); Assert.AreEqual(4, trackChunkReadingHandler.StartHandledCount, "Track chunk: Start Handled Count is invalid."); Assert.AreEqual(4, trackChunkReadingHandler.ContentStartHandledCount, "Track chunk: Content Start Handled Count is invalid."); Assert.AreEqual(4, trackChunkReadingHandler.EndHandledCount, "Track chunk: End Handled Count is invalid."); Assert.AreEqual(0, trackChunkReadingHandler.BadHandledCount, "Track chunk: Scope wasn't used correctly."); Assert.AreEqual(3, eventReadingHandler.HandledCount, "Event: Handled Count is invalid."); Assert.AreEqual(0, eventReadingHandler.BadHandledCount, "Event: Scope wasn't used correctly."); }
public void Read_Handler_Mixed() { var timeDivision = new TicksPerQuarterNoteTimeDivision(1000); var handler = new MixedReadingHandler(); MidiFileTestUtilities.ReadUsingHandlers( new MidiFile( new TrackChunk(new TextEvent("test"), new TextEvent("test 2")), new TrackChunk(), new TrackChunk(new SetTempoEvent(100000)), new TrackChunk()) { TimeDivision = timeDivision }, handler); Assert.AreEqual(1, handler.FileStartHandledCount, "File: Start Handled Count is invalid."); Assert.AreEqual(1, handler.FileEndHandledCount, "File: End Handled Count is invalid."); Assert.AreEqual(timeDivision, handler.FileTimeDivision, "File: Time division is invalid."); Assert.AreEqual(4, handler.TrackChunkStartHandledCount, "Track chunk: Start Handled Count is invalid."); Assert.AreEqual(4, handler.TrackChunkContentStartHandledCount, "Track chunk: Content Start Handled Count is invalid."); Assert.AreEqual(4, handler.TrackChunkEndHandledCount, "Track chunk: End Handled Count is invalid."); Assert.AreEqual(3, handler.EventHandledCount, "Event: Handled Count is invalid."); }
public void Create_TimeDivision_TimeSignature() { var expectedTimeDivision = new TicksPerQuarterNoteTimeDivision(10000); var expectedTimeSignature = new TimeSignature(3, 8); TestSimpleTempoMap(TempoMap.Create(expectedTimeDivision, expectedTimeSignature), expectedTimeDivision, Tempo.Default, expectedTimeSignature); }
public void Create_TimeDivision_Tempo() { var expectedTimeDivision = new TicksPerQuarterNoteTimeDivision(10000); var expectedTempo = new Tempo(123456); TestSimpleTempoMap(TempoMap.Create(expectedTimeDivision, expectedTempo), expectedTimeDivision, expectedTempo, TimeSignature.Default); }
public void Create_TimeDivision_Tempo_TimeSignature() { var expectedTimeDivision = new TicksPerQuarterNoteTimeDivision(10000); var expectedTempo = Tempo.FromBeatsPerMinute(123); var expectedTimeSignature = new TimeSignature(3, 8); TestSimpleTempoMap(TempoMap.Create(expectedTimeDivision, expectedTempo, expectedTimeSignature), expectedTimeDivision, expectedTempo, expectedTimeSignature); }
public void CheckTempoMapReadingHandler_MultipleTrackChunks() { var timeDivision = new TicksPerQuarterNoteTimeDivision(100); var handler = ReadWithTempoMapReadingHandler( new MidiFile( new TrackChunk( new NoteOnEvent(), new SetTempoEvent(100000), new SetTempoEvent(150000) { DeltaTime = 50 }, new SetTempoEvent(200000), new NoteOffEvent() { DeltaTime = 100 }, new TimeSignatureEvent(3, 4)), new TrackChunk( new SetTempoEvent(300000) { DeltaTime = 50 }, new TimeSignatureEvent(5, 8) { DeltaTime = 1000 })) { TimeDivision = timeDivision }); var tempoMap = handler.TempoMap; Assert.AreEqual(timeDivision, tempoMap.TimeDivision, "Time division is invalid."); CollectionAssert.AreEqual( new[] { new ValueChange <Tempo>(0, new Tempo(100000)), new ValueChange <Tempo>(50, new Tempo(300000)) }, tempoMap.GetTempoChanges(), "Tempo changes collection contains invalid values."); CollectionAssert.AreEqual( new[] { new ValueChange <TimeSignature>(150, new TimeSignature(3, 4)), new ValueChange <TimeSignature>(1050, new TimeSignature(5, 8)) }, tempoMap.GetTimeSignatureChanges(), "Time signature changes collection contains invalid values."); Assert.AreSame(tempoMap, handler.TempoMap, "Tempo map object is changed on second get."); }
private TempoChanger(double secondsPerPop, TicksPerQuarterNoteTimeDivision timeDivision, List <SetTempoEvent> tempoEvents) { SecondsPerPop = secondsPerPop; TimeDivision = timeDivision; tempos = tempoEvents; if (tempoEvents.Count == 0) { throw new ArgumentException("There is no tempo event"); } CurrentTempo = tempoEvents[0]; }
public void Read_Handler_File() { var timeDivision = new TicksPerQuarterNoteTimeDivision(1000); var handler = new FileReadingHandler(); MidiFileTestUtilities.ReadUsingHandlers(new MidiFile { TimeDivision = timeDivision }, handler); Assert.AreEqual(1, handler.StartHandledCount, "Start Handled Count is invalid."); Assert.AreEqual(1, handler.EndHandledCount, "End Handled Count is invalid."); Assert.AreEqual(timeDivision, handler.TimeDivision, "Time division is invalid."); Assert.AreEqual(0, handler.BadHandledCount, "Scope wasn't used correctly."); }
public void CheckTempoMapReadingHandler_MultipleTrackChunks_DontAllowTempoMapUsageDuringReading_AccessDuringReading() { var timeDivision = new TicksPerQuarterNoteTimeDivision(100); var handler = new TempoMapReadingHandler(); var exceptionThrown = false; try { var tempoMap = handler.TempoMap; } catch (InvalidOperationException) { exceptionThrown = true; } MidiFileTestUtilities.ReadUsingHandlers( new MidiFile( new TrackChunk( new NoteOnEvent(), new SetTempoEvent(100000), new SetTempoEvent(150000) { DeltaTime = 50 }, new SetTempoEvent(200000), new NoteOffEvent() { DeltaTime = 100 }, new TimeSignatureEvent(3, 4)), new TrackChunk( new SetTempoEvent(300000) { DeltaTime = 50 }, new TimeSignatureEvent(5, 8) { DeltaTime = 1000 })) { TimeDivision = timeDivision }, handler); Assert.IsTrue(exceptionThrown, "Exception was not thrown on get during read."); Assert.DoesNotThrow(() => { var tempoMap = handler.TempoMap; }, "Exception thrown on get after read."); }
private void OpenMidiFile() { try { _dancerSong = new DancerSong(); OpenFileDialog openFileDialog = new OpenFileDialog { Filter = "MIDI files (*.mid)|*.mid;", InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) }; if (openFileDialog.ShowDialog() == true) { SelectedNote = null; _dancerSong.Midi = MidiFile.Read(openFileDialog.FileName); ParsedNotes = _midiEventsTextParser.ParseFromMidFormat(_dancerSong.Midi); channelId = 0; ChannelTitles = _midiEventsTextParser.ChannelTitles; PresentedNotes = _midiEventsTextParser.NotesInChannel[0]; selectedNotes = new ObservableCollection <Note>(); SplitByChannels(); SelectedChannel = "All channels"; TicksPerQuarterNoteTimeDivision td = playback.TempoMap.TimeDivision as TicksPerQuarterNoteTimeDivision; if (td is null) { throw new NotSupportedException("Time division in this MIDI file is not supported by this application."); } MetricTimeSpan metricTime = TimeConverter.ConvertTo <MetricTimeSpan>(td.TicksPerQuarterNote, playback.TempoMap); _dancerSong.ticksPerSecond = td.TicksPerQuarterNote * 1000 / (metricTime.Seconds * 1000 + metricTime.Milliseconds); EventSystem.Publish <OnMidiLoadedMessage>( new OnMidiLoadedMessage { midiChannels = this.midiChannels, playback = this.playback, midiChannelsTitles = this.channelTitles, ticksPerSecond = _dancerSong.ticksPerSecond, ticksPerquarterNote = td.TicksPerQuarterNote }); } } catch (NotSupportedException ex) { MessageBox.Show(ex.Message); } }
public static TempoChanger FromMidi(double secondsPerPop, TicksPerQuarterNoteTimeDivision timeDivision, MidiFile midi) { var tempos = new List <SetTempoEvent>(); foreach (var chunk in midi.GetTrackChunks()) { long time = 0; foreach (var ev in chunk.Events) { time += ev.DeltaTime; if (ev is SetTempoEvent tempo) { tempos.Add(new SetTempoEvent() { DeltaTime = time, MicrosecondsPerQuarterNote = tempo.MicrosecondsPerQuarterNote, }); } } } tempos.Sort((x, y) => x.DeltaTime.CompareTo(y.DeltaTime)); return(new TempoChanger(secondsPerPop, timeDivision, tempos)); }
public MidiTrackController(double secondsPerPop, TicksPerQuarterNoteTimeDivision timeDivision, List <MidiEvent> trackEvents) { SecondsPerPop = secondsPerPop; TimeDivision = timeDivision; events = trackEvents; }