コード例 #1
0
ファイル: MidiFixer.cs プロジェクト: JoshuaWebb/FlRockBand3
        public void AddVenueTrack(MidiEventCollection midi)
        {
            var existingTrack = midi.FindTrackNumberByName(TrackName.Venue.ToString());

            if (existingTrack != -1)
            {
                return;
            }

            midi.AddNamedTrack(TrackName.Venue.ToString());
        }
コード例 #2
0
ファイル: MidiFixer.cs プロジェクト: JoshuaWebb/FlRockBand3
        public static MidiEventCollection ReorderTracks(MidiEventCollection midi)
        {
            var newMidi       = new MidiEventCollection(midi.MidiFileType, midi.DeltaTicksPerQuarterNote);
            var tempoMapIndex = midi.FindTrackNumberByName(TrackName.TempoMap.ToString());

            newMidi.AddTrack(midi[tempoMapIndex]);

            for (var t = 0; t < midi.Tracks; t++)
            {
                if (t != tempoMapIndex)
                {
                    newMidi.AddTrack(midi[t]);
                }
            }

            return(newMidi);
        }
コード例 #3
0
ファイル: MidiFixer.cs プロジェクト: JoshuaWebb/FlRockBand3
        public void ProcessTimeSignatures(MidiEventCollection midi)
        {
            // This is way easier if these have already been consolidated
            ConsolidateTimeTracks(midi);

            var timeSigTrackNo = midi.FindTrackNumberByName(TrackName.InputTimeSig.ToString());

            if (timeSigTrackNo == -1)
            {
                AddInfo($"No '{TrackName.InputTimeSig}' track");
                return;
            }

            var timeEvents = midi[midi.FindTrackNumberByName(TrackName.TempoMap.ToString())];

            var inputTimeSignatureEvents = midi[timeSigTrackNo].OfType <NoteOnEvent>();
            var groups = inputTimeSignatureEvents.GroupBy(e => e.AbsoluteTime);

            var error = false;

            foreach (var pair in groups)
            {
                var time = pair.Key;
                // The higher velocity value is the numerator (top)
                // And the lower velocity value is the denominator (bottom)
                var sorted = pair.OrderByDescending(e => e.Velocity).ToArray();
                if (sorted.Length != 2)
                {
                    error = true;
                    var detail = string.Join(", ", sorted.Select(e => $"<{e.NoteName} ({e.NoteNumber}), Velocity: {e.Velocity}>"));
                    AddError($"Incorrect number of time signature notes at {GetBarInfo(midi, time)}: {detail}");
                    continue;
                }

                if (sorted[0].Velocity == sorted[1].Velocity)
                {
                    error = true;
                    var detail = string.Join(", ", sorted.Select(e => $"<{e.NoteName} ({e.NoteNumber}), Velocity: {e.Velocity}>"));
                    AddError($"Multiple notes with the same velocity at {GetBarInfo(midi, time)}: {detail}");
                    continue;
                }

                var numerator = sorted[0].NoteNumber;

                int denominator;
                if (!TryConvertToDenominator(sorted[1].NoteNumber, out denominator))
                {
                    error = true;
                    AddError($"Invalid denominator note '{sorted[1].NoteNumber}' at {time}");
                    continue;
                }

                var timeSigEvent         = new TimeSignatureEvent(time, numerator, denominator, TicksInClick, NumberOfThirtySecondNotesInQuarterNote);
                var existingTimeSigEvent = timeEvents.OfType <TimeSignatureEvent>().SingleOrDefault(e => e.AbsoluteTime == time);
                if (existingTimeSigEvent != null)
                {
                    timeEvents.Remove(existingTimeSigEvent);
                }

                timeEvents.Add(timeSigEvent);
            }

            if (error)
            {
                throw new InvalidOperationException("Invalid time signature input");
            }

            // Clean up input track
            midi.RemoveTrack(timeSigTrackNo);

            UpdateTrackEnd(timeEvents, timeEvents.OrderBy(e => e.AbsoluteTime).Last().AbsoluteTime);

            // TODO: If there is no TimeSignatureEvent or TempoEvent at 0, wig out
        }