/// <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); }
private void PianoControl1_NoteOff(object sender, NoteOffEvent e) { foreach (var i in instruments) { i.NotifyMidiEvent(e); } }
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; } }
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 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); }
void StopNote(int noteNumber) { if (MidiDeviceID >= 0) { NoteOffEvent NoteOff = new NoteOffEvent(); NoteOff.Channel = (FourBitNumber)15; NoteOff.NoteNumber = (SevenBitNumber)noteNumber; NoteOff.Velocity = (SevenBitNumber)127; if (Channel1Outputs [OutputMode]) { NoteOff.Channel = (FourBitNumber)0; MidiDevice.SendEvent(NoteOff); } if (Channel15Outputs [OutputMode]) { NoteOff.Channel = (FourBitNumber)14; MidiDevice.SendEvent(NoteOff); } if (Channel16Outputs [OutputMode]) { NoteOff.Channel = (FourBitNumber)15; MidiDevice.SendEvent(NoteOff); } Debug.Log("Stop " + noteNumber + " ID: " + MidiDeviceID); } }
void OnNoteOff(SyncObject syncObject, NoteOffEvent noteOnEvent) { syncObject.SendEvent( "noteOff", syncObject.Id, new IValue[] { }, localOnly: true ); }
private void lastKeyOff() { if (lastKeyOn >= 0) { NoteOffEvent noe = new NoteOffEvent((SevenBitNumber)lastKeyOn, (SevenBitNumber)127); NoteOff?.Invoke(this, noe); lastKeyOn = -1; } }
private void listBox1_MouseUp(object sender, MouseEventArgs e) { if (noteOnEvent != null) { NoteOffEvent noe = new NoteOffEvent(noteOnEvent.NoteNumber, noteOnEvent.Velocity); inst.NotifyMidiEvent(noe); noteOnEvent = null; } }
public static void NoteOff(NoteOffEvent msg) { lock (NoteOfflock) { Log.Debug($"msg {msg.NoteNumber} off at time {DateTime.Now:O}"); if (Convert.ToInt32(msg.NoteNumber) <= 84 && Convert.ToInt32(msg.NoteNumber) >= 48) { kc.KeyboardRelease(Convert.ToInt32(msg.NoteNumber)); } } }
private void PianoControl1_NoteOff(object sender, NoteOffEvent e) { try { //InstrumentManager.ExclusiveLockObject.EnterUpgradeableReadLock(); Instrument.NotifyMidiEvent(e); } finally { //InstrumentManager.ExclusiveLockObject.ExitUpgradeableReadLock(); } }
private void DrawNote(SpriteBatch sb, Rectangle area, NoteOnEvent n1, NoteOffEvent n2) { double conversion = area.Width / (vw.StopTime - vw.StartTime); Lane l = lanes[n1.Note]; sb.Draw(ui.Lane, new Rectangle { X = l.Position * 10 + area.X, Y = area.Height - (int)(area.X + (n2.Time - vw.StartTime) * conversion), Height = (int)((n2.Time - n1.Time) * conversion), Width = 10, }, Find(n1.Time)); }
private void _read() { _vTime = new VlqBase128Be(m_io); _eventHeader = m_io.ReadU1(); if (EventHeader == 255) { _metaEventBody = new MetaEventBody(m_io, this, m_root); } if (EventHeader == 240) { _sysexBody = new SysexEventBody(m_io, this, m_root); } switch (EventType) { case 224: { _eventBody = new PitchBendEvent(m_io, this, m_root); break; } case 144: { _eventBody = new NoteOnEvent(m_io, this, m_root); break; } case 208: { _eventBody = new ChannelPressureEvent(m_io, this, m_root); break; } case 192: { _eventBody = new ProgramChangeEvent(m_io, this, m_root); break; } case 160: { _eventBody = new PolyphonicPressureEvent(m_io, this, m_root); break; } case 176: { _eventBody = new ControllerEvent(m_io, this, m_root); break; } case 128: { _eventBody = new NoteOffEvent(m_io, this, m_root); break; } } }
public NoteOffEvent ToOffEvent() { var off = new NoteOffEvent(); off.note = note; off.velocity = velocity; off.Status = Status; off.Size = Size; off.DeltaTick = DeltaTick; off.eventType = EventType.NoteOff; off.Channel = Channel; off.Previous = Previous; return(off); }
public void RemoveObject(NoteOffEvent note) { if (!valid) { return; } var spatial = CurSpatials[note.NoteNumber]; if (spatial == null) { return; } CurSpatials[note.NoteNumber] = null; RemoveSpatial(spatial); }
/// <summary> /// /// </summary> /// <param name="noteOff"></param> public bool RemoveNote(NoteOffEvent noteOff) { bool result = false; for (int i = 0; i < orderedNotes.Count; i++) { if (orderedNotes[i].NoteNumber == noteOff.NoteNumber) { orderedNotes.RemoveAt(i); result = true; break; } } if (result) { calculateArp(); } return(result); }
/// <summary> /// Render the staff within given rectangle. /// Ignores height of rectangle /// Doesn't Calls begin and end on sprite batches /// </summary> public void Draw(SpriteBatch sb, Rectangle area) { foreach (var lane in lanes.Values) { if (lane.Lit) { sb.Draw(ui.Lane, new Rectangle { X = lane.Position * 10 + area.X, Y = 0, Height = area.Height, Width = 10, }, Color.White); } } for (int idx = s.DisplayEvents.GetFirstIdx(vw.StartTime); idx < s.DisplayEvents.Count; idx++) { var evt = s.DisplayEvents[idx]; if (evt.Time > vw.StopTime) { goto outer; } switch (evt) { case NoteOffEvent n2: NoteOnEvent n1 = n2.Match; DrawNote(sb, area, n1, n2); break; case NoteOnEvent n3: NoteOffEvent n4 = n3.Match; //TODO make note only draw once DrawNote(sb, area, n3, n4); break; default: throw new ArgumentException("Cannot display event"); } } outer :; }
public bool IsCorrespondingNoteOffEvent(NoteOffEvent noteOffEvent) { return(NoteEventUtilities.IsNoteOnCorrespondToNoteOff((NoteOnEvent)NoteOnTimedEvent.Event, noteOffEvent) && !IsNoteCompleted); }
public static void NoteOff(NoteOffEvent msg) { lock (NoteOfflock) { } }
/// <summary> /// Creates a new instance of the <see cref="NoteOnEvent"/> class using the specified <see cref="NoteOffEvent"/>, note number and velocity. /// </summary> /// <param name="channel">The channel of the event.</param> /// <param name="track">The track of the event.</param> /// <param name="deltaTime">The delta time of the event.</param> /// <param name="absoluteTime">The absolute time of the event.</param> /// <param name="noteNumber">The number of the note.</param> /// <param name="velocity">The velocity of the note.</param> /// <param name="offEvent">The <see cref="NoteOffEvent"/> associated with this event.</param> internal NoteOnEvent(byte channel, uint track, uint deltaTime, uint absoluteTime, byte noteNumber, byte velocity, NoteOffEvent offEvent) : this(channel, track, deltaTime, absoluteTime, noteNumber, velocity) { this.offEvent = offEvent; }
/// <summary> /// /// </summary> /// <param name="midiEvent"></param> protected override void OnNoteOffEvent(NoteOffEvent midiEvent) { soundManager.ProcessKeyOff(midiEvent); }
public static SongSimplification GetSimplificationZeroOfSong(string base64encodedMidiFile) { var notesObj = new List <Note>(); var midiFile = MidiFile.Read(base64encodedMidiFile); long songDuration = GetSongDurationInTicks(base64encodedMidiFile); var isSustainPedalOn = false; var notesOnBecauseOfSustainPedal = new List <Note>(); var instrumentOfChannel = new byte[16]; short chunkNo = -1; foreach (TrackChunk chunk in midiFile.Chunks) { chunkNo++; var currentNotes = new List <Note>(); long currentTick = 0; foreach (MidiEvent eventito in chunk.Events) { currentTick += eventito.DeltaTime; if (eventito is ProgramChangeEvent) { var pg = eventito as ProgramChangeEvent; instrumentOfChannel[pg.Channel] = (byte)pg.ProgramNumber.valor; continue; } if (IsSustainPedalEventOn(eventito)) { isSustainPedalOn = true; continue; } if (IsSustainPedalEventOff(eventito)) { isSustainPedalOn = false; foreach (var n in notesOnBecauseOfSustainPedal) { ProcessNoteOff(n.Pitch, currentNotes, notesObj, currentTick, n.Instrument, (byte)chunkNo); } continue; } if (eventito is NoteOnEvent) { NoteOnEvent noteOnEvent = eventito as NoteOnEvent; if (noteOnEvent.Velocity > 0 || isSustainPedalOn == false) { ProcessNoteOn(noteOnEvent.NoteNumber, noteOnEvent.Velocity, currentNotes, notesObj, currentTick, instrumentOfChannel[noteOnEvent.Channel], IsPercussionEvent(eventito), (byte)chunkNo); } continue; } if (eventito is NoteOffEvent && isSustainPedalOn == false) { NoteOffEvent noteOffEvent = eventito as NoteOffEvent; ProcessNoteOff(noteOffEvent.NoteNumber, currentNotes, notesObj, currentTick, instrumentOfChannel[noteOffEvent.Channel], (byte)chunkNo); continue; } if (eventito is PitchBendEvent) { PitchBendEvent bendito = eventito as PitchBendEvent; foreach (var notita in currentNotes) { PitchBendEvent maldito = bendito.Clone() as PitchBendEvent; maldito.DeltaTime = currentTick; notita.PitchBending.Add(new PitchBendItem { Note = notita, Pitch = maldito.PitchValue, TicksSinceBeginningOfSong = maldito.DeltaTime }); } continue; } } } var retObj = new SongSimplification() { Notes = notesObj, SimplificationVersion = 0, NumberOfVoices = chunkNo }; return(retObj); }
private static Tuple <Option <MidiEvent>, int, byte> NextEvent(List <byte> trackData, int startIndex, byte lastMidiChannel) { var i = startIndex - 1; MidiEvent midiEvent = null; { int deltaTime; { var lengthTemp = new List <byte>(); do { i += 1; lengthTemp.Add(trackData.ElementAt(i)); } while (trackData.ElementAt(i) > 0x7F); deltaTime = VariableLengthUtil.decode_to_int(lengthTemp); } i += 1; var eventTypeValue = trackData.ElementAt(i); // MIDI Channel Events if ((eventTypeValue & 0xF0) < 0xF0) { var midiChannelEventType = (byte)(eventTypeValue & 0xF0); var midiChannel = (byte)(eventTypeValue & 0x0F); i += 1; var parameter1 = trackData.ElementAt(i); byte parameter2; // One or two parameter type switch (midiChannelEventType) { // One parameter types case 0xC0: midiEvent = new ProgramChangeEvent(deltaTime, midiChannel, parameter1); lastMidiChannel = midiChannel; break; case 0xD0: midiEvent = new ChannelAftertouchEvent(deltaTime, midiChannel, parameter1); lastMidiChannel = midiChannel; break; // Two parameter types case 0x80: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new NoteOffEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0x90: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new NoteOnEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0xA0: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new NoteAftertouchEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0xB0: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new ControllerEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; case 0xE0: i += 1; parameter2 = trackData.ElementAt(i); midiEvent = new PitchBendEvent(deltaTime, midiChannel, parameter1, parameter2); lastMidiChannel = midiChannel; break; // Might be a Control Change Messages LSB default: midiEvent = new ControllerEvent(deltaTime, lastMidiChannel, eventTypeValue, parameter1); break; } i += 1; } // Meta Events else if (eventTypeValue == 0xFF) { i += 1; var metaEventType = trackData.ElementAt(i); i += 1; var metaEventLength = trackData.ElementAt(i); i += 1; var metaEventData = Enumerable.Range(i, metaEventLength).Select(trackData.ElementAt).ToArray(); switch (metaEventType) { case 0x00: midiEvent = new SequenceNumberEvent(BitConverter.ToUInt16(metaEventData.Reverse().ToArray(), 0)); break; case 0x01: midiEvent = new TextEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x02: midiEvent = new CopyrightNoticeEvent(StringEncoder.GetString(metaEventData)); break; case 0x03: midiEvent = new SequenceOrTrackNameEvent(StringEncoder.GetString(metaEventData)); break; case 0x04: midiEvent = new InstrumentNameEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x05: midiEvent = new LyricsEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x06: midiEvent = new MarkerEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x07: midiEvent = new CuePointEvent(deltaTime, StringEncoder.GetString(metaEventData)); break; case 0x20: midiEvent = new MIDIChannelPrefixEvent(deltaTime, metaEventData[0]); break; case 0x2F: midiEvent = new EndOfTrackEvent(deltaTime); break; case 0x51: var tempo = (metaEventData[2] & 0x0F) + ((metaEventData[2] & 0xF0) * 16) + ((metaEventData[1] & 0x0F) * 256) + ((metaEventData[1] & 0xF0) * 4096) + ((metaEventData[0] & 0x0F) * 65536) + ((metaEventData[0] & 0xF0) * 1048576); midiEvent = new SetTempoEvent(deltaTime, tempo); break; case 0x54: midiEvent = new SMPTEOffsetEvent(deltaTime, metaEventData[0], metaEventData[1], metaEventData[2], metaEventData[3], metaEventData[4]); break; case 0x58: midiEvent = new TimeSignatureEvent(deltaTime, metaEventData[0], metaEventData[1], metaEventData[2], metaEventData[3]); break; case 0x59: midiEvent = new KeySignatureEvent(deltaTime, metaEventData[0], metaEventData[1]); break; case 0x7F: midiEvent = new SequencerSpecificEvent(deltaTime, metaEventData); break; } i += metaEventLength; } // System Exclusive Events else if (eventTypeValue == 0xF0 || eventTypeValue == 0xF7) { var lengthTemp = new List <byte>(); do { i += 1; lengthTemp.Add(trackData.ElementAt(i)); } while (trackData.ElementAt(i) > 0x7F); var eventLength = VariableLengthUtil.decode_to_int(lengthTemp); i += 1; var eventData = Enumerable.Range(i, eventLength).Select(trackData.ElementAt); midiEvent = new SysexEvent(deltaTime, eventTypeValue, eventData); i += eventLength; } } return(midiEvent != null ? new Tuple <Option <MidiEvent>, int, byte>(new Some <MidiEvent>(midiEvent), i - startIndex, lastMidiChannel) : new Tuple <Option <MidiEvent>, int, byte>(new None <MidiEvent>(), i - startIndex, lastMidiChannel)); }