Beispiel #1
0
 /// <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);
 }
Beispiel #2
0
 private void PianoControl1_NoteOff(object sender, NoteOffEvent e)
 {
     foreach (var i in instruments)
     {
         i.NotifyMidiEvent(e);
     }
 }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
    }
Beispiel #7
0
 void OnNoteOff(SyncObject syncObject, NoteOffEvent noteOnEvent)
 {
     syncObject.SendEvent(
         "noteOff",
         syncObject.Id,
         new IValue[] { },
         localOnly: true
         );
 }
Beispiel #8
0
 private void lastKeyOff()
 {
     if (lastKeyOn >= 0)
     {
         NoteOffEvent noe = new NoteOffEvent((SevenBitNumber)lastKeyOn, (SevenBitNumber)127);
         NoteOff?.Invoke(this, noe);
         lastKeyOn = -1;
     }
 }
Beispiel #9
0
        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));
         }
     }
 }
Beispiel #11
0
        private void PianoControl1_NoteOff(object sender, NoteOffEvent e)
        {
            try
            {
                //InstrumentManager.ExclusiveLockObject.EnterUpgradeableReadLock();

                Instrument.NotifyMidiEvent(e);
            }
            finally
            {
                //InstrumentManager.ExclusiveLockObject.ExitUpgradeableReadLock();
            }
        }
Beispiel #12
0
        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));
        }
Beispiel #13
0
            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;
                }
                }
            }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        public void RemoveObject(NoteOffEvent note)
        {
            if (!valid)
            {
                return;
            }
            var spatial = CurSpatials[note.NoteNumber];

            if (spatial == null)
            {
                return;
            }
            CurSpatials[note.NoteNumber] = null;
            RemoveSpatial(spatial);
        }
Beispiel #16
0
        /// <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);
        }
Beispiel #17
0
        /// <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 :;
        }
Beispiel #18
0
 public bool IsCorrespondingNoteOffEvent(NoteOffEvent noteOffEvent)
 {
     return(NoteEventUtilities.IsNoteOnCorrespondToNoteOff((NoteOnEvent)NoteOnTimedEvent.Event,
                                                           noteOffEvent) &&
            !IsNoteCompleted);
 }
Beispiel #19
0
 public static void NoteOff(NoteOffEvent msg)
 {
     lock (NoteOfflock)
     {
     }
 }
Beispiel #20
0
 /// <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;
 }
Beispiel #21
0
 /// <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);
        }
Beispiel #23
0
        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));
        }