Example #1
0
        private static MidiFile TestNotes(Pattern pattern, ICollection <NoteInfo> expectedNotesInfos, params Tuple <long, Tempo>[] tempoChanges)
        {
            var channel = (FourBitNumber)2;

            TempoMap tempoMap = null;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, channel);

            var expectedNotes = expectedNotesInfos.Select(i =>
            {
                var expectedTime   = TimeConverter.ConvertFrom(i.Time ?? new MetricTime(), tempoMap);
                var expectedLength = LengthConverter.ConvertFrom(i.Length, expectedTime, tempoMap);

                return(new Note(i.NoteNumber, expectedLength, expectedTime)
                {
                    Velocity = i.Velocity,
                    Channel = channel
                });
            });

            Assert.IsTrue(NoteEquality.Equals(expectedNotes, midiFile.GetNotes()));

            return(midiFile);
        }
Example #2
0
            public int Compare(object x, object y)
            {
                var xNote = (Note)x;
                var yNote = (Note)y;

                return(NoteEquality.AreEqual(xNote, yNote) ? 0 : -1);
            }
        public void CheckNotesReadingHandler_MultipleTrackChunks_DontSort()
        {
            var handler = ReadWithNotesReadingHandler(
                new MidiFile(
                    new TrackChunk(
                        new NoteOnEvent((SevenBitNumber)1, (SevenBitNumber)10),
                        new NoteOffEvent((SevenBitNumber)1, (SevenBitNumber)5)
            {
                DeltaTime = 100
            },
                        new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)56)
            {
                DeltaTime = 50, Channel = (FourBitNumber)10
            },
                        new NoteOffEvent((SevenBitNumber)40, (SevenBitNumber)0)
            {
                DeltaTime = 100, Channel = (FourBitNumber)10
            }),
                    new TrackChunk(
                        new NoteOnEvent()
            {
                DeltaTime = 45
            },
                        new NoteOffEvent()
            {
                DeltaTime = 100
            },
                        new TextEvent("test")
            {
                DeltaTime = 50
            },
                        new ControlChangeEvent((SevenBitNumber)40, (SevenBitNumber)45)
            {
                DeltaTime = 100
            })),
                false);

            var notes = handler.Notes;

            NoteEquality.AreEqual(
                notes,
                new[]
            {
                new Note((SevenBitNumber)1, 100, 0)
                {
                    Velocity = (SevenBitNumber)10, OffVelocity = (SevenBitNumber)5
                },
                new Note((SevenBitNumber)0, 100, 45),
                new Note((SevenBitNumber)40, 100, 150)
                {
                    Velocity = (SevenBitNumber)56, Channel = (FourBitNumber)10
                }
            });

            Assert.AreSame(notes, handler.Notes, "Notes collection object is changed on second get.");
        }
Example #4
0
        public void Split_TimeInsideNote()
        {
            var note = new Note((SevenBitNumber)100, 200, 100);
            var time = 120;

            var parts = note.Split(time);

            Assert.IsTrue(NoteEquality.AreEqual(new Note((SevenBitNumber)100, 20, 100), parts.LeftPart),
                          "Left part is invalid.");
            Assert.IsTrue(NoteEquality.AreEqual(new Note((SevenBitNumber)100, 180, 120), parts.RightPart),
                          "Right part is invalid.");
        }
Example #5
0
        public void Clone()
        {
            var note = new Note((SevenBitNumber)100, 500, 123)
            {
                Channel     = (FourBitNumber)10,
                Velocity    = (SevenBitNumber)45,
                OffVelocity = (SevenBitNumber)54
            };

            Assert.IsTrue(NoteEquality.AreEqual(note, note.Clone()),
                          "Clone of a note doesn't equal to the original one.");
        }
Example #6
0
        public static MidiFile TestNotes(Pattern pattern, ICollection <NoteInfo> expectedNotesInfos, params Tuple <long, Tempo>[] tempoChanges)
        {
            TempoMap tempoMap;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, Channel);

            var expectedNotes = expectedNotesInfos.Select(i =>
            {
                var expectedTime   = TimeConverter.ConvertFrom(i.Time ?? new MetricTimeSpan(), tempoMap);
                var expectedLength = LengthConverter.ConvertFrom(i.Length, expectedTime, tempoMap);

                return(new DryWetMidi.Interaction.Note(i.NoteNumber, expectedLength, expectedTime)
                {
                    Velocity = i.Velocity,
                    Channel = Channel
                });
            })
                                .OrderBy(n => n.Time)
                                .ToArray();

            var actualNotes = midiFile.GetNotes().ToArray();

            Assert.AreEqual(expectedNotes.Length, actualNotes.Length, "Notes count is invalid.");

            var j = 0;

            foreach (var expectedActual in expectedNotes.Zip(actualNotes, (e, a) => new { Expected = e, Actual = a }))
            {
                var expectedNote = expectedActual.Expected;
                var actualNote   = expectedActual.Actual;

                Assert.IsTrue(NoteEquality.AreEqual(expectedNote, actualNote), $"Note {j} is invalid. Expected: {expectedNote}; actual: {actualNote}.");
                j++;
            }

            return(midiFile);
        }
Example #7
0
        public void Split_TimeAboveEndTime()
        {
            Func <Note> noteCreator = () => new Note((SevenBitNumber)100, 200, 100);

            var note = noteCreator();
            var time = 500;

            var parts = note.Split(time);

            Assert.IsNull(parts.RightPart,
                          "Right part is not null.");
            Assert.AreNotSame(parts.LeftPart,
                              note,
                              "Left part refers to the same object as the original note.");
            Assert.IsTrue(NoteEquality.AreEqual(noteCreator(), parts.LeftPart),
                          "Left part doesn't equal to the original note.");
        }
        private void CheckTrackNotesWithoutOutputDevice(
            ICollection <EventToSend> eventsToSend,
            ICollection <EventToSend> eventsWillBeSent,
            TimeSpan moveFrom,
            TimeSpan moveTo,
            IEnumerable <int> notesWillBeStarted,
            IEnumerable <int> notesWillBeFinished)
        {
            var playbackContext = new PlaybackContext();

            var stopwatch = playbackContext.Stopwatch;
            var tempoMap  = playbackContext.TempoMap;

            var eventsForPlayback = GetEventsForPlayback(eventsToSend, tempoMap);

            var notes         = eventsForPlayback.GetNotes().ToArray();
            var notesStarted  = new List <Note>();
            var notesFinished = new List <Note>();

            using (var playback = new Playback(eventsForPlayback, tempoMap))
            {
                playback.TrackNotes             = true;
                playback.NotesPlaybackStarted  += (_, e) => notesStarted.AddRange(e.Notes);
                playback.NotesPlaybackFinished += (_, e) => notesFinished.AddRange(e.Notes);

                stopwatch.Start();
                playback.Start();

                SpinWait.SpinUntil(() => stopwatch.Elapsed >= moveFrom);
                playback.MoveToTime((MetricTimeSpan)moveTo);

                Thread.Sleep(TimeSpan.FromTicks(eventsWillBeSent.Sum(e => e.Delay.Ticks)) + SendReceiveUtilities.MaximumEventSendReceiveDelay);

                stopwatch.Stop();

                var playbackStopped = SpinWait.SpinUntil(() => !playback.IsRunning, SendReceiveUtilities.MaximumEventSendReceiveDelay);
                Assert.IsTrue(playbackStopped, "Playback is running after completed.");
            }

            Assert.IsTrue(NoteEquality.AreEqual(notesStarted, notesWillBeStarted.Select(i => notes[i])), "Invalid notes started.");
            Assert.IsTrue(NoteEquality.AreEqual(notesFinished, notesWillBeFinished.Select(i => notes[i])), "Invalid notes finished.");
        }
Example #9
0
        public void SplitByNotes_DifferentChannels()
        {
            var tempoMap = TempoMap.Default;
            var channel1 = (FourBitNumber)10;
            var channel2 = (FourBitNumber)4;

            var trackChunk1 = new PatternBuilder()
                              .SetNoteLength(MusicalTimeSpan.Quarter)
                              .SetOctave(Octave.Get(2))

                              .Note(NoteName.A)
                              .Note(NoteName.C)

                              .Build()
                              .ToTrackChunk(tempoMap, channel1);

            var trackChunk2 = new PatternBuilder()
                              .SetNoteLength(MusicalTimeSpan.Eighth)
                              .SetOctave(Octave.Get(3))
                              .StepForward(MusicalTimeSpan.ThirtySecond)

                              .Note(NoteName.D)
                              .Note(NoteName.DSharp)

                              .Build()
                              .ToTrackChunk(tempoMap, channel2);

            var midiFile = new MidiFile(trackChunk1, trackChunk2);
            var notes    = midiFile.GetNotes().ToList();

            var filesByNotes = midiFile.SplitByNotes().ToList();

            Assert.AreEqual(4, filesByNotes.Count, "New files count is invalid.");

            Assert.IsTrue(NoteEquality.AreEqual(filesByNotes[0].GetNotes(), new[] { notes[0] }));
            Assert.IsTrue(NoteEquality.AreEqual(filesByNotes[1].GetNotes(), new[] { notes[1] }));
            Assert.IsTrue(NoteEquality.AreEqual(filesByNotes[2].GetNotes(), new[] { notes[2] }));
            Assert.IsTrue(NoteEquality.AreEqual(filesByNotes[3].GetNotes(), new[] { notes[3] }));
        }
Example #10
0
        public void SplitByNotes_SingleChannel()
        {
            var tempoMap = TempoMap.Default;

            var midiFile = new PatternBuilder()
                           .SetNoteLength(MusicalTimeSpan.Quarter)
                           .SetOctave(Octave.Get(2))

                           .Note(NoteName.A)

                           .ProgramChange((SevenBitNumber)20)
                           .Note(NoteName.C)

                           .Build()
                           .ToFile(tempoMap);

            var filesByNotes = midiFile.SplitByNotes().ToList();

            Assert.AreEqual(2, filesByNotes.Count, "New files count is invalid.");

            var notes = midiFile.GetNotes().ToList();

            Assert.IsTrue(NoteEquality.AreEqual(filesByNotes[0].GetNotes(), new[] { notes[0] }));
            Assert.IsTrue(NoteEquality.AreEqual(filesByNotes[1].GetNotes(), new[] { notes[1] }));

            var timedEvents = midiFile.GetTimedEvents().Where(e => !(e.Event is NoteEvent)).ToList();

            Assert.IsTrue(TimedEventEquality.AreEqual(filesByNotes[0].GetTimedEvents()
                                                      .Where(e => !(e.Event is NoteEvent)),
                                                      timedEvents,
                                                      false));
            Assert.IsTrue(TimedEventEquality.AreEqual(filesByNotes[1].GetTimedEvents()
                                                      .Where(e => !(e.Event is NoteEvent)),
                                                      timedEvents,
                                                      false));
        }
Example #11
0
        private void CheckNoteCallback(
            ICollection <EventToSend> eventsToSend,
            ICollection <ReceivedEvent> expectedReceivedEvents,
            TimeSpan changeCallbackAfter,
            NoteCallback noteCallback,
            NoteCallback secondNoteCallback,
            ICollection <Note> expectedNotesStarted,
            ICollection <Note> expectedNotesFinished)
        {
            var playbackContext = new PlaybackContext();

            var receivedEvents = playbackContext.ReceivedEvents;
            var sentEvents     = playbackContext.SentEvents;
            var stopwatch      = playbackContext.Stopwatch;
            var tempoMap       = playbackContext.TempoMap;

            var eventsForPlayback = GetEventsForPlayback(eventsToSend, tempoMap);

            var notesStarted  = new List <Note>();
            var notesFinished = new List <Note>();

            using (var outputDevice = OutputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
            {
                SendReceiveUtilities.WarmUpDevice(outputDevice);
                outputDevice.EventSent += (_, e) => sentEvents.Add(new SentEvent(e.Event, stopwatch.Elapsed));

                using (var playback = new Playback(eventsForPlayback, tempoMap, outputDevice))
                {
                    playback.NotesPlaybackStarted  += (_, e) => notesStarted.AddRange(e.Notes);
                    playback.NotesPlaybackFinished += (_, e) => notesFinished.AddRange(e.Notes);

                    playback.NoteCallback = noteCallback;

                    using (var inputDevice = InputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
                    {
                        inputDevice.EventReceived += (_, e) =>
                        {
                            lock (playbackContext.ReceivedEventsLockObject)
                            {
                                receivedEvents.Add(new ReceivedEvent(e.Event, stopwatch.Elapsed));
                            }
                        };

                        inputDevice.StartEventsListening();
                        stopwatch.Start();
                        playback.Start();

                        SpinWait.SpinUntil(() => stopwatch.Elapsed >= changeCallbackAfter);
                        playback.NoteCallback = secondNoteCallback;

                        var timeout         = TimeSpan.FromTicks(eventsToSend.Sum(e => e.Delay.Ticks)) + SendReceiveUtilities.MaximumEventSendReceiveDelay;
                        var playbackStopped = SpinWait.SpinUntil(() => !playback.IsRunning, timeout);
                        Assert.IsTrue(playbackStopped, "Playback is running after completed.");
                    }
                }
            }

            CompareReceivedEvents(receivedEvents, expectedReceivedEvents.ToList());

            Assert.IsTrue(NoteEquality.AreEqual(notesStarted, expectedNotesStarted), "Invalid notes started.");
            Assert.IsTrue(NoteEquality.AreEqual(notesFinished, expectedNotesFinished), "Invalid notes finished.");
        }
Example #12
0
        private void CheckTrackNotesWithOutputDevice(
            ICollection <EventToSend> eventsToSend,
            ICollection <EventToSend> eventsWillBeSent,
            TimeSpan moveFrom,
            TimeSpan moveTo,
            IEnumerable <int> notesWillBeStarted,
            IEnumerable <int> notesWillBeFinished)
        {
            var playbackContext = new PlaybackContext();

            var receivedEvents = playbackContext.ReceivedEvents;
            var sentEvents     = playbackContext.SentEvents;
            var stopwatch      = playbackContext.Stopwatch;
            var tempoMap       = playbackContext.TempoMap;

            var eventsForPlayback = GetEventsForPlayback(eventsToSend, tempoMap);

            var notes         = eventsForPlayback.GetNotes().ToArray();
            var notesStarted  = new List <Note>();
            var notesFinished = new List <Note>();

            using (var outputDevice = OutputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
            {
                SendReceiveUtilities.WarmUpDevice(outputDevice);
                outputDevice.EventSent += (_, e) => sentEvents.Add(new SentEvent(e.Event, stopwatch.Elapsed));

                using (var playback = new Playback(eventsForPlayback, tempoMap, outputDevice))
                {
                    playback.TrackNotes             = true;
                    playback.NotesPlaybackStarted  += (_, e) => notesStarted.AddRange(e.Notes);
                    playback.NotesPlaybackFinished += (_, e) => notesFinished.AddRange(e.Notes);

                    using (var inputDevice = InputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
                    {
                        inputDevice.EventReceived += (_, e) =>
                        {
                            lock (playbackContext.ReceivedEventsLockObject)
                            {
                                receivedEvents.Add(new ReceivedEvent(e.Event, stopwatch.Elapsed));
                            }
                        };
                        inputDevice.StartEventsListening();
                        stopwatch.Start();
                        playback.Start();

                        SpinWait.SpinUntil(() => stopwatch.Elapsed >= moveFrom);
                        playback.MoveToTime((MetricTimeSpan)moveTo);

                        var timeout           = TimeSpan.FromTicks(eventsWillBeSent.Sum(e => e.Delay.Ticks)) + SendReceiveUtilities.MaximumEventSendReceiveDelay;
                        var areEventsReceived = SpinWait.SpinUntil(() => receivedEvents.Count == eventsWillBeSent.Count, timeout);
                        Assert.IsTrue(areEventsReceived, $"Events are not received for timeout {timeout}.");

                        stopwatch.Stop();

                        var playbackStopped = SpinWait.SpinUntil(() => !playback.IsRunning, SendReceiveUtilities.MaximumEventSendReceiveDelay);
                        Assert.IsTrue(playbackStopped, "Playback is running after completed.");
                    }
                }
            }

            CompareSentReceivedEvents(sentEvents, receivedEvents, eventsWillBeSent.ToList());

            Assert.IsTrue(NoteEquality.AreEqual(notesStarted, notesWillBeStarted.Select(i => notes[i])), "Invalid notes started.");
            Assert.IsTrue(NoteEquality.AreEqual(notesFinished, notesWillBeFinished.Select(i => notes[i])), "Invalid notes finished.");
        }
        public void CheckNotesReadingHandler_SingleTrackChunk(bool sortNotes)
        {
            var handler = ReadWithNotesReadingHandler(
                new MidiFile(
                    new TrackChunk(
                        new SetTempoEvent(1234),
                        new NoteOnEvent((SevenBitNumber)1, (SevenBitNumber)100)
            {
                DeltaTime = 10, Channel = (FourBitNumber)1
            },
                        new NoteOnEvent((SevenBitNumber)2, (SevenBitNumber)70)
            {
                DeltaTime = 10, Channel = (FourBitNumber)1
            },
                        new PitchBendEvent(123)
            {
                DeltaTime = 10
            },
                        new MarkerEvent("Marker")
            {
                DeltaTime = 10
            },
                        new NoteOnEvent((SevenBitNumber)3, (SevenBitNumber)1)
            {
                Channel = (FourBitNumber)1
            },
                        new MarkerEvent("Marker 2")
            {
                DeltaTime = 10
            },
                        new TextEvent("Text")
            {
                DeltaTime = 10
            },
                        new TextEvent("Text 2")
            {
                DeltaTime = 10
            },
                        new NoteOnEvent((SevenBitNumber)2, (SevenBitNumber)1)
            {
                Channel = (FourBitNumber)10
            },
                        new CuePointEvent("Point")
            {
                DeltaTime = 10
            },
                        new NoteOffEvent((SevenBitNumber)3, (SevenBitNumber)1)
            {
                Channel = (FourBitNumber)1
            },
                        new NoteOffEvent((SevenBitNumber)1, (SevenBitNumber)0)
            {
                DeltaTime = 10, Channel = (FourBitNumber)1
            },
                        new NoteOffEvent((SevenBitNumber)2, (SevenBitNumber)0)
            {
                Channel = (FourBitNumber)10
            },
                        new NoteOffEvent((SevenBitNumber)2, (SevenBitNumber)0)
            {
                DeltaTime = 10, Channel = (FourBitNumber)1
            })),
                sortNotes);

            var notes = handler.Notes;

            NoteEquality.AreEqual(
                notes,
                new[]
            {
                new Note((SevenBitNumber)1, 80, 10)
                {
                    Channel = (FourBitNumber)1, Velocity = (SevenBitNumber)100
                },
                new Note((SevenBitNumber)2, 80, 20)
                {
                    Channel = (FourBitNumber)1, Velocity = (SevenBitNumber)70
                },
                new Note((SevenBitNumber)3, 40, 40)
                {
                    Channel = (FourBitNumber)1, Velocity = (SevenBitNumber)1, OffVelocity = (SevenBitNumber)1
                },
                new Note((SevenBitNumber)2, 20, 70)
                {
                    Channel = (FourBitNumber)10, Velocity = (SevenBitNumber)1
                }
            });

            Assert.AreSame(notes, handler.Notes, "Notes collection object is changed on second get.");
        }