static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("Usage AlphaTab.ScoreDump.exe PathToFile PathToSoundFont"); return; } // load score var score = ScoreLoader.LoadScoreFromBytes(File.ReadAllBytes(args[0])); // generate midi var midiFile = new MidiFile(); var handler = new AlphaSynthMidiFileHandler(midiFile); var generator = new MidiFileGenerator(score, null, handler); generator.Generate(); var player = new AlphaSynth(new NAudioSynthOutput()); player.MidiLoaded += () => { Console.WriteLine("Midi loaded"); }; player.SoundFontLoaded += () => { Console.WriteLine("SoundFont loaded"); }; player.MidiLoadFailed += e => { Console.WriteLine("Midi load failed"); }; player.SoundFontLoadFailed += e => { Console.WriteLine("SoundFont load failed"); }; player.Finished += _ => { Console.WriteLine("Playback finished"); ((NAudioSynthOutput)player.Output).Close(); }; player.PositionChanged += e => { TimeSpan currentTime = TimeSpan.FromMilliseconds(e.CurrentTime); TimeSpan endTime = TimeSpan.FromMilliseconds(e.EndTime); Console.CursorTop--; Console.Write("".PadLeft(Console.BufferWidth - 1, ' ')); Console.CursorLeft = 0; Console.WriteLine("{0:mm\\:ss\\:fff} ({1}) of {2:mm\\:ss\\:fff} ({3})", currentTime, e.CurrentTick, endTime, e.EndTick); }; player.ReadyForPlayback += () => { Console.WriteLine("Ready for playback"); }; player.LoadSoundFont(File.ReadAllBytes(args[1])); player.LoadMidi(midiFile); Console.WriteLine("Start playing"); player.Play(); Console.WriteLine("Press enter to exit"); Console.ReadLine(); player.Pause(); Console.ReadLine(); }
public void TestPcmGeneration() { var tex = "\\tempo 102 \\tuning E4 B3 G3 D3 A2 E2 \\instrument 25 . r.8 (0.4 0.3 ).8 " + "(-.3 -.4 ).2 {d } | (0.4 0.3 ).8 r.8 (3.3 3.4 ).8 r.8 (5.4 5.3 ).4 r.8 (0.4 0.3 ).8 |" + " r.8 (3.4 3.3 ).8 r.8 (6.3 6.4 ).8 (5.4 5.3 ).4 {d }r.8 |" + " (0.4 0.3).8 r.8(3.4 3.3).8 r.8(5.4 5.3).4 r.8(3.4 3.3).8 | " + "r.8(0.4 0.3).8(-.3 - .4).2 { d } | "; var importer = new AlphaTexImporter(); importer.Init(TestPlatform.CreateStringReader(tex)); var score = importer.ReadScore(); var midi = new MidiFile(); var gen = new MidiFileGenerator(score, null, new AlphaSynthMidiFileHandler(midi)); gen.Generate(); var testOutput = new TestOutput(); var synth = new AlphaSynth(testOutput); synth.LoadSoundFont(TestPlatform.LoadFile("TestFiles/Audio/default.sf2")); synth.LoadMidi(midi); synth.Play(); var finished = false; synth.Finished += b => finished = true; while (!finished) { testOutput.Continue(); } //Console.WriteLine(testOutput.Samples.Count); //using (var writer = new BinaryWriter(new FileStream("test.pcm", FileMode.Create, FileAccess.Write))) //{ // for (int i = 0; i < testOutput.Samples.Count; i++) // { // writer.Write(testOutput.Samples[i]); // } //} }
static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("Usage AlphaTab.MidiDump.exe Path"); return; } // load score var score = ScoreLoader.LoadScoreFromBytes(File.ReadAllBytes(args[0])); // generate midi MidiFile file = MidiFileGenerator.GenerateMidiFile(score); // write midi file string path = Path.ChangeExtension(args[0], "mid"); using (var fs = new StreamWrapper(File.OpenWrite(path))) { file.WriteTo(fs); } }
public void TestBend() { var tex = ":4 15.6{b(0 4)} 15.6"; var score = ParseTex(tex); Assert.AreEqual(1, score.Tracks.Count); Assert.AreEqual(1, score.Tracks[0].Bars.Count); Assert.AreEqual(1, score.Tracks[0].Bars[0].Voices.Count); Assert.AreEqual(2, score.Tracks[0].Bars[0].Voices[0].Beats.Count); Assert.AreEqual(1, score.Tracks[0].Bars[0].Voices[0].Beats[0].Notes.Count); Assert.AreEqual(1, score.Tracks[0].Bars[0].Voices[0].Beats[1].Notes.Count); var handler = new FlatMidiEventGenerator(); var generator = new MidiFileGenerator(score, handler); generator.Generate(); var info = score.Tracks[0].PlaybackInfo; var note = score.Tracks[0].Bars[0].Voices[0].Beats[0].Notes[0]; var expectedEvents = new FlatMidiEventGenerator.MidiEvent[] { // channel init new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.Volume, Value = 120 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.Balance, Value = 64 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.Expression, Value = 127 }, new FlatMidiEventGenerator.ProgramChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Program = (byte)info.Program }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.Volume, Value = 120 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.Balance, Value = 64 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.Expression, Value = 127 }, new FlatMidiEventGenerator.ProgramChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Program = (byte)info.Program }, new FlatMidiEventGenerator.TimeSignatureEvent { Tick = 0, Numerator = 4, Denominator = 4 }, new FlatMidiEventGenerator.TempoEvent { Tick = 0, Tempo = 120 }, // bend effect new FlatMidiEventGenerator.BendEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Value = 64 }, // no bend new FlatMidiEventGenerator.BendEvent { Tick = 87, Track = 0, Channel = info.PrimaryChannel, Value = 65 }, new FlatMidiEventGenerator.BendEvent { Tick = 174, Track = 0, Channel = info.PrimaryChannel, Value = 66 }, new FlatMidiEventGenerator.BendEvent { Tick = 261, Track = 0, Channel = info.PrimaryChannel, Value = 67 }, new FlatMidiEventGenerator.BendEvent { Tick = 349, Track = 0, Channel = info.PrimaryChannel, Value = 68 }, new FlatMidiEventGenerator.BendEvent { Tick = 436, Track = 0, Channel = info.PrimaryChannel, Value = 69 }, new FlatMidiEventGenerator.BendEvent { Tick = 523, Track = 0, Channel = info.PrimaryChannel, Value = 70 }, new FlatMidiEventGenerator.BendEvent { Tick = 610, Track = 0, Channel = info.PrimaryChannel, Value = 71 }, new FlatMidiEventGenerator.BendEvent { Tick = 698, Track = 0, Channel = info.PrimaryChannel, Value = 72 }, new FlatMidiEventGenerator.BendEvent { Tick = 785, Track = 0, Channel = info.PrimaryChannel, Value = 73 }, new FlatMidiEventGenerator.BendEvent { Tick = 872, Track = 0, Channel = info.PrimaryChannel, Value = 74 }, new FlatMidiEventGenerator.BendEvent { Tick = 959, Track = 0, Channel = info.PrimaryChannel, Value = 75 }, new FlatMidiEventGenerator.BendEvent { Tick = 960, Track = 0, Channel = info.PrimaryChannel, Value = 64 }, // note itself new FlatMidiEventGenerator.NoteEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, DynamicValue = note.Dynamic, Key = (byte)note.RealValue, Length = note.Beat.Duration.ToTicks() }, new FlatMidiEventGenerator.NoteEvent { Tick = 960, Track = 0, Channel = info.PrimaryChannel, DynamicValue = note.Dynamic, Key = (byte)note.RealValue, Length = note.Beat.Duration.ToTicks() } }; for (int i = 0; i < handler.MidiEvents.Count; i++) { Console.WriteLine("i[{0}] {1}", i, handler.MidiEvents[i]); if (i < expectedEvents.Length) { Assert.AreEqual(expectedEvents[i], handler.MidiEvents[i]); } } Assert.AreEqual(expectedEvents.Length, handler.MidiEvents.Count); }
public void TestBendMultiPoint() { var tex = ":4 15.6{b(0 4 0)} 15.6"; var score = ParseTex(tex); Assert.AreEqual(1, score.Tracks.Count); Assert.AreEqual(1, score.Tracks[0].Staves[0].Bars.Count); Assert.AreEqual(1, score.Tracks[0].Staves[0].Bars[0].Voices.Count); Assert.AreEqual(2, score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats.Count); Assert.AreEqual(1, score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0].Notes.Count); Assert.AreEqual(1, score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[1].Notes.Count); var handler = new FlatMidiEventGenerator(); var generator = new MidiFileGenerator(score, handler); generator.Generate(); var info = score.Tracks[0].PlaybackInfo; var note = score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0].Notes[0]; var expectedEvents = new FlatMidiEventGenerator.MidiEvent[] { // channel init new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.VolumeCoarse, Value = 120 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.PanCoarse, Value = 64 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.ExpressionControllerCoarse, Value = 127 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.RegisteredParameterFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.RegisteredParameterCourse, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.DataEntryFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)MidiController.DataEntryCoarse, Value = 12 }, new FlatMidiEventGenerator.ProgramChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Program = (byte)info.Program }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.VolumeCoarse, Value = 120 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.PanCoarse, Value = 64 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.ExpressionControllerCoarse, Value = 127 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.RegisteredParameterFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.RegisteredParameterCourse, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.DataEntryFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)MidiController.DataEntryCoarse, Value = 12 }, new FlatMidiEventGenerator.ProgramChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Program = (byte)info.Program }, new FlatMidiEventGenerator.TimeSignatureEvent { Tick = 0, Numerator = 4, Denominator = 4 }, new FlatMidiEventGenerator.TempoEvent { Tick = 0, Tempo = 120 }, // bend effect new FlatMidiEventGenerator.BendEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Value = 64 }, // no bend new FlatMidiEventGenerator.BendEvent { Tick = 43, Track = 0, Channel = info.PrimaryChannel, Value = 65 }, new FlatMidiEventGenerator.BendEvent { Tick = 87, Track = 0, Channel = info.PrimaryChannel, Value = 66 }, new FlatMidiEventGenerator.BendEvent { Tick = 130, Track = 0, Channel = info.PrimaryChannel, Value = 67 }, new FlatMidiEventGenerator.BendEvent { Tick = 174, Track = 0, Channel = info.PrimaryChannel, Value = 68 }, new FlatMidiEventGenerator.BendEvent { Tick = 218, Track = 0, Channel = info.PrimaryChannel, Value = 69 }, new FlatMidiEventGenerator.BendEvent { Tick = 261, Track = 0, Channel = info.PrimaryChannel, Value = 70 }, new FlatMidiEventGenerator.BendEvent { Tick = 305, Track = 0, Channel = info.PrimaryChannel, Value = 71 }, new FlatMidiEventGenerator.BendEvent { Tick = 349, Track = 0, Channel = info.PrimaryChannel, Value = 72 }, new FlatMidiEventGenerator.BendEvent { Tick = 392, Track = 0, Channel = info.PrimaryChannel, Value = 73 }, new FlatMidiEventGenerator.BendEvent { Tick = 436, Track = 0, Channel = info.PrimaryChannel, Value = 74 }, new FlatMidiEventGenerator.BendEvent { Tick = 479, Track = 0, Channel = info.PrimaryChannel, Value = 75 }, // full bend new FlatMidiEventGenerator.BendEvent { Tick = 480, Track = 0, Channel = info.PrimaryChannel, Value = 75 }, // full bend new FlatMidiEventGenerator.BendEvent { Tick = 523, Track = 0, Channel = info.PrimaryChannel, Value = 74 }, new FlatMidiEventGenerator.BendEvent { Tick = 567, Track = 0, Channel = info.PrimaryChannel, Value = 73 }, new FlatMidiEventGenerator.BendEvent { Tick = 610, Track = 0, Channel = info.PrimaryChannel, Value = 72 }, new FlatMidiEventGenerator.BendEvent { Tick = 654, Track = 0, Channel = info.PrimaryChannel, Value = 71 }, new FlatMidiEventGenerator.BendEvent { Tick = 698, Track = 0, Channel = info.PrimaryChannel, Value = 70 }, new FlatMidiEventGenerator.BendEvent { Tick = 741, Track = 0, Channel = info.PrimaryChannel, Value = 69 }, new FlatMidiEventGenerator.BendEvent { Tick = 785, Track = 0, Channel = info.PrimaryChannel, Value = 68 }, new FlatMidiEventGenerator.BendEvent { Tick = 829, Track = 0, Channel = info.PrimaryChannel, Value = 67 }, new FlatMidiEventGenerator.BendEvent { Tick = 872, Track = 0, Channel = info.PrimaryChannel, Value = 66 }, new FlatMidiEventGenerator.BendEvent { Tick = 916, Track = 0, Channel = info.PrimaryChannel, Value = 65 }, new FlatMidiEventGenerator.BendEvent { Tick = 959, Track = 0, Channel = info.PrimaryChannel, Value = 64 }, // no bend // note itself new FlatMidiEventGenerator.NoteEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, DynamicValue = note.Dynamic, Key = (byte)note.RealValue, Length = note.Beat.Duration.ToTicks() }, // reset bend new FlatMidiEventGenerator.BendEvent { Tick = 960, Track = 0, Channel = info.PrimaryChannel, Value = 64 }, // finish new FlatMidiEventGenerator.NoteEvent { Tick = 960, Track = 0, Channel = info.PrimaryChannel, DynamicValue = note.Dynamic, Key = (byte)note.RealValue, Length = note.Beat.Duration.ToTicks() }, // end of track new FlatMidiEventGenerator.TrackEndEvent { Tick = 3840, Track = 0 } // 3840 = end of bar }; for (int i = 0; i < handler.MidiEvents.Count; i++) { Console.WriteLine("i[{0}] {1}", i, handler.MidiEvents[i]); if (i < expectedEvents.Length) { Assert.AreEqual(expectedEvents[i], handler.MidiEvents[i]); } } Assert.AreEqual(expectedEvents.Length, handler.MidiEvents.Count); }
public void TestGraceBeatGeneration() { var reader = new Gp7Importer(); var buffer = TestPlatform.LoadFile("TestFiles/Audio/GraceBeats.gp"); var settings = Settings.SongBook; reader.Init(ByteBuffer.FromBuffer(buffer), settings); var score = reader.ReadScore(); var handler = new FlatMidiEventGenerator(); var generator = new MidiFileGenerator(score, settings, handler); generator.Generate(); // on beat var tick = 0; var ticks = new FastList <int>(); Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0].AbsolutePlaybackStart); Assert.AreEqual(3840, score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[0].Voices[0].Beats[0].PlaybackDuration; Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[1].Voices[0].Beats[0].AbsolutePlaybackStart); Assert.AreEqual(120, score.Tracks[0].Staves[0].Bars[1].Voices[0].Beats[0].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[1].Voices[0].Beats[0].PlaybackDuration; Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[1].Voices[0].Beats[1].AbsolutePlaybackStart); Assert.AreEqual(3720, score.Tracks[0].Staves[0].Bars[1].Voices[0].Beats[1].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[1].Voices[0].Beats[1].PlaybackDuration; // before beat Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[2].Voices[0].Beats[0].AbsolutePlaybackStart); Assert.AreEqual(3720, score.Tracks[0].Staves[0].Bars[2].Voices[0].Beats[0].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[2].Voices[0].Beats[0].PlaybackDuration; Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0].AbsolutePlaybackStart); Assert.AreEqual(120, score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[0].PlaybackDuration; Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[1].AbsolutePlaybackStart); Assert.AreEqual(3840, score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[1].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[3].Voices[0].Beats[1].PlaybackDuration; // bend Assert.AreEqual(GraceType.BendGrace, score.Tracks[0].Staves[0].Bars[4].Voices[0].Beats[0].GraceType); Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[4].Voices[0].Beats[0].AbsolutePlaybackStart); Assert.AreEqual(1920, score.Tracks[0].Staves[0].Bars[4].Voices[0].Beats[0].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[4].Voices[0].Beats[0].PlaybackDuration; Assert.AreEqual(tick, score.Tracks[0].Staves[0].Bars[4].Voices[0].Beats[1].AbsolutePlaybackStart); Assert.AreEqual(1920, score.Tracks[0].Staves[0].Bars[4].Voices[0].Beats[1].PlaybackDuration); ticks.Add(tick); tick += score.Tracks[0].Staves[0].Bars[4].Voices[0].Beats[1].PlaybackDuration; var info = score.Tracks[0].PlaybackInfo; var expectedEvents = new FlatMidiEventGenerator.MidiEvent[] { // channel init new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)ControllerType.VolumeCoarse, Value = 120 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)ControllerType.PanCoarse, Value = 64 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)ControllerType.ExpressionControllerCoarse, Value = 127 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)ControllerType.RegisteredParameterFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)ControllerType.RegisteredParameterCourse, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)ControllerType.DataEntryFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Controller = (byte)ControllerType.DataEntryCoarse, Value = 12 }, new FlatMidiEventGenerator.ProgramChangeEvent { Tick = 0, Track = 0, Channel = info.PrimaryChannel, Program = (byte)info.Program }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)ControllerType.VolumeCoarse, Value = 120 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)ControllerType.PanCoarse, Value = 64 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)ControllerType.ExpressionControllerCoarse, Value = 127 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)ControllerType.RegisteredParameterFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)ControllerType.RegisteredParameterCourse, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)ControllerType.DataEntryFine, Value = 0 }, new FlatMidiEventGenerator.ControlChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Controller = (byte)ControllerType.DataEntryCoarse, Value = 12 }, new FlatMidiEventGenerator.ProgramChangeEvent { Tick = 0, Track = 0, Channel = info.SecondaryChannel, Program = (byte)info.Program }, new FlatMidiEventGenerator.TimeSignatureEvent { Tick = 0, Numerator = 4, Denominator = 4 }, new FlatMidiEventGenerator.TempoEvent { Tick = 0, Tempo = 120 }, // on beat new FlatMidiEventGenerator.BendEvent { Tick = ticks[0], Track = 0, Channel = info.PrimaryChannel, Value = 64 }, new FlatMidiEventGenerator.NoteEvent { Tick = ticks[0], Track = 0, Channel = info.PrimaryChannel, DynamicValue = DynamicValue.F, Key = (byte)67, Length = 3840 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[1], Track = 0, Channel = info.PrimaryChannel, Value = 64 }, new FlatMidiEventGenerator.NoteEvent { Tick = ticks[1], Track = 0, Channel = info.PrimaryChannel, DynamicValue = DynamicValue.F, Key = (byte)67, Length = 120 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[2], Track = 0, Channel = info.PrimaryChannel, Value = 64 }, new FlatMidiEventGenerator.NoteEvent { Tick = ticks[2], Track = 0, Channel = info.PrimaryChannel, DynamicValue = DynamicValue.F, Key = (byte)67, Length = 3720 }, // before beat new FlatMidiEventGenerator.BendEvent { Tick = ticks[3], Track = 0, Channel = info.PrimaryChannel, Value = 64 }, new FlatMidiEventGenerator.NoteEvent { Tick = ticks[3], Track = 0, Channel = info.PrimaryChannel, DynamicValue = DynamicValue.F, Key = (byte)67, Length = 3720 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[4], Track = 0, Channel = info.PrimaryChannel, Value = 64 }, new FlatMidiEventGenerator.NoteEvent { Tick = ticks[4], Track = 0, Channel = info.PrimaryChannel, DynamicValue = DynamicValue.F, Key = (byte)67, Length = 120 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[5], Track = 0, Channel = info.PrimaryChannel, Value = 64 }, new FlatMidiEventGenerator.NoteEvent { Tick = ticks[5], Track = 0, Channel = info.PrimaryChannel, DynamicValue = DynamicValue.F, Key = (byte)67, Length = 3840 }, // bend beat new FlatMidiEventGenerator.BendEvent { Tick = ticks[6], Track = 0, Channel = info.SecondaryChannel, Value = 64 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 0, Track = 0, Channel = info.SecondaryChannel, Value = 64 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 1, Track = 0, Channel = info.SecondaryChannel, Value = 65 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 2, Track = 0, Channel = info.SecondaryChannel, Value = 66 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 3, Track = 0, Channel = info.SecondaryChannel, Value = 67 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 4, Track = 0, Channel = info.SecondaryChannel, Value = 68 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 5, Track = 0, Channel = info.SecondaryChannel, Value = 69 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 6, Track = 0, Channel = info.SecondaryChannel, Value = 70 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 7, Track = 0, Channel = info.SecondaryChannel, Value = 71 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 8, Track = 0, Channel = info.SecondaryChannel, Value = 72 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 9, Track = 0, Channel = info.SecondaryChannel, Value = 73 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 10, Track = 0, Channel = info.SecondaryChannel, Value = 74 }, new FlatMidiEventGenerator.BendEvent { Tick = ticks[6] + 13 * 11 + 1, Track = 0, Channel = info.SecondaryChannel, Value = 75 }, new FlatMidiEventGenerator.NoteEvent { Tick = ticks[6], Track = 0, Channel = info.SecondaryChannel, Length = 3840, Key = 67, DynamicValue = DynamicValue.F }, // end of track new FlatMidiEventGenerator.TrackEndEvent { Tick = 19200, Track = 0 } // 3840 = end of bar }; for (int i = 0; i < handler.MidiEvents.Count; i++) { Logger.Info("Test", $"i[{i}] {handler.MidiEvents[i]}"); if (i < expectedEvents.Length) { Assert.AreEqual(expectedEvents[i], handler.MidiEvents[i]); } } Assert.AreEqual(expectedEvents.Length, handler.MidiEvents.Count); }