public static void PlayPiano() { Sequencer a = new Sequencer(); using (OutputDevice outDevice = new OutputDevice(0)) { for (int i = 60; i < 100; i++) { ChannelMessageBuilder builder = new ChannelMessageBuilder(); builder.Command = ChannelCommand.NoteOn; builder.MidiChannel = 14; builder.Data1 = i; builder.Data2 = i - 20; builder.Build(); outDevice.Send(builder.Result); Thread.Sleep(500); builder.Command = ChannelCommand.NoteOff; builder.Data2 = 0; builder.Build(); outDevice.Send(builder.Result); } } }
public void AllSoundOff() { ArrayList stoppedMessages = new ArrayList(); for (int c = 0; c <= ChannelMessage.MidiChannelMaxValue; c++) { for (int n = 0; n <= ShortMessage.DataMaxValue; n++) { if (noteOnMessage[c, n] != null) { builder.MidiChannel = c; builder.Command = ChannelCommand.NoteOff; builder.Data1 = noteOnMessage[c, n].Data1; builder.Build(); stoppedMessages.Add(builder.Result); noteOnMessage[c, n] = null; } } if (holdPedal1Message[c]) { builder.MidiChannel = c; builder.Command = ChannelCommand.Controller; builder.Data1 = (int)ControllerType.HoldPedal1; builder.Build(); stoppedMessages.Add(builder.Result); holdPedal1Message[c] = false; } if (holdPedal2Message[c]) { builder.MidiChannel = c; builder.Command = ChannelCommand.Controller; builder.Data1 = (int)ControllerType.HoldPedal2; builder.Build(); stoppedMessages.Add(builder.Result); holdPedal2Message[c] = false; } if (sustenutoMessage[c]) { builder.MidiChannel = c; builder.Command = ChannelCommand.Controller; builder.Data1 = (int)ControllerType.SustenutoPedal; builder.Build(); stoppedMessages.Add(builder.Result); sustenutoMessage[c] = false; } } OnStopped(new StoppedEventArgs(stoppedMessages)); }
private void ParseChannelMessage() { if (trackIndex >= trackData.Length) { throw new MidiFileException("End of track unexpectedly reached."); } cmBuilder.Command = ChannelMessage.UnpackCommand(status); cmBuilder.MidiChannel = ChannelMessage.UnpackMidiChannel(status); cmBuilder.Data1 = trackData[trackIndex]; trackIndex++; if (ChannelMessage.DataBytesPerType(cmBuilder.Command) == 2) { if (trackIndex >= trackData.Length) { throw new MidiFileException("End of track unexpectedly reached."); } cmBuilder.Data2 = trackData[trackIndex]; trackIndex++; } cmBuilder.Build(); newTrack.Insert(ticks, cmBuilder.Result); runningStatus = status; }
public void ReleaseNote(int noteNumber) { var b = new ChannelMessageBuilder(); b.Command = ChannelCommand.NoteOff; b.Data1 = MIDIUtils.ConvertNoteNumberToMIDINoteNumber(noteNumber); b.MidiChannel = 0; b.Build(); if (ChannelMessageReceived != null) ChannelMessageReceived(this, new ChannelMessageEventArgs(b.Result)); }
private static ChannelMessage GetChannelMessage(ChannelCommand command, int channel, int data1, int data2) { ChannelMessageBuilder on = new ChannelMessageBuilder(); on.MidiChannel = channel; on.Command = command; on.Data1 = data1; on.Data2 = data2; on.Build(); return on.Result; }
private static IMidiMessage Convert(Event e, Track track) { if (e is NoteEvent) { NoteEvent note = (NoteEvent)e; if (note.Type == NoteEvent.EventType.NoteOff) { ChannelMessageBuilder b = new ChannelMessageBuilder(); b.MidiChannel = note.Channel; b.Command = ChannelCommand.NoteOff; b.Data1 = ChannelNoteToMidiPitch(note.Pitch); b.Data2 = ChannelVelocityToMidiVolume(note.Velocity); b.Build(); return b.Result; } else { ChannelMessageBuilder b = new ChannelMessageBuilder(); b.MidiChannel = note.Channel; b.Command = ChannelCommand.NoteOn; b.Data1 = ChannelNoteToMidiPitch(note.Pitch); b.Data2 = ChannelVelocityToMidiVolume(note.Velocity); b.Build(); return b.Result; } } else if (e is TempoEvent) { TempoEvent tempoEvent = (TempoEvent)e; TempoChangeBuilder builder = new TempoChangeBuilder(); // convert BPM to microseconds builder.Tempo = 60000000 / tempoEvent.TempoBpm; builder.Build(); return builder.Result; } else if (e is TimeSignatureEvent) { TimeSignatureEvent timeSignatureEvent = (TimeSignatureEvent)e; TimeSignatureBuilder builder = new TimeSignatureBuilder(); builder.Numerator = (byte)timeSignatureEvent.BeatsPerBar; builder.Denominator = (byte)timeSignatureEvent.BeatValue; builder.ClocksPerMetronomeClick = 24; builder.ThirtySecondNotesPerQuarterNote = 8; builder.Build(); return builder.Result; } else { Debug.Fail("unknown event type " + e.GetType().Name); return null; } }
public void Send(int midiChannel, int controller, byte value) { if (this.outputDevice == null) return; var builder = new ChannelMessageBuilder(); builder.Command = ChannelCommand.Controller; builder.Data1 = controller; builder.Data2 = value; builder.MidiChannel = midiChannel; builder.Build(); this.outputDevice.Send(builder.Result); }
private void ParseChannelMessage() { if (trackIndex >= trackData.Length) { //throw new MidiFileException("End of track unexpectedly reached."); Console.Write("\nERROR: End of track unexpectedly reached (TrackReader.cs ParseChannelMessage)"); return; } cmBuilder.Command = ChannelMessage.UnpackCommand(status); cmBuilder.MidiChannel = ChannelMessage.UnpackMidiChannel(status); cmBuilder.Data1 = trackData[trackIndex]; // PROGRAM CHANGE if (cmBuilder.Command == ChannelCommand.ProgramChange) { newTrack.ProgramChange = cmBuilder.Data1; newTrack.MidiChannel = cmBuilder.MidiChannel; } trackIndex++; if (ChannelMessage.DataBytesPerType(cmBuilder.Command) == 2) { if (trackIndex >= trackData.Length) { //throw new MidiFileException("End of track unexpectedly reached."); Console.Write("\nERROR: End of track unexpectedly reached (TrackReader.cs ParseChannelMessage)"); return; } // FAB : 07/08/2014 if (trackData[trackIndex] <= 127) { cmBuilder.Data2 = trackData[trackIndex]; } else { cmBuilder.Data2 = 127; } if (cmBuilder.Data1 == 0x07) { // Volume de la piste newTrack.Volume = cmBuilder.Data2; } else if (cmBuilder.Data1 == 0x5B) { // Reverb 91 // FAB 2017 newTrack.Reverb = cmBuilder.Data2; } else if (cmBuilder.Data1 == 0x0A) { // pan 10 // FAB 2017 newTrack.Pan = cmBuilder.Data2; } // Collecte des notes if (cmBuilder.Command == ChannelCommand.NoteOn) { newTrack.ContainsNotes = true; newTrack.Visible = true; // Data1 = Note number // Data2 = Velocity if (ticks >= 0 && cmBuilder.Data2 > 0) { // FAB : // Add a MidiNote to this track. This is called for each NoteOn event */ newTrack.MidiChannel = cmBuilder.MidiChannel; MidiNote note = new MidiNote(ticks, newTrack.MidiChannel, cmBuilder.Data1, 0, cmBuilder.Data2, false); newTrack.Notes.Add(note); } else { // FAB if (newTrack.Notes.Count > 0) { newTrack.MidiChannel = cmBuilder.MidiChannel; NoteOff(newTrack.MidiChannel, cmBuilder.Data1, ticks); } } } else if (ticks >= 0 && cmBuilder.Command == ChannelCommand.NoteOff) { // FAB newTrack.ContainsNotes = true; newTrack.Visible = true; newTrack.MidiChannel = cmBuilder.MidiChannel; NoteOff(newTrack.MidiChannel, cmBuilder.Data1, ticks); } trackIndex++; } cmBuilder.Build(); newTrack.Insert(ticks, cmBuilder.Result); runningStatus = status; }
private void play_chord(Keys k, int t) { int n1 = (int)Mozart.Component(k, 1) + 57; int n2 = (int)Mozart.Component(k, 3) + 57; int n3 = (int)Mozart.Component(k, 5) + 57; while (n1 < low) { n1 += 12; } while (n2 < n1) { n2 += 12; } while (n3 < n2) { n3 += 12; } ChannelMessageBuilder builder = new ChannelMessageBuilder(); builder.Command = ChannelCommand.NoteOn; builder.MidiChannel = 0; builder.Data1 = n1; builder.Data2 = 127; builder.Build(); outDevice.Send(builder.Result); builder.Command = ChannelCommand.NoteOn; builder.MidiChannel = 0; builder.Data1 = n2; builder.Data2 = 127; builder.Build(); outDevice.Send(builder.Result); builder.Command = ChannelCommand.NoteOn; builder.MidiChannel = 0; builder.Data1 = n3; builder.Data2 = 127; builder.Build(); outDevice.Send(builder.Result); System.Threading.Thread.Sleep(t); builder.Command = ChannelCommand.NoteOff; builder.MidiChannel = 0; builder.Data1 = n1; builder.Data2 = 127; builder.Build(); outDevice.Send(builder.Result); builder.Command = ChannelCommand.NoteOff; builder.MidiChannel = 0; builder.Data1 = n2; builder.Data2 = 127; builder.Build(); outDevice.Send(builder.Result); builder.Command = ChannelCommand.NoteOff; builder.MidiChannel = 0; builder.Data1 = n3; builder.Data2 = 127; builder.Build(); outDevice.Send(builder.Result); }
private void ZapalMidi(Panel panel, ChannelCommand cm) { ChannelMessageBuilder cmb = new ChannelMessageBuilder(); cmb.Command = cm; cmb.MidiChannel = 3; cmb.Data1 = Convert.ToInt32(panel.Tag); cmb.Data2 = 127; cmb.Build(); outDevice1.Send(cmb.Result); }
private static int ProgramChange(Track t, int tick, int p, int channel, ChannelEvent ce) { if (p != ce.Instrument) { Console.Out.WriteLine("PC " + ce.Instrument); ChannelMessageBuilder pc = new ChannelMessageBuilder(); pc.MidiChannel = channel; pc.Command = ChannelCommand.ProgramChange; pc.Data1 = 0;// 79 + ce.Instrument; pc.Build(); t.Insert(tick, pc.Result); p = ce.Instrument; } return p; }
private static void NoteOn(int tick, TrackInfo ti, ChannelEvent ce) { bool eventHasVolume = ce.Volume != -1; int noteVolume = eventHasVolume ? ce.Volume : 64; // TODO: read from sample settings var pitch = CellConverter.ChannelNoteToMidiPitch(ce.Note); if (ti.NoteMapper != null) { pitch = ti.NoteMapper(ce); } //Console.Out.WriteLine("{0:00} On " + note, tick); ChannelMessageBuilder on = new ChannelMessageBuilder(); on.MidiChannel = ti.Channel; on.Command = ChannelCommand.NoteOn; on.Data1 = pitch; on.Data2 = Math.Min(127, 2 * noteVolume); on.Build(); ti.Track.Insert(tick, on.Result); ti.LastPitch = pitch; ti.LastVolume = noteVolume; }
private static void NoteOff(int tick, TrackInfo ti) { //Console.Out.WriteLine("{0:00} Off " + note, tick); ChannelMessageBuilder off = new ChannelMessageBuilder(); off.MidiChannel = ti.Channel; off.Command = ChannelCommand.NoteOff; off.Data1 = ti.LastPitch; off.Data2 = ti.LastVolume; off.Build(); ti.Track.Insert(tick, off.Result); ti.LastPitch = -1; ti.LastVolume = -1; }
static void Main(string[] args) { bool outputMidiVelocity = false; //var filename = "01-v-drac.s3m"; //S3MFile f = S3MFile.Parse(filename); //var tempo = 60000000 / (f.Header.InitialTempo); //byte numerator = 4; //byte denominator = 4; //var speed = 3; //var skip = 0; var filename = "02-v-bewm.s3m"; S3MFile f = S3MFile.Parse(filename); var tempo = 60000000 / (f.Header.InitialTempo); byte numerator = 4; byte denominator = 4; var speed = 3; var skip = 0; outputMidiVelocity = true; /* var filename = "V-OPTION.S3M"; S3MFile f = S3MFile.Parse(filename); var tempo = 60000000 / (f.Header.InitialTempo); byte numerator = 6; byte denominator = 8; var speed = 3; var skip = 4; */ /* var filename = "V-FALCON.S3M"; S3MFile f = S3MFile.Parse(filename); var tempo = 60000000 / (1 * f.Header.InitialTempo); byte numerator = 4; byte denominator = 4; var speed = 3; var skip = 0; */ /* var filename = "V-CONTRA.IT"; S3MFile f = S3MFile.Parse(filename); var tempo = 60000000 / (1 * f.Header.InitialTempo); byte numerator = 4; byte denominator = 4; var speed = 3; var skip = 0; * */ /* var filename = "V-BLAST.S3M"; S3MFile f = S3MFile.Parse(filename); var tempo = 60000000 / (1 * f.Header.InitialTempo); byte numerator = 4; byte denominator = 4; var speed = 3; var skip = 0;*/ Sequence s = new Sequence(); Track t1 = new Track(); Track t2 = new Track(); Track t3 = new Track(); Track drums = new Track(); Track kick = new Track(); Track timeTrack = new Track(); s.Add(timeTrack); s.Add(t1); s.Add(t2); s.Add(t3); //s.Add(drums); //s.Add(kick); var drumPC = new ChannelMessageBuilder(); drumPC.MidiChannel = 09; drumPC.Command = ChannelCommand.ProgramChange; drumPC.Data1 = 0;// 79 + ce.Instrument; drumPC.Build(); drums.Insert(0, drumPC.Result); kick.Insert(0, drumPC.Result); TimeSignatureBuilder tsb = new TimeSignatureBuilder(); tsb.Numerator = numerator; tsb.Denominator = denominator; tsb.ClocksPerMetronomeClick = 24; tsb.ThirtySecondNotesPerQuarterNote = 8; tsb.Build(); timeTrack.Insert(0, tsb.Result); TempoChangeBuilder tcb = new TempoChangeBuilder(); tcb.Tempo = tempo; tcb.Build(); timeTrack.Insert(0, tcb.Result); var outputPatterns = new int[] { 5, 6, 7}; //var c1 = (from p in f.OrderedPatterns // where patterns.Contains(p.PatternNumber) // select p) // .SelectMany(p => p.Channels) // .Where(c => c.ChannelNumber == 1) // .SelectMany(ce => ce.ChannelEvents); //var c2 = (from p in f.OrderedPatterns // where patterns.Contains(p.PatternNumber) // select p) // .SelectMany(p => p.Channels) // .Where(c => c.ChannelNumber == 2) // .SelectMany(ce => ce.ChannelEvents); //var c3 = (from p in f.OrderedPatterns // where patterns.Contains(p.PatternNumber) // select p) // .SelectMany(p => p.Channels) // .Where(c => c.ChannelNumber == 3) // .SelectMany(ce => ce.ChannelEvents); var patterns = from p in f.OrderedPatterns.Skip(skip) /*where outputPatterns.Contains(p.PatternNumber) */select p; //.SelectMany(p => p.Rows); Dictionary<int, TrackInfo> tracks = new Dictionary<int, TrackInfo>(); tracks.Add(1, new TrackInfo(t1)); tracks[1].Channel = 0; tracks.Add(2, new TrackInfo(t2)); tracks[2].Channel = 1; tracks.Add(3, new TrackInfo(t3)); tracks[3].Channel = 2; var di = new TrackInfo(drums); di.Channel = 9; var mapper = new Func<ChannelEvent, int>(ce => { switch (ce.Instrument) { case 6: return 42; case 8: return 35; case 9: return 38; case 10: return 47; default: Debug.Fail(ce.Instrument.ToString()); return 0; } }); di.NoteMapper = mapper; var kickInfo = new TrackInfo(kick); kickInfo.Channel = 9; kickInfo.NoteMapper = mapper; tracks.Add(4, di); tracks.Add(5, kickInfo); var tick = 0; foreach (var pattern in patterns) { bool breakPattern = false; foreach (var row in pattern.Rows) { //if ((row.RowNumber-1) % 16 == 0) //{ // drums.Insert(tick, kickOn); // drums.Insert(tick + speed, kickOff); //} foreach (var ce in row.ChannelEvents) { if (ce == null) { //Console.Out.WriteLine("skip"); continue; } if (ce.Command == 3) { var modulo = row.RowNumber % 32; if (modulo != 0) { // sad to say, not sure why mod 8 but divide by 16 works var m8 = row.RowNumber % 8; if (m8 == 0) { var restore = tsb.Result; tsb.Numerator = (byte)(row.RowNumber / 16); tsb.Build(); var change = tsb.Result; timeTrack.Insert(tick, change); timeTrack.Insert(tick + 3, restore); } } //Debugger.Break(); // pattern break // figure out the time signature of the pattern up to this point // then go back and insert a time signature change message at the beginning // of the pattern // and another one at the end to revert //var restore = tsb.Result; //tsb.Numerator = 2; //tsb.Build(); //var change = tsb.Result; //timeTrack.Insert(rowStartTick, change); //timeTrack.Insert(tick + 3, restore); breakPattern = true; } if (!tracks.ContainsKey(ce.ChannelNumber)) continue; TrackInfo ti = tracks[ce.ChannelNumber]; if (ce.Note == -1 ) { // skip } else if( ce.Note == 0xFF) { // re-use current note, but change instrument //Console.Out.WriteLine("skip"); } else if (ce.Note == 0xFE) //off { if (ti.LastPitch != -1) { NoteOff(tick, ti); } } else { //if (ce.Volume != -1 && ce.Volume < 32) continue; if (ti.LastPitch != -1) { NoteOff(tick, ti); } //p = ProgramChange(ti.Track, tick, p, ce); var delay = 0; if (ce.Command == 19) { if (208 <= ce.Data && ce.Data <= 214) // HACK: 214 is a guess at the top range of SD commands { delay = ce.Data - 208; Debug.Assert(delay >= 0); } } NoteOn(tick + delay, ti, ce); } } tick += speed; if (breakPattern) { break; } } } foreach (var pair in tracks) { if (pair.Value.LastPitch != -1) { NoteOff(tick, pair.Value); } } foreach (MidiEvent m in drums.Iterator().Take(5)) { if (m.MidiMessage is ChannelMessage) { ChannelMessage cm = (ChannelMessage)m.MidiMessage; Console.Out.WriteLine("{0} {1}", m.AbsoluteTicks, cm.Command); } } s.Save(Path.ChangeExtension(filename, ".mid")); /* var tick = 0; var speed = 3; var lastNote = -1; var p = -1; foreach (var ce in c1) { if (ce == null || ce.Note == -1 || ce.Note == 0xFF) { tick += speed; Console.Out.WriteLine("skip"); continue; } else if (ce.Note == 0xFE) //off { lastNote = NoteOff(t, tick, lastNote); } else { if (lastNote != -1) { lastNote = NoteOff(t, tick, lastNote); } p = ProgramChange(t, tick, p, ce); var delay = 0; if (ce.Command == 19) { if (208 <= ce.Data && ce.Data <= 214) // HACK: 214 is a guess at the top range of SD commands { delay = ce.Data - 208; Debug.Assert(delay >= 0); } } lastNote = NoteOn(t, tick + delay, ce.Note); } tick += speed; } lastNote = NoteOff(t, tick, lastNote); * * */ }
/// <summary> /// Play the notes from a flashcard through the output device. /// </summary> /// <param name="f"></param> private void PlayFlashcard(Flashcard f) { ChannelMessageBuilder cbm = new ChannelMessageBuilder(); cbm.Command = ChannelCommand.NoteOn; cbm.Data2 = 75; cbm.MidiChannel = 0; cbm.Build(); cbm.Command = ChannelCommand.NoteOff; var onMessages = new ChannelMessage[f.StaffNotes.Length]; var offMessages = new ChannelMessage[f.StaffNotes.Length]; for (var i = 0; i < f.StaffNotes.Length; i++) { cbm.Data1 = f.StaffNotes[i].NoteRepresentation.Note.MIDINumber; cbm.Command = ChannelCommand.NoteOn; cbm.Build(); onMessages[i] = cbm.Result; cbm.Command = ChannelCommand.NoteOff; cbm.Build(); offMessages[i] = cbm.Result; } var t = new Timer(500) { AutoReset = false }; t.Elapsed += (s, a) => Array.ForEach(offMessages, m => _outputDevice.Send(m)); Array.ForEach(onMessages, m => _outputDevice.Send(m)); t.Start(); }
protected List<ChannelMessage> GetChannelMessages(ChannelCommand noteOnOff) { List<ChannelMessage> messages = new List<ChannelMessage>(); ChannelMessageBuilder builder = new ChannelMessageBuilder(); builder.MidiChannel = this.Channel; //foreach(MidiControl midiControl in this.MidiControls) //{ // messages.AddRange(midiControl.ChannelMessages); //} builder.Command = noteOnOff; foreach(NoteMessage midiNote in _notes) { builder.Data1 = midiNote.Pitch; builder.Data2 = midiNote.Velocity; builder.Build(); messages.Add(builder.Result); } return messages; }