public static uint CalcIndex(byte note, byte channel) => ((uint)channel << 7) | note; // equivelent to channel * 128 + note public void MatchNoteEvents() { // Handle note on/off event matching, as well as converting vel 0 noteon's to note off events. if (state.eventElement is NoteOnEvent noteOn) { uint key = CalcIndex(noteOn.note, noteOn.Channel); if (noteOn.velocity == 0 && notesActive[key].Count > 0) { NoteOffEvent off = noteOn.ToOffEvent(); NoteOnEvent on = notesActive[key].Pop(); on.NoteOff = off; state.eventElement = off; } else { notesActive[key].Push(noteOn); } } else if (state.eventElement is NoteOffEvent noteOff) { uint key = CalcIndex(noteOff.note, noteOff.Channel); NoteOnEvent on = notesActive[key].Pop(); on.NoteOff = noteOff; } }
void LoadMidiFile(string fileName) { MidiFile mf = new MidiFile(fileName); midiFile = mf; long highestTick = -1; bpm = 120; int tempo_count = 0; beats.Clear(); for (int i = 0; i < mf.Events.Tracks; i++) { var channel = mf.Events[i]; foreach (var eve in channel) { highestTick = (eve.AbsoluteTime > highestTick) ? eve.AbsoluteTime : highestTick; if (eve.CommandCode == MidiCommandCode.MetaEvent) { //Debug.Log(eve.Channel+":"+eve); if (eve is TempoEvent) { tempo_count++; if (tempo_count <= 1) { bpm = (60000000 / ((TempoEvent)eve).MicrosecondsPerQuarterNote); // calculate ticks per second! ticksPerSecond = bpm * mf.DeltaTicksPerQuarterNote / 60f; } else { Debug.LogError("BPM has changed twice!"); } } } else if (eve.CommandCode == MidiCommandCode.NoteOn) { NoteOnEvent noteOnEvent = eve as NoteOnEvent; Beat beat = new Beat(); beat._event = noteOnEvent; beat.Time = (int)noteOnEvent.AbsoluteTime; beat.trackIndex = i; beat.estimatedTime = beat.Time / ticksPerSecond; beats.Add(beat); } } } musicLength = highestTick / ticksPerSecond; Debug.Log(string.Format("music length = {0}, bpm = {1}", musicLength, bpm)); beats.Sort((a, b) => a._event.AbsoluteTime.CompareTo(b._event.AbsoluteTime)); SetBeatIndexes(); Debug.Log(string.Format("beat count = {0}, last beat time = {1}, last beat = {2}", beats.Count, beats[beats.Count - 1]._event.AbsoluteTime / ticksPerSecond, beats[beats.Count - 1]._event)); }
private void AddNote(byte Key, uint Duration, byte Velocity, byte Channel = 0) { var onEvent = new EventData(); onEvent.EventType = EventTypeList.NoteOn; var on = new NoteOnEvent(); on.Channel = Channel; on.Key = (byte)(Key + Offset); on.Velocity = Velocity; onEvent.Event = on; onEvent.DeltaTime = 0; Events.Add(onEvent); var offEvent = new EventData(); offEvent.EventType = EventTypeList.NoteOff; var off = new NoteOffEvent(); off.Channel = Channel; off.Key = (byte)(Key + Offset); off.Velocity = Velocity; offEvent.Event = off; offEvent.DeltaTime = Duration; Events.Add(offEvent); }
public FaderPort() { _inputDevice = InputDevice.GetByName("FaderPort"); _outputDevice = OutputDevice.GetByName("FaderPort"); if (_inputDevice == null) { throw new InvalidOperationException("Unable to connect to FaderPort input device."); } if (_outputDevice == null) { throw new InvalidOperationException("Unable to connect to FaderPort output device."); } _inputDevice.EventReceived += OnInputEvent; _inputDevice.StartEventsListening(); _outputDevice.PrepareForEventsSending(); var nativeEvent = new NoteOnEvent((SevenBitNumber)0, (SevenBitNumber)0x64) { Channel = (FourBitNumber)1 }; Console.WriteLine("Switching FaderPort to native mode."); _outputDevice.SendEvent(nativeEvent); ClearAllLights(); _cts = new CancellationTokenSource(); _blinkerThread = new Thread(BlinkerMain); _blinkerThread.Start(); }
public int getAverageVelocity() { int velocitySum = 0; int velocityCount = 0; for (int track = 0; track < m_data.Tracks; track++) { foreach (MidiEvent e in m_data[track]) { TimeSignatureEvent t; if (e.CommandCode == MidiCommandCode.NoteOn) { NoteOnEvent n = (NoteOnEvent)e; if (n.OffEvent != null) { ++velocityCount; velocitySum += n.Velocity; // It is an event! } } } } return((int)(velocitySum / velocityCount)); }
/// <summary> /// Play a MIDI note inside Warframe. /// </summary> /// <param name="note"> The note to be played.</param> /// <param name="enableVibrato"> Should we use vibrato to play unplayable notes?.</param> /// <param name="transposeNotes"> Should we transpose unplayable notes?.</param> public static void PlayNote(NoteOnEvent note, bool enableVibrato, bool transposeNotes) { var hWnd = GetForegroundWindow(); if (warframeWindow.Equals(IntPtr.Zero) || !hWnd.Equals(warframeWindow)) { return; } var noteId = (int)note.NoteNumber; if (!shawzinNotes.ContainsKey(noteId)) { if (transposeNotes) { if (noteId < shawzinNotes.Keys.First()) { noteId = shawzinNotes.Keys.First() + noteId % 12; } else if (noteId > shawzinNotes.Keys.Last()) { noteId = shawzinNotes.Keys.Last() - 15 + noteId % 12; } } else { return; } } var shawzinNote = shawzinNotes[noteId]; PlayNote(noteId, enableVibrato, transposeNotes); }
// Token: 0x06002A62 RID: 10850 RVA: 0x00137FB8 File Offset: 0x001361B8 private static void smethod_4(IList <MidiEvent> ilist_0) { foreach (MidiEvent midiEvent in ilist_0) { NoteOnEvent noteOnEvent = midiEvent as NoteOnEvent; if (noteOnEvent != null) { Console.WriteLine(string.Concat(new object[] { "Note: ", noteOnEvent.NoteNumber, ", Pos: ", noteOnEvent.AbsoluteTime, ", Vel: ", noteOnEvent.Velocity, ", Channel: ", noteOnEvent.Channel, ", Off pos: ", noteOnEvent.OffEvent.AbsoluteTime })); } TextEvent textEvent = midiEvent as TextEvent; if (textEvent != null) { Console.WriteLine(textEvent.Text + " " + textEvent.AbsoluteTime); } } }
private static TrackChunk AddEventsOfNote( TrackChunk chunkito, Note n, byte channel) { var noteOn = new NoteOnEvent() { Channel = new FourBitNumber(channel), DeltaTime = n.StartSinceBeginningOfSongInTicks, NoteNumber = new SevenBitNumber(n.Pitch), Velocity = new SevenBitNumber(n.Volume) }; chunkito.Events.Add(noteOn); var noteOff = new NoteOffEvent() { Channel = new FourBitNumber(channel), DeltaTime = n.EndSinceBeginningOfSongInTicks, NoteNumber = new SevenBitNumber(n.Pitch) }; chunkito.Events.Add(noteOff); foreach (var pb in n.PitchBending) { var p = new PitchBendEvent() { Channel = new FourBitNumber(channel), DeltaTime = pb.TicksSinceBeginningOfSong, PitchValue = pb.Pitch }; chunkito.Events.Add(p); } return(chunkito); }
private void LoadScore() { var strictMode = false; mf = new MidiFile(MidiScoreFile, strictMode); ppq = mf.DeltaTicksPerQuarterNote; ScoreLoaded = true; tempo = PlayerCtrl.Control.tempo; //Find first note var track = mf.Events[0]; // MIDI Files for VRMIN should only have one track int eventIdx = 0; NoteOnEvent firstNoteEvent = null; foreach (var midiEvent in track) { if (MidiEvent.IsNoteOn(midiEvent)) { firstNoteEvent = (NoteOnEvent)midiEvent; break; } } if (firstNoteEvent != null) { CurrentNote = new NoteMessage(-1, firstNoteEvent.NoteNumber, PlayerCtrl.Control.startDelay); } else { throw new System.ArgumentException("No Data in loaded Score"); } }
public void SendEvent_MidiEvent() { var midiEvent = new NoteOnEvent((SevenBitNumber)45, (SevenBitNumber)89) { Channel = (FourBitNumber)6 }; using (var outputDevice = OutputDevice.GetByName(MidiDevicesNames.DeviceA)) { MidiEvent eventSent = null; outputDevice.EventSent += (_, e) => eventSent = e.Event; using (var inputDevice = InputDevice.GetByName(MidiDevicesNames.DeviceA)) { MidiEvent eventReceived = null; inputDevice.EventReceived += (_, e) => eventReceived = e.Event; inputDevice.StartEventsListening(); outputDevice.PrepareForEventsSending(); outputDevice.SendEvent(new NoteOnEvent((SevenBitNumber)45, (SevenBitNumber)89) { Channel = (FourBitNumber)6 }); var timeout = TimeSpan.FromMilliseconds(15); var isEventSentReceived = SpinWait.SpinUntil(() => eventSent != null && eventReceived != null, timeout); Assert.IsTrue(isEventSentReceived, "Event either not sent ot not received."); MidiAsserts.AreEventsEqual(midiEvent, eventSent, false, "Sent event is invalid."); MidiAsserts.AreEventsEqual(eventSent, eventReceived, false, "Received event is invalid."); } } }
/// <summary> /// Finds the first pair of same-note on and off events /// in an array of MIDI events starting from <paramref name="start_index"/> /// </summary> /// <param name="events"></param> /// <param name="start_index"></param> /// <param name="on_event"></param> /// <param name="off_event"></param> /// <param name="time_span_in_pulses"></param> /// <param name="max_steps"></param> /// <returns></returns> public static bool FindNoteOnOff( MidiEvent[] events, int start_index, out NoteOnEvent on_event, out NoteOffEvent off_event, out int time_span_in_pulses, int max_steps) { on_event = null; off_event = null; time_span_in_pulses = 0; for (int i = 0; i < max_steps; i++) { int index = start_index + i; MidiEvent @event = events[index]; if (on_event != null) { time_span_in_pulses += @event.delta_time; if (@event is NoteOffEvent) { off_event = @event as NoteOffEvent; if (off_event.note_number == on_event.note_number) { return(true); } } } if (@event is NoteOnEvent) { on_event = on_event ?? @event as NoteOnEvent; } } return(false); }
public void DebugTrack() { int itrck = 0; foreach (IList <MidiEvent> track in midifile.Events) { itrck++; foreach (MidiEvent midievent in track) { string info = string.Format("Track:{0} Channel:{1,2:00} Command:{2} AbsoluteTime:{3:0000000} ", itrck, midievent.Channel, midievent.CommandCode, midievent.AbsoluteTime); if (midievent.CommandCode == MidiCommandCode.NoteOn) { NoteOnEvent noteon = (NoteOnEvent)midievent; if (noteon.OffEvent == null) { info += string.Format(" OffEvent null"); } else { info += string.Format(" OffEvent.DeltaTimeChannel:{0:0000.00} ", noteon.OffEvent.DeltaTime); } } Debug.Log(info); } } }
public void DebugMidiSorted() { foreach (TrackMidiEvent midievent in MidiSorted) { string info = string.Format("Track:{0} Channel:{1,2:00} Command:{2} AbsoluteTime:{3:0000000} ", midievent.IndexTrack, midievent.Event.Channel, midievent.Event.CommandCode, midievent.Event.AbsoluteTime); switch (midievent.Event.CommandCode) { case MidiCommandCode.NoteOn: NoteOnEvent noteon = (NoteOnEvent)midievent.Event; if (noteon.Velocity == 0) { info += string.Format(" Velocity 0"); } if (noteon.OffEvent == null) { info += string.Format(" OffEvent null"); } else { info += string.Format(" OffEvent.DeltaTimeChannel:{0:0000.00} ", noteon.OffEvent.DeltaTime); } break; } Debug.Log(info); } }
public void NoteOnIsDeepClone() { var ev = new NoteOnEvent(0, 1, 30, 100, 15); var clone = (NoteOnEvent)ev.Clone(); Assert.That(clone.OffEvent, Is.Not.SameAs(ev.OffEvent)); }
/// <summary> /// Play a MIDI note inside Warframe. /// </summary> /// <param name="note"> The note to be played.</param> /// <param name="enableVibrato"> Should we use vibrato to play unplayable notes?.</param> /// <param name="transposeNotes"> Should we transpose unplayable notes?.</param> public static bool PlayNote(NoteOnEvent note, bool enableVibrato, bool transposeNotes) { //var hWnd = GetForegroundWindow(); //if (warframeWindow.Equals(IntPtr.Zero) || !hWnd.Equals(warframeWindow)) return false; if (!IsWindowFocused("Warframe")) { return(false); } var noteId = (int)note.NoteNumber; if (!shawzinNotes.ContainsKey(noteId)) { if (transposeNotes) { if (noteId < shawzinNotes.Keys.First()) { noteId = shawzinNotes.Keys.First() + noteId % 12; } else if (noteId > shawzinNotes.Keys.Last()) { noteId = shawzinNotes.Keys.Last() - 15 + noteId % 12; } } else { return(false); } } PlayNote(noteId, enableVibrato, transposeNotes); return(true); }
public void TestAddNamedTrackCopyWithOwnEnd() { var manualMidi = new MidiEventCollection(1, 200); var noteEvent = new NoteOnEvent(0, 1, 1, 1, 1); const string trackName = "name"; var trackNameEvent = new TextEvent(trackName, MetaEventType.SequenceTrackName, 0); var endTrackEvent = new MetaEvent(MetaEventType.EndTrack, 0, 90); var track = manualMidi.AddTrack(); track.Add(trackNameEvent); track.Add(noteEvent); track.Add(noteEvent.OffEvent); track.Add(endTrackEvent); var extensionMidi = new MidiEventCollection(1, 200); var events = new MidiEvent[] { noteEvent, noteEvent.OffEvent, endTrackEvent }; extensionMidi.AddNamedTrackCopy(trackName, events); MidiAssert.Equal(manualMidi, extensionMidi); // Assert they aren't the same objects var manualTrack = manualMidi[0]; var extensionTrack = extensionMidi[0]; for (var e = 0; e < manualTrack.Count; e++) { Assert.That(extensionTrack[e], Is.Not.SameAs(manualTrack[e])); } // Verify the NoteOnEvent.OffEvent link Assert.AreEqual(extensionMidi[0][2], ((NoteOnEvent)extensionMidi[0][1]).OffEvent); }
private void OnTimerTick(object sender, EventArgs e) //once over 10ms after play is clicked { try { timePassed += m_timeInterval; //count up the time DrawTimeIndicatorCanvas(); //redraw the time indicator line pointInTime = (timePassed * xScale); if (timePassed == NoteOnList[listCount].AbsoluteTime) { noteOn = new NoteOnEvent(NoteOnList[listCount].AbsoluteTime, NoteOnList[listCount].Channel, NoteOnList[listCount].NoteNumber, NoteOnList[listCount].Velocity, NoteOnList[listCount].NoteLength); PlayNote(noteOn.NoteNumber, noteOn.NoteLength); // pointInTime = (noteOn.AbsoluteTime * xScale) + 168 ; // (double)startTime * xScale) listCount++; } } catch (ArgumentOutOfRangeException) { listCount = 0; } catch (NullReferenceException) { m_timer.Stop(); outputDevice.Close(); } }
GameObject UpdateNewPlatformPositionAndScale(GameObject platform, NoteOnEvent note) { platform.transform.localScale = new Vector3(note.NoteLength * (note.NoteLength < 50 ? 0.3f : 0.03f), platform.transform.localScale.y); // Check if it is not too far in Y, then X if (Math.Abs(platform.transform.position.y - lastPosition.y) > MaxJumpYGain) { platform.transform.position = new Vector3(platform.transform.position.x, lastPosition.y + (lastPosition.y > platform.transform.position.y ? -MaxJumpYGain : MaxJumpYGain)); } if (Math.Abs(platform.transform.position.x - lastPosition.x) > MaxJumpXGain) { platform.transform.position = new Vector3(lastPosition.x + MaxJumpXGain, platform.transform.position.y); } // Adapt material according to note var comp = platform.gameObject.GetComponentInChildren <MeshRenderer>(); comp.material = GetMaterialOfNote(note.NoteName); comp.material.shader.name = "UI/Default"; platform.GetComponent <PlatformEffect>().Tag = "PP" + note.NoteNumber; return(platform); }
public void TestAddNamedTrack() { var manualMidi = new MidiEventCollection(1, 200); var noteEvent = new NoteOnEvent(0, 1, 1, 1, 1); const string trackName = "name"; var trackNameEvent = new TextEvent(trackName, MetaEventType.SequenceTrackName, 0); var endTrackEvent = new MetaEvent(MetaEventType.EndTrack, 0, noteEvent.OffEvent.AbsoluteTime); var track = manualMidi.AddTrack(); track.Add(trackNameEvent); track.Add(noteEvent); track.Add(noteEvent.OffEvent); track.Add(endTrackEvent); var extensionMidi = new MidiEventCollection(1, 200); var events = new MidiEvent[] { noteEvent, noteEvent.OffEvent }; extensionMidi.AddNamedTrack(trackName, events); MidiAssert.Equal(manualMidi, extensionMidi); // Assert events (not name / end) are the same objects var manualTrack = manualMidi[0]; var extensionTrack = extensionMidi[0]; for (var e = 1; e < manualTrack.Count - 1; e++) { Assert.That(extensionTrack[e], Is.SameAs(manualTrack[e])); } }
public void TestAddTrackCopyParams() { var manualMidi = new MidiEventCollection(1, 200); var noteEvent = new NoteOnEvent(0, 1, 1, 1, 1); var track = manualMidi.AddTrack(); track.Add(noteEvent); track.Add(noteEvent.OffEvent); var extensionMidi = new MidiEventCollection(1, 200); extensionMidi.AddTrackCopy(noteEvent, noteEvent.OffEvent); MidiAssert.Equal(manualMidi, extensionMidi); // Assert they aren't the same objects var manualTrack = manualMidi[0]; var extensionTrack = extensionMidi[0]; for (var e = 0; e < manualTrack.Count; e++) { Assert.That(extensionTrack[e], Is.Not.SameAs(manualTrack[e])); } // Verify the NoteOnEvent.OffEvent link Assert.AreEqual(extensionMidi[0][1], ((NoteOnEvent)extensionMidi[0][0]).OffEvent); }
public void AddDefaultDifficultyEventsDrums(MidiEventCollection midi) { var track = midi.GetTrackByName(TrackName.Drums.ToString()); var notes = track.OfType <NoteOnEvent>().ToList(); var expert = new Range <int>("Expert", 96, 100); var hard = new Range <int>("Hard", 84, 88); var medium = new Range <int>("Medium", 72, 76); var easy = new Range <int>("Easy", 60, 64); foreach (var range in new[] { easy, medium, hard, expert }) { if (notes.Any(n => n.NoteNumber >= range.Start && n.NoteNumber <= range.End)) { AddInfo($"{TrackName.Drums} already has at least one '{range.Name}' note."); continue; } var note = new NoteOnEvent(ThirdBarTime(midi), 1, range.Start, DefaultVelocity, MaxDrumNoteLength(midi)); track.Add(note); track.Add(note.OffEvent); } UpdateTrackEnd(track); }
public int getOctaveEstimate() { // Midi musicnote numbers go from #21 to #108 int noteNumberSum = 0; int noteCount = 0; for (int track = 0; track < m_data.Tracks; track++) { foreach (MidiEvent e in m_data[track]) { TimeSignatureEvent t; if (e.CommandCode == MidiCommandCode.NoteOn) { NoteOnEvent n = (NoteOnEvent)e; if (n.OffEvent != null) { ++noteCount; noteNumberSum += n.NoteNumber; // It is an event! } } } } int avgNoteVal = (int)(noteNumberSum / noteCount); return(avgNoteVal % 7); }
public void StopPlaying() { if (PlayingNote != null) { _midiOut.Send(PlayingNote.OffEvent.GetAsShortMessage()); PlayingNote = null; } }
public void TestAddTrackCopyDuplicateEvents() { var noteEvent = new NoteOnEvent(0, 1, 1, 1, 1); var extensionMidi = new MidiEventCollection(1, 200); var events = new MidiEvent[] { noteEvent, noteEvent.OffEvent, noteEvent, noteEvent.OffEvent }; Assert.Throws <ArgumentException>(() => extensionMidi.AddTrackCopy(events)); }
private void AddNoteEvent(int noteNumber) { int channel = 2; var noteOnEvent = new NoteOnEvent(0, channel, noteNumber, 100, 50); events.Add(noteOnEvent); events.Add(noteOnEvent.OffEvent); }
public void GetNoteId_NoteEvent_Null() { NoteOnEvent noteEvent = null; Assert.Throws <ArgumentNullException>( () => NoteIdUtilities.GetNoteId(noteEvent), "The method did not throw a NullReferenceException when passed a null reference."); }
private void MidiPushButtonLearnCallback(object sender, MidiInMessageEventArgs e) { NoteOnEvent evento = (NoteOnEvent)e.MidiEvent; _pushButtonMidiNote = evento.NoteNumber; GlobalStaticContext.RegisterPadWithMidiNote(this, _pushButtonMidiNote); GlobalStaticContext.ExitLearnMode(); }
public void PlayNewNote(int note, int velocity) { var nextNote = new NoteOnEvent(0, _channel, note, velocity, 0); StopPlaying(); _midiOut.Send(nextNote.GetAsShortMessage()); PlayingNote = nextNote; }
/// <returns>Was the step successful? (false if e.g. startTime == endTIme)</returns> public bool StepMIDI(double startTime, double endTime) //Fire all events between prevTime and time. { //Convert times to absolute: startTime = GetTimeInTicks(startTime); endTime = GetTimeInTicks(endTime); if (startTime == endTime) { return(false); //Ignore if start and end time are equal. } if (logTrack != -1) { Debug.Log("Stepping MIDI from " + startTime + " to " + endTime + "..."); } for (int t = 0; t < MIDIEvents.Length; t++) //for every track... { for (int i = lastEventCache[t] + 1; i < trackLengthsCache[t]; i++) //for every event... { ITimedObject e = MIDIEvents[t][i]; if (e.Time < startTime) //Event has already played. Skip to next one. { if (t == logTrack) { Debug.Log("Read expired event on track " + t + " between times " + startTime + " and " + endTime + ". Event time is " + e.Time); } lastEventCache[t] = i; continue; } if (e.Time >= endTime) //Event is too far in the future. Abort loop. { if (t == logTrack) { Debug.Log("Read future event on track " + t + " between times " + startTime + " and " + endTime + ". Event time is " + e.Time); } //Don't set last event cache - we want to revisit this event in the future. break; } //Else, event is within the timestep. if (e is TimedEvent && ((TimedEvent)e).Event is NoteOnEvent) //NoteOn without Note Off - convert it to a short note because Reaper f****d shit up. { NoteOnEvent noteOn = ((TimedEvent)e).Event as NoteOnEvent; Note newNote = new Note(noteOn.NoteNumber, midi.TimeDivision.ToInt16() / 4, e.Time); newNote.Velocity = noteOn.Velocity; e = newNote; } if (e is Note) //If it is a Note... { if (t == logTrack) { Debug.Log("Read new note on track " + t + " between times " + startTime + " and " + endTime + ". Event time is " + e.Time); } OnMIDINoteDown(t, e as Note); //Fire OnMIDINoteDown event. lastEventCache[t] = i; } } } return(true); }
protected override MidiEvent CloneEvent() { var non = new NoteOnEvent(base.NoteNumber, base.Velocity) { Channel = base.Channel }; return(new TaggedNoteOnEvent(non)); }
/// <summary> /// Creates a MidiEvent from a raw message received using /// the MME MIDI In APIs /// </summary> /// <param name="rawMessage">The short MIDI message</param> /// <returns>A new MIDI Event</returns> public static MidiEvent FromRawMessage(int rawMessage) { long absoluteTime = 0; int b = rawMessage & 0xFF; int data1 = (rawMessage >> 8) & 0xFF; int data2 = (rawMessage >> 16) & 0xFF; MidiCommandCode commandCode; int channel = 1; if ((b & 0xF0) == 0xF0) { // both bytes are used for command code in this case commandCode = (MidiCommandCode)b; } else { commandCode = (MidiCommandCode)(b & 0xF0); channel = (b & 0x0F) + 1; } MidiEvent me; switch (commandCode) { case MidiCommandCode.NoteOn: case MidiCommandCode.NoteOff: case MidiCommandCode.KeyAfterTouch: if (data2 > 0 && commandCode == MidiCommandCode.NoteOn) { me = new NoteOnEvent(absoluteTime, channel, data1, data2, 0); } else { me = new NoteEvent(absoluteTime, channel, commandCode, data1, data2); } break; case MidiCommandCode.ControlChange: me = new ControlChangeEvent(absoluteTime,channel,(MidiController)data1,data2); break; case MidiCommandCode.PatchChange: me = new PatchChangeEvent(absoluteTime,channel,data1); break; case MidiCommandCode.ChannelAfterTouch: me = new ChannelAfterTouchEvent(absoluteTime,channel,data1); break; case MidiCommandCode.PitchWheelChange: me = new PitchWheelChangeEvent(absoluteTime, channel, data1 + (data2 << 7)); break; case MidiCommandCode.TimingClock: case MidiCommandCode.StartSequence: case MidiCommandCode.ContinueSequence: case MidiCommandCode.StopSequence: case MidiCommandCode.AutoSensing: me = new MidiEvent(absoluteTime,channel,commandCode); break; case MidiCommandCode.MetaEvent: case MidiCommandCode.Sysex: default: throw new FormatException(String.Format("Unsupported MIDI Command Code for Raw Message {0}", commandCode)); } return me; }
/// <summary> /// Constructs a MidiEvent from a BinaryStream /// </summary> /// <param name="br">The binary stream of MIDI data</param> /// <param name="previous">The previous MIDI event (pass null for first event)</param> /// <returns>A new MidiEvent</returns> public static MidiEvent ReadNextEvent(BinaryReader br, MidiEvent previous) { int deltaTime = MidiEvent.ReadVarInt(br); MidiCommandCode commandCode; int channel = 1; byte b = br.ReadByte(); if((b & 0x80) == 0) { // a running command - command & channel are same as previous commandCode = previous.CommandCode; channel = previous.Channel; br.BaseStream.Position--; // need to push this back } else { if((b & 0xF0) == 0xF0) { // both bytes are used for command code in this case commandCode = (MidiCommandCode) b; } else { commandCode = (MidiCommandCode) (b & 0xF0); channel = (b & 0x0F) + 1; } } MidiEvent me; switch(commandCode) { case MidiCommandCode.NoteOn: me = new NoteOnEvent(br); break; case MidiCommandCode.NoteOff: case MidiCommandCode.KeyAfterTouch: me = new NoteEvent(br); break; case MidiCommandCode.ControlChange: me = new ControlChangeEvent(br); break; case MidiCommandCode.PatchChange: me = new PatchChangeEvent(br); break; case MidiCommandCode.ChannelAfterTouch: me = new ChannelAfterTouchEvent(br); break; case MidiCommandCode.PitchWheelChange: me = new PitchWheelChangeEvent(br); break; case MidiCommandCode.TimingClock: case MidiCommandCode.StartSequence: case MidiCommandCode.ContinueSequence: case MidiCommandCode.StopSequence: me = new MidiEvent(); break; case MidiCommandCode.Sysex: me = SysexEvent.ReadSysexEvent(br); break; case MidiCommandCode.MetaEvent: me = MetaEvent.ReadMetaEvent(br); break; default: throw new FormatException(String.Format("Unsupported MIDI Command Code {0:X2}",(byte) commandCode)); } me.channel = channel; me.deltaTime = deltaTime; me.commandCode = commandCode; return me; }