コード例 #1
0
        private void LoadMidiFile(MidiFile midiFile)
        {
            _tempoChanges = new FastList <MidiFileSequencerTempoChange>();
            //Converts midi to sample based format for easy sequencing
            float bpm = 120.0f;

            //Combine all tracks into 1 track that is organized from lowest to highest absolute time
            if (midiFile.Tracks.Length > 1 || midiFile.Tracks[0].EndTime == 0)
            {
                midiFile.CombineTracks();
            }

            //Convert delta time to sample time
            _synthData   = new SynthEvent[midiFile.Tracks[0].MidiEvents.Length];
            _division    = midiFile.Division;
            _eventIndex  = 0;
            CurrentTime  = 0;
            CurrentTempo = (int)bpm;
            //Calculate sample based time using double counter and round down to nearest integer sample.
            var absDelta = 0.0;
            var absTick  = 0;
            var absTime  = 0.0;

            for (int x = 0; x < midiFile.Tracks[0].MidiEvents.Length; x++)
            {
                var mEvent = midiFile.Tracks[0].MidiEvents[x];
                _synthData[x]       = new SynthEvent(mEvent);
                absTick            += mEvent.DeltaTime;
                absTime            += mEvent.DeltaTime * (60000.0 / (bpm * midiFile.Division));
                absDelta           += Synth.SampleRate * mEvent.DeltaTime * (60.0 / (bpm * midiFile.Division));
                _synthData[x].Delta = (int)(absDelta);
                //Update tempo
                if (IsTempoMessage(mEvent.Command, mEvent.Data1))
                {
                    var meta = (MetaNumberEvent)mEvent;
                    bpm = MidiHelper.MicroSecondsPerMinute / meta.Value;
                    _tempoChanges.Add(new MidiFileSequencerTempoChange(bpm, absTick, (int)(absTime)));
                }
            }

            EndTime = _synthData[_synthData.Length - 1].Delta;
        }
コード例 #2
0
 public void DispatchEvent(int i, SynthEvent synthEvent)
 {
     _midiEventQueue.AddFirst(synthEvent);
     _midiEventCounts[i]++;
 }
コード例 #3
0
        public void LoadMidi(MidiFile midiFile)
        {
            _tempoChanges = new FastList <MidiFileSequencerTempoChange>();


            // Combine all tracks into 1 track that is organized from lowest to highest absolute time
            if (midiFile.Tracks.Length > 1 || midiFile.Tracks[0].EndTime == 0)
            {
                midiFile.CombineTracks();
            }
            _division    = midiFile.Division;
            _eventIndex  = 0;
            _currentTime = 0;

            // build synth events.
            _synthData = new FastList <SynthEvent>();

            // Converts midi to milliseconds for easy sequencing
            double bpm     = 120;
            var    absTick = 0;
            var    absTime = 0.0;

            var metronomeLength = 0;
            var metronomeTick   = 0;
            var metronomeTime   = 0.0;

            for (int x = 0; x < midiFile.Tracks[0].MidiEvents.Length; x++)
            {
                var mEvent = midiFile.Tracks[0].MidiEvents[x];

                var synthData = new SynthEvent(mEvent);
                _synthData.Add(synthData);
                absTick        += mEvent.DeltaTime;
                absTime        += mEvent.DeltaTime * (60000.0 / (bpm * midiFile.Division));
                synthData.Delta = absTime;

                if (mEvent.Command == MidiEventTypeEnum.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.Tempo)
                {
                    var meta = (MetaNumberEvent)mEvent;
                    bpm = MidiHelper.MicroSecondsPerMinute / (double)meta.Value;
                    _tempoChanges.Add(new MidiFileSequencerTempoChange(bpm, absTick, (int)(absTime)));
                }
                else if (mEvent.Command == MidiEventTypeEnum.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.TimeSignature)
                {
                    var meta = (MetaDataEvent)mEvent;
                    var timeSignatureDenominator = (int)Math.Pow(2, meta.Data[1]);
                    metronomeLength = (int)(_division * (4.0 / timeSignatureDenominator));
                }
                else if (mEvent.Command == MidiEventTypeEnum.ProgramChange)
                {
                    var channel = mEvent.Channel;
                    if (!_firstProgramEventPerChannel.ContainsKey(channel))
                    {
                        _firstProgramEventPerChannel[channel] = synthData;
                    }
                }

                if (metronomeLength > 0)
                {
                    while (metronomeTick < absTick)
                    {
                        var metronome = SynthEvent.NewMetronomeEvent(metronomeLength);
                        _synthData.Add(metronome);
                        metronome.Delta = metronomeTime;

                        metronomeTick += metronomeLength;
                        metronomeTime += metronomeLength * (60000.0 / (bpm * midiFile.Division));
                    }
                }
            }

            _synthData.Sort((a, b) => (int)(a.Delta - b.Delta));
            _endTime = absTime;
            EndTick  = absTick;
        }
コード例 #4
0
        public void LoadMidi(MidiFile midiFile)
        {
            _tempoChanges = new FastList <MidiFileSequencerTempoChange>();

            _division    = midiFile.Division;
            _eventIndex  = 0;
            _currentTime = 0;

            // build synth events.
            _synthData = new FastList <SynthEvent>();

            // Converts midi to milliseconds for easy sequencing
            double bpm     = 120;
            var    absTick = 0;
            var    absTime = 0.0;

            var metronomeLength = 0;
            var metronomeTick   = 0;
            var metronomeTime   = 0.0;

            var previousTick = 0;

            foreach (var mEvent in midiFile.Events)
            {
                var synthData = new SynthEvent(_synthData.Count, mEvent);
                _synthData.Add(synthData);

                var deltaTick = mEvent.Tick - previousTick;
                absTick       += deltaTick;
                absTime       += deltaTick * (60000.0 / (bpm * midiFile.Division));
                synthData.Time = absTime;
                previousTick   = mEvent.Tick;

                if (mEvent.Command == MidiEventType.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.Tempo)
                {
                    var meta = (MetaNumberEvent)mEvent;
                    bpm = MidiHelper.MicroSecondsPerMinute / (double)meta.Value;
                    _tempoChanges.Add(new MidiFileSequencerTempoChange(bpm, absTick, (int)(absTime)));
                }
                else if (mEvent.Command == MidiEventType.Meta && mEvent.Data1 == (int)MetaEventTypeEnum.TimeSignature)
                {
                    var meta = (MetaDataEvent)mEvent;
                    var timeSignatureDenominator = (int)Math.Pow(2, meta.Data[1]);
                    metronomeLength = (int)(_division * (4.0 / timeSignatureDenominator));
                }
                else if (mEvent.Command == MidiEventType.ProgramChange)
                {
                    var channel = mEvent.Channel;
                    if (!_firstProgramEventPerChannel.ContainsKey(channel))
                    {
                        _firstProgramEventPerChannel[channel] = synthData;
                    }
                }

                if (metronomeLength > 0)
                {
                    while (metronomeTick < absTick)
                    {
                        var metronome = SynthEvent.NewMetronomeEvent(_synthData.Count, metronomeLength);
                        _synthData.Add(metronome);
                        metronome.Time = metronomeTime;

                        metronomeTick += metronomeLength;
                        metronomeTime += metronomeLength * (60000.0 / (bpm * midiFile.Division));
                    }
                }
            }

            _synthData.Sort((a, b) =>
            {
                if (a.Time > b.Time)
                {
                    return(1);
                }
                else if (a.Time < b.Time)
                {
                    return(-1);
                }
                return(a.EventIndex - b.EventIndex);
            });
            _endTime = absTime;
            EndTick  = absTick;
        }