Exemple #1
0
        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.");
        }
Exemple #2
0
        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.");
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        public void Create_TimeDivision_Tempo()
        {
            var expectedTimeDivision = new TicksPerQuarterNoteTimeDivision(10000);
            var expectedTempo        = new Tempo(123456);

            TestSimpleTempoMap(TempoMap.Create(expectedTimeDivision, expectedTempo),
                               expectedTimeDivision,
                               expectedTempo,
                               TimeSignature.Default);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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.");
        }
Exemple #7
0
        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];
        }
Exemple #8
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.");
        }
Exemple #9
0
        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.");
        }
Exemple #10
0
        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);
            }
        }
Exemple #11
0
        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;
 }