示例#1
0
        public void ResizeByRatio_EmptyFile()
        {
            var midiFile = new MidiFile();

            midiFile.Resize(2.0);
            Assert.IsTrue(TimedEventEquality.AreEqual(midiFile.GetTimedEvents(), Enumerable.Empty <TimedEvent>(), false));
        }
示例#2
0
        public void Resize_EmptyFile()
        {
            var midiFile = new MidiFile();

            midiFile.Resize(new MetricTimeSpan(1, 0, 0));
            Assert.IsTrue(TimedEventEquality.AreEqual(midiFile.GetTimedEvents(), Enumerable.Empty <TimedEvent>(), false));
        }
示例#3
0
        public void Resize_Midi()
        {
            var timedEvents = new[]
            {
                new TimedEvent(new SetTempoEvent(200000), 0),
                new TimedEvent(new TextEvent("Text"), 100),
                new TimedEvent(new TextEvent("Text 2"), 150),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)10, (SevenBitNumber)100), 50),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)10, (SevenBitNumber)50), 80)
            };

            var midiFile = timedEvents.ToFile();

            midiFile.Resize((ITimeSpan)(MidiTimeSpan)15000);

            Assert.IsTrue(TimedEventEquality.AreEqual(
                              midiFile.GetTimedEvents(),
                              new[]
            {
                new TimedEvent(new SetTempoEvent(200000), 0),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)10, (SevenBitNumber)100), 5000),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)10, (SevenBitNumber)50), 8000),
                new TimedEvent(new TextEvent("Text"), 10000),
                new TimedEvent(new TextEvent("Text 2"), 15000),
            },
                              false));
        }
示例#4
0
        public void CheckTimedEventsReadingHandler_SingleTrackChunk(bool sortEvents)
        {
            var handler = ReadWithTimedEventsReadingHandler(
                new MidiFile(
                    new TrackChunk(
                        new NoteOnEvent(),
                        new NoteOffEvent()
            {
                DeltaTime = 100
            },
                        new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)56)
            {
                DeltaTime = 50
            },
                        new NoteOffEvent((SevenBitNumber)40, (SevenBitNumber)0)
            {
                DeltaTime = 100
            })),
                sortEvents);

            var timedEvents = handler.TimedEvents;

            TimedEventEquality.AreEqual(
                timedEvents,
                new[]
            {
                new TimedEvent(new NoteOnEvent(), 0),
                new TimedEvent(new NoteOffEvent(), 100),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)56), 150),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)0), 200),
            },
                true);

            Assert.AreSame(timedEvents, handler.TimedEvents, "Timed events collection object is changed on second get.");
        }
示例#5
0
        public void Clone()
        {
            var timedEvent = new TimedEvent(new NoteOnEvent((SevenBitNumber)100, (SevenBitNumber)50));

            Assert.IsTrue(TimedEventEquality.AreEqual(timedEvent, timedEvent.Clone(), true),
                          "Clone of a timed event doesn't equal to the original one.");
        }
示例#6
0
        private static void TestTimedEventsWithExactOrder(
            Pattern pattern,
            ICollection <TimedEventInfo> expectedTimedEventsInfos,
            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 expectedTimedEvents = expectedTimedEventsInfos.Select(i =>
                                                                      new TimedEvent(i.Event, TimeConverter.ConvertFrom(i.Time ?? new MidiTimeSpan(), tempoMap)));

            var actualTimedEvents = midiFile.GetTimedEvents();

            Assert.IsTrue(TimedEventEquality.AreEqual(expectedTimedEvents, actualTimedEvents, false), "Events have invalid order.");
        }
示例#7
0
        private static void TestTimedEvents(
            Pattern pattern,
            ICollection <TimedEventInfo> expectedTimedEventsInfos,
            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 expectedTimedEvents = expectedTimedEventsInfos.Select(i =>
                                                                      new TimedEvent(i.Event,
                                                                                     TimeConverter.ConvertFrom(i.Time ?? new MidiTimeSpan(), tempoMap)));

            var actualTimedEvents = midiFile.GetTimedEvents();

            foreach (var expectedEvent in expectedTimedEvents)
            {
                Assert.IsTrue(actualTimedEvents.Any(actual => TimedEventEquality.AreEqual(expectedEvent, actual, false)),
                              $"There are no event: {expectedEvent}");
            }
        }
示例#8
0
        public void CheckTimedEventsReadingHandler_MultipleTrackChunks_Sort()
        {
            var handler = ReadWithTimedEventsReadingHandler(
                new MidiFile(
                    new TrackChunk(
                        new NoteOnEvent(),
                        new NoteOffEvent()
            {
                DeltaTime = 100
            },
                        new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)56)
            {
                DeltaTime = 50
            },
                        new NoteOffEvent((SevenBitNumber)40, (SevenBitNumber)0)
            {
                DeltaTime = 100
            }),
                    new TrackChunk(
                        new NoteOnEvent()
            {
                DeltaTime = 45
            },
                        new NoteOffEvent()
            {
                DeltaTime = 100
            },
                        new TextEvent("test")
            {
                DeltaTime = 50
            },
                        new ControlChangeEvent((SevenBitNumber)40, (SevenBitNumber)45)
            {
                DeltaTime = 100
            })),
                true);

            var timedEvents = handler.TimedEvents;

            TimedEventEquality.AreEqual(
                timedEvents,
                new[]
            {
                new TimedEvent(new NoteOnEvent(), 0),
                new TimedEvent(new NoteOnEvent(), 45),
                new TimedEvent(new NoteOffEvent(), 100),
                new TimedEvent(new NoteOffEvent(), 145),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)56), 150),
                new TimedEvent(new TextEvent("test"), 195),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)40, (SevenBitNumber)0), 200),
                new TimedEvent(new ControlChangeEvent((SevenBitNumber)40, (SevenBitNumber)45), 295),
            },
                true);

            Assert.AreSame(timedEvents, handler.TimedEvents, "Timed events collection object is changed on second get.");
        }
        public void ConvertCsvToMidiFile_SingleTrackChunk_MetricTimes(MidiFileCsvLayout layout, bool orderEvents, string[] csvLines)
        {
            if (!orderEvents)
            {
                var tmp = csvLines[2];
                csvLines[2] = csvLines[5];
                csvLines[5] = tmp;
            }

            var midiFile = ConvertCsvToMidiFile(layout, TimeSpanType.Metric, csvLines);

            TempoMap expectedTempoMap;

            using (var tempoMapManager = new TempoMapManager(new TicksPerQuarterNoteTimeDivision(500)))
            {
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 1, 3), new Tempo(300000));
                expectedTempoMap = tempoMapManager.TempoMap;
            }

            var expectedEvents = new[]
            {
                new TimeAndMidiEvent(new MetricTimeSpan(),
                                     new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)120)
                {
                    Channel = (FourBitNumber)10
                }),
                new TimeAndMidiEvent(new MetricTimeSpan(),
                                     new TextEvent("Test")),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 1, 0),
                                     new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)110)
                {
                    Channel = (FourBitNumber)7
                }),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 1, 3),
                                     new SetTempoEvent(300000)),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 1, 10),
                                     new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)70)
                {
                    Channel = (FourBitNumber)10
                }),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 10, 3),
                                     new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)80)
                {
                    Channel = (FourBitNumber)7
                })
            }
            .Select(te => new TimedEvent(te.Event, TimeConverter.ConvertFrom(te.Time, expectedTempoMap)))
            .ToArray();

            Assert.AreEqual(1, midiFile.GetTrackChunks().Count(), "Track chunks count is invalid.");
            CollectionAssert.AreEqual(midiFile.GetTempoMap().GetTempoChanges(), expectedTempoMap.GetTempoChanges(), "Invalid tempo map.");
            Assert.AreEqual(new TicksPerQuarterNoteTimeDivision(500), midiFile.TimeDivision, "Invalid time division.");
            Assert.IsTrue(TimedEventEquality.AreEqual(expectedEvents, midiFile.GetTimedEvents(), false),
                          "Invalid events.");
        }
        public void SaveRecordingToFile()
        {
            var tempoMap = TempoMap.Default;

            var eventsToSend = new[]
            {
                new EventToSend(new NoteOnEvent(), TimeSpan.Zero),
                new EventToSend(new NoteOffEvent(), TimeSpan.FromMilliseconds(500)),
                new EventToSend(new ProgramChangeEvent((SevenBitNumber)40), TimeSpan.FromSeconds(5)),
                new EventToSend(new ActiveSensingEvent(), TimeSpan.FromMilliseconds(100)),
                new EventToSend(new ProgramChangeEvent((SevenBitNumber)50), TimeSpan.FromMilliseconds(500)),
            };

            using (var outputDevice = OutputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
            {
                SendReceiveUtilities.WarmUpDevice(outputDevice);

                using (var inputDevice = InputDevice.GetByName(SendReceiveUtilities.DeviceToTestOnName))
                {
                    var receivedEventsNumber = 0;

                    inputDevice.StartEventsListening();
                    inputDevice.EventReceived += (_, __) => receivedEventsNumber++;

                    using (var recording = new Recording(tempoMap, inputDevice))
                    {
                        var sendingThread = new Thread(() =>
                        {
                            SendReceiveUtilities.SendEvents(eventsToSend, outputDevice);
                        });

                        recording.Start();
                        sendingThread.Start();

                        SpinWait.SpinUntil(() => !sendingThread.IsAlive && receivedEventsNumber == eventsToSend.Length);
                        recording.Stop();

                        var midiFile    = recording.ToFile();
                        var timedEvents = midiFile.GetTimedEvents();

                        var expectedEvents = new[]
                        {
                            new TimedEvent(new NoteOnEvent(), TimeConverter.ConvertFrom((MetricTimeSpan)TimeSpan.Zero, tempoMap)),
                            new TimedEvent(new NoteOffEvent(), TimeConverter.ConvertFrom((MetricTimeSpan)TimeSpan.FromMilliseconds(500), tempoMap)),
                            new TimedEvent(new ProgramChangeEvent((SevenBitNumber)40), TimeConverter.ConvertFrom((MetricTimeSpan)TimeSpan.FromSeconds(5.5), tempoMap)),
                            new TimedEvent(new ProgramChangeEvent((SevenBitNumber)50), TimeConverter.ConvertFrom((MetricTimeSpan)TimeSpan.FromSeconds(6.1), tempoMap))
                        };

                        Assert.IsTrue(
                            TimedEventEquality.AreEqual(expectedEvents, timedEvents, false, 10),
                            "Timed events saved incorrectly.");
                    }
                }
            }
        }
示例#11
0
 private static void CompareTimedEvents(
     IEnumerable <TimedEvent> actualTimedEvents,
     IEnumerable <TimedEvent> expectedTimedEvents,
     string message)
 {
     Assert.IsTrue(TimedEventEquality.AreEqual(
                       actualTimedEvents,
                       expectedTimedEvents,
                       false),
                   message);
 }
示例#12
0
        public void ManageTimedEvents_CustomSameTimeEventsComparer()
        {
            var originalTimedEvents = new[]
            {
                new TimedEvent(new LyricEvent("X"), 100),
                new TimedEvent(new LyricEvent("Y"), 100)
            };

            var expectedTimedEvents = new[]
            {
                new TimedEvent(new LyricEvent("Y"), 100),
                new TimedEvent(new LyricEvent("X"), 100)
            };

            //

            using (var timedEventsManager = new TrackChunk().ManageTimedEvents())
            {
                var events = timedEventsManager.Events;
                events.Add(originalTimedEvents);

                var sortedEvents = events.ToList();

                var eventsSortedProperly = TimedEventEquality.AreEqual(expectedTimedEvents, sortedEvents, false);
                Assert.IsFalse(eventsSortedProperly, "Events have valid order without custom same-time comparison.");
            }

            //

            Comparison <MidiEvent> sameTimeEventsComparison = (e1, e2) =>
            {
                var lyricEvent1 = (LyricEvent)e1;
                var lyricEvent2 = (LyricEvent)e2;

                if (lyricEvent1.Text == "X" && lyricEvent2.Text != "X")
                {
                    return(1);
                }

                return(0);
            };

            using (var timedEventsManager = new TrackChunk().ManageTimedEvents(sameTimeEventsComparison))
            {
                var events = timedEventsManager.Events;
                events.Add(originalTimedEvents);

                var sortedEvents = events.ToList();

                var eventsSortedProperly = TimedEventEquality.AreEqual(expectedTimedEvents, sortedEvents, false);
                Assert.IsTrue(eventsSortedProperly, "Events have invalid order with custom same-time comparison.");
            }
        }
        public void ConvertCsvToMidiFile_NewLines(MidiFileCsvLayout layout, string[] csvLines)
        {
            var midiFile = ConvertCsvToMidiFile(layout, TimeSpanType.Midi, csvLines);

            var expectedEvents = new[]
            {
                new TimedEvent(new TextEvent($"Test{Environment.NewLine} text wi\rth ne\nw line"), 0),
                new TimedEvent(new MarkerEvent("Marker"), 100),
                new TimedEvent(new TextEvent($"Test{Environment.NewLine} text with new line and{Environment.NewLine} new \"line again"), 200),
            };

            Assert.IsTrue(TimedEventEquality.AreEqual(expectedEvents, midiFile.GetTimedEvents(), false),
                          "Invalid events.");
        }
        public void ConvertCsvToMidiFile_SingleTrackChunk(MidiFileCsvLayout layout, bool orderEvents, string[] csvLines)
        {
            if (!orderEvents)
            {
                var tmp = csvLines[2];
                csvLines[2] = csvLines[4];
                csvLines[4] = tmp;
            }

            var midiFile = ConvertCsvToMidiFile(layout, TimeSpanType.Midi, csvLines);

            var expectedEvents = new[]
            {
                new TimedEvent(new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)120)
                {
                    Channel = (FourBitNumber)10
                }, 0),
                new TimedEvent(new TextEvent("Test"), 0),
                new TimedEvent(new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)110)
                {
                    Channel = (FourBitNumber)7
                }, 100),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)70)
                {
                    Channel = (FourBitNumber)10
                }, 250),
                new TimedEvent(new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)80)
                {
                    Channel = (FourBitNumber)7
                }, 1000)
            };

            Assert.AreEqual(1, midiFile.GetTrackChunks().Count(), "Track chunks count is invalid.");
            Assert.IsTrue(TimedEventEquality.AreEqual(expectedEvents, midiFile.GetTimedEvents(), false),
                          "Invalid events.");
        }
示例#15
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));
        }
示例#16
0
        private static MidiFile TestTimedEvents(Pattern pattern, ICollection <TimedEventInfo> expectedTimedEventsInfos, 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 expectedTimedEvents = expectedTimedEventsInfos.Select(i =>
                                                                      new TimedEvent(i.Event,
                                                                                     TimeConverter.ConvertFrom(i.Time ?? new MetricTimeSpan(), tempoMap)));

            var actualTimedEvents = midiFile.GetTimedEvents();

            Assert.IsTrue(expectedTimedEvents.All(expected => actualTimedEvents.Any(actual => TimedEventEquality.Equals(expected, actual))));

            return(midiFile);
        }