Exemple #1
0
        public MidiTrack(byte[] instPrograms, byte[] drumPrograms, byte[] activeChannels, MidiEvent[] midiEvents)
        {
            Instruments = instPrograms;
            DrumInstruments = drumPrograms;
            ActiveChannels = activeChannels;
            MidiEvents = midiEvents;

            NoteOnCount = 0;
            EndTime = 0;
        }
Exemple #2
0
        public void CombineTracks()
        {
            var finalTrack = MergeTracks();
            var absEvents = new MidiEvent[Tracks.Length][];

            for (int i = 0; i < Tracks.Length; i++)
            {
                absEvents[i] = new MidiEvent[Tracks[i].MidiEvents.Length];
                var totalDeltaTime = 0;
                for (int j = 0; j < Tracks[i].MidiEvents.Length; j++)
                {
                    absEvents[i][j] = Tracks[i].MidiEvents[j];
                    totalDeltaTime += absEvents[i][j].DeltaTime;
                    absEvents[i][j].DeltaTime = totalDeltaTime;
                }
            }

            var eventCount = 0;
            var delta = 0;
            var nextdelta = int.MaxValue;
            var counters = new int[absEvents.Length];
            TypeUtils.ClearIntArray(counters);
            while (eventCount < finalTrack.MidiEvents.Length)
            {
                for (int x = 0; x < absEvents.Length; x++)
                {
                    while (counters[x] < absEvents[x].Length && absEvents[x][counters[x]].DeltaTime == delta)
                    {
                        finalTrack.MidiEvents[eventCount] = absEvents[x][counters[x]];
                        eventCount++;
                        counters[x]++;
                    }
                    if (counters[x] < absEvents[x].Length && absEvents[x][counters[x]].DeltaTime < nextdelta)
                        nextdelta = absEvents[x][counters[x]].DeltaTime;
                }
                delta = nextdelta;
                nextdelta = int.MaxValue;
            }
            finalTrack.EndTime = finalTrack.MidiEvents[finalTrack.MidiEvents.Length - 1].DeltaTime;
            var deltaDiff = 0;
            for (int x = 0; x < finalTrack.MidiEvents.Length; x++)
            {
                var oldTime = finalTrack.MidiEvents[x].DeltaTime;
                finalTrack.MidiEvents[x].DeltaTime -= deltaDiff;
                deltaDiff = oldTime;
            }

            Tracks = new MidiTrack[] { finalTrack };
            TrackFormat = MidiTrackFormat.SingleTrack;
        }
Exemple #3
0
 private void FireMidiMessageProcessed(MidiEvent e)
 {
     for (int i = 0; i < _midiMessageProcessed.Count; i++)
     {
         var l = _midiMessageProcessed[i];
         if (l != null)
         {
             l(e);
         }
     }
 }
Exemple #4
0
 public void ProcessMidiMessage(MidiEvent e)
 {
     var command = e.Command;
     var channel = e.Channel;
     var data1 = e.Data1;
     var data2 = e.Data2;
     switch (command)
     {
         case MidiEventTypeEnum.NoteOff:
             NoteOff(channel, data1);
             break;
         case MidiEventTypeEnum.NoteOn:
             if (data2 == 0)
                 NoteOff(channel, data1);
             else
                 NoteOn(channel, data1, data2);
             break;
         case MidiEventTypeEnum.NoteAftertouch:
             //synth uses channel after touch instead
             break;
         case MidiEventTypeEnum.Controller:
             switch ((ControllerTypeEnum)data1)
             {
                 case ControllerTypeEnum.BankSelectCoarse: //Bank select coarse
                     if (channel == MidiHelper.DrumChannel)
                         data2 += PatchBank.DrumBank;
                     if (SoundBank.IsBankLoaded(data2))
                         _synthChannels[channel].BankSelect = (byte)data2;
                     else
                         _synthChannels[channel].BankSelect = (byte) ((channel == MidiHelper.DrumChannel) ? PatchBank.DrumBank : 0);
                     break;
                 case ControllerTypeEnum.ModulationCoarse: //Modulation wheel coarse
                     _synthChannels[channel].ModRange.Coarse = (byte)data2;
                     _synthChannels[channel].UpdateCurrentMod();
                     break;
                 case ControllerTypeEnum.ModulationFine: //Modulation wheel fine
                     _synthChannels[channel].ModRange.Fine = (byte)data2;
                     _synthChannels[channel].UpdateCurrentMod();
                     break;
                 case ControllerTypeEnum.VolumeCoarse: //Channel volume coarse
                     _synthChannels[channel].Volume.Coarse = (byte)data2;
                     break;
                 case ControllerTypeEnum.VolumeFine: //Channel volume fine
                     _synthChannels[channel].Volume.Fine = (byte)data2;
                     break;
                 case ControllerTypeEnum.PanCoarse: //Pan coarse
                     _synthChannels[channel].Pan.Coarse = (byte)data2;
                     _synthChannels[channel].UpdateCurrentPan();
                     break;
                 case ControllerTypeEnum.PanFine: //Pan fine
                     _synthChannels[channel].Pan.Fine = (byte)data2;
                     _synthChannels[channel].UpdateCurrentPan();
                     break;
                 case ControllerTypeEnum.ExpressionControllerCoarse: //Expression coarse
                     _synthChannels[channel].Expression.Coarse = (byte)data2;
                     _synthChannels[channel].UpdateCurrentVolume();
                     break;
                 case ControllerTypeEnum.ExpressionControllerFine: //Expression fine
                     _synthChannels[channel].Expression.Fine = (byte)data2;
                     _synthChannels[channel].UpdateCurrentVolume();
                     break;
                 case ControllerTypeEnum.HoldPedal: //Hold pedal
                     if (_synthChannels[channel].HoldPedal && !(data2 > 63)) //if hold pedal is released stop any voices with pending release tags
                         ReleaseHoldPedal(channel);
                     _synthChannels[channel].HoldPedal = data2 > 63;
                     break;
                 case ControllerTypeEnum.LegatoPedal: //Legato Pedal
                     _synthChannels[channel].LegatoPedal = data2 > 63;
                     break;
                 case ControllerTypeEnum.NonRegisteredParameterCourse: //NRPN Coarse Select   //fix for invalid DataEntry after unsupported NRPN events
                     _synthChannels[channel].Rpn.Combined = 0x3FFF; //todo implement NRPN
                     break;
                 case ControllerTypeEnum.NonRegisteredParameterFine: //NRPN Fine Select     //fix for invalid DataEntry after unsupported NRPN events
                     _synthChannels[channel].Rpn.Combined = 0x3FFF; //todo implement NRPN
                     break;
                 case ControllerTypeEnum.RegisteredParameterCourse: //RPN Coarse Select
                     _synthChannels[channel].Rpn.Coarse = (byte)data2;
                     break;
                 case ControllerTypeEnum.RegisteredParameterFine: //RPN Fine Select
                     _synthChannels[channel].Rpn.Fine = (byte)data2;
                     break;
                 case ControllerTypeEnum.AllNotesOff: //Note Off All
                     NoteOffAll(false);
                     break;
                 case ControllerTypeEnum.DataEntryCoarse: //DataEntry Coarse
                     switch (_synthChannels[channel].Rpn.Combined)
                     {
                         case 0: //change semitone, pitchwheel
                             _synthChannels[channel].PitchBendRangeCoarse = (byte)data2;
                             _synthChannels[channel].UpdateCurrentPitch();
                             break;
                         case 1: //master fine tune coarse
                             _synthChannels[channel].MasterFineTune.Coarse = (byte)data2;
                             break;
                         case 2: //master coarse tune coarse
                             _synthChannels[channel].MasterCoarseTune = (short)(data2 - 64);
                             break;
                     }
                     break;
                 case ControllerTypeEnum.DataEntryFine: //DataEntry Fine
                     switch (_synthChannels[channel].Rpn.Combined)
                     {
                         case 0: //change cents, pitchwheel
                             _synthChannels[channel].PitchBendRangeFine = (byte)data2;
                             _synthChannels[channel].UpdateCurrentPitch();
                             break;
                         case 1: //master fine tune fine
                             _synthChannels[channel].MasterFineTune.Fine = (byte)data2;
                             break;
                     }
                     break;
                 case ControllerTypeEnum.ResetControllers: //Reset All
                     _synthChannels[channel].Expression.Combined = 0x3FFF;
                     _synthChannels[channel].ModRange.Combined = 0;
                     if (_synthChannels[channel].HoldPedal)
                         ReleaseHoldPedal(channel);
                     _synthChannels[channel].HoldPedal = false;
                     _synthChannels[channel].LegatoPedal = false;
                     _synthChannels[channel].Rpn.Combined = 0x3FFF;
                     _synthChannels[channel].PitchBend.Combined = 0x2000;
                     _synthChannels[channel].ChannelAfterTouch = 0;
                     _synthChannels[channel].UpdateCurrentPitch(); //because pitchBend was reset
                     _synthChannels[channel].UpdateCurrentVolume(); //because expression was reset
                     break;
                 default:
                     return;
             }
             break;
         case MidiEventTypeEnum.ProgramChange: //Program Change
             _synthChannels[channel].Program = (byte)data1;
             break;
         case MidiEventTypeEnum.ChannelAftertouch: //Channel Aftertouch
             _synthChannels[channel].ChannelAfterTouch = (byte)data2;
             break;
         case MidiEventTypeEnum.PitchBend: //Pitch Bend
             _synthChannels[channel].PitchBend.Coarse = (byte)data2;
             _synthChannels[channel].PitchBend.Fine = (byte)data1;
             _synthChannels[channel].UpdateCurrentPitch();                   
             break;
     }
     FireMidiMessageProcessed(e);
 }
Exemple #5
0
 public SynthEvent(MidiEvent e)
 {
     Event = e;
 }
 private void MidiEventProcessed(MidiEvent midiEvent)
 {
     if (IsTempoMessage(midiEvent.Command, midiEvent.Data1))
     {
         var meta = (MetaNumberEvent)midiEvent;
         CurrentTempo = (int)(MidiHelper.MicroSecondsPerMinute / meta.Value);
     }
 }
Exemple #7
0
 private static int TrackVoiceStats(MidiEvent midiEvent, FastList<byte> instList, FastList<byte> drumList, FastList<byte> channelList, int noteOnCount)
 {
     if (midiEvent.Command == MidiEventTypeEnum.NoteOn)
     {
         var chan = midiEvent.Channel;
         if (channelList.IndexOf((byte)chan) == -1)
             channelList.Add((byte)chan);
         noteOnCount++;
     }
     else if (midiEvent.Command == MidiEventTypeEnum.ProgramChange)
     {
         var chan = midiEvent.Channel;
         var prog = midiEvent.Data1;
         if (chan == MidiHelper.DrumChannel)
         {
             if (drumList.IndexOf((byte)prog) == -1)
                 drumList.Add((byte)prog);
         }
         else
         {
             if (instList.IndexOf((byte)prog) == -1)
                 instList.Add((byte)prog);
         }
     }
     return noteOnCount;
 }