Ejemplo n.º 1
0
        public static void DiscretizeBends(Model midi)
        {
            var bendedNotes = midi.EventsOfType <NoteOn>(n => n.Bends != null && n.Bends.Count > 0).ToArray();

            // divide note into not-bended ones
            foreach (var note in bendedNotes)
            {
                var tmpNote = note;
                var pitch   = note.NoteNumber;
                var end     = note.End;

                var bends = note.Bends.OrderBy(b => b.AbsoluteRealTime).ToArray();
                note.Bends = new List <PitchBend>();

                foreach (var bend in bends)
                {
                    tmpNote.End            = bend.AbsoluteRealTime;
                    tmpNote.RealTimeLength = tmpNote.End - tmpNote.AbsoluteRealTime;

                    var bendedPitch = (byte)(pitch + bend.RealPitchChange + 0.5);
                    if (bendedPitch != tmpNote.NoteNumber)
                    {
                        tmpNote = new NoteOn
                        {
                            AbsoluteRealTime = bend.AbsoluteRealTime,
                            AbsoluteTime     = bend.AbsoluteTime,
                            ChannelNumber    = note.ChannelNumber,
                            Instrument       = note.Instrument,
                            NoteNumber       = bendedPitch,
                            Volume           = note.Volume,
                            RealVolume       = note.RealVolume,
                            Bends            = new List <PitchBend>()
                        };
                        midi.Tracks[0].Channels[tmpNote.ChannelNumber].Events.Add(tmpNote);
                    }
                }

                tmpNote.End            = end;
                tmpNote.RealTimeLength = tmpNote.End - tmpNote.AbsoluteRealTime;
            }

            // delete all pitch bends
            var channels = midi.Tracks.SelectMany(t => t.Channels);

            foreach (var channel in channels)
            {
                channel.Events.RemoveAll(e => e is PitchBend);
            }
        }
        double ControllerValueDuringNote(IEnumerable <Controller>[] changes, NoteOn note, double defaultValue = 96)
        {
            var during = changes[note.ChannelNumber]
                         .Where(ch => ch.AbsoluteRealTime < note.AbsoluteRealTime + note.RealTimeLength)
                         .Where(ch => ch.AbsoluteRealTime >= note.AbsoluteRealTime);

            if (during.Any())
            {
                return(during.Average(d => d.ControllerValue));
            }

            var before = changes[note.ChannelNumber].Where(ch => ch.AbsoluteRealTime <= note.AbsoluteRealTime);

            if (before.Any())
            {
                // select max according to AbsoluteRealTIme
                return(before.Aggregate((prev, act) => prev.AbsoluteRealTime < act.AbsoluteRealTime ? act : prev).ControllerValue);
            }

            return(defaultValue);
        }