public void AddDefaultDifficultyEventsDrums(MidiEventCollection midi) { var track = midi.GetTrackByName(TrackName.Drums.ToString()); var notes = track.OfType <NoteOnEvent>().ToList(); var expert = new Range <int>("Expert", 96, 100); var hard = new Range <int>("Hard", 84, 88); var medium = new Range <int>("Medium", 72, 76); var easy = new Range <int>("Easy", 60, 64); foreach (var range in new[] { easy, medium, hard, expert }) { if (notes.Any(n => n.NoteNumber >= range.Start && n.NoteNumber <= range.End)) { AddInfo($"{TrackName.Drums} already has at least one '{range.Name}' note."); continue; } var note = new NoteOnEvent(ThirdBarTime(midi), 1, range.Start, DefaultVelocity, MaxDrumNoteLength(midi)); track.Add(note); track.Add(note.OffEvent); } UpdateTrackEnd(track); }
public void AddMusicEndEvent(MidiEventCollection midi) { var eventsTrack = midi.GetTrackByName(TrackName.Events.ToString()); var endEvent = eventsTrack.FindFirstTextEvent(EventName.End.ToString()); Debug.Assert(endEvent != null); // TODO: move slightly earlier than the end ?? AddEventIfItDoesNotExist(midi, EventName.MusicEnd.ToString(), endEvent.AbsoluteTime); }
public void CapDrumTrackDurations(MidiEventCollection midi) { var drumPart = midi.GetTrackByName(TrackName.Drums.ToString()); // Don't shorten the special notes because they are supposed to // overlap the regular notes var regularDrumNotes = drumPart. OfType <NoteOnEvent>(). Where(note => !SpecialNoteNumbers.Contains(note.NoteNumber)); foreach (var noteOn in regularDrumNotes) { noteOn.OffEvent.AbsoluteTime = noteOn.AbsoluteTime + 1; } }
private void AddEventIfItDoesNotExist(MidiEventCollection midi, string eventName, long time) { var eventsTrack = midi.GetTrackByName(TrackName.Events.ToString()); var existingEvent = eventsTrack.FindFirstTextEvent(eventName); if (existingEvent != null) { return; } var newEvent = new TextEvent(eventName, MetaEventType.TextEvent, time); AddInfo($"Adding {eventName} event at {GetBarInfo(midi, newEvent)}"); eventsTrack.Add(newEvent); }
public void ValidateBeatTrack(MidiEventCollection midi) { var beatTrack = midi.GetTrackByName(TrackName.Beat.ToString()); var invalidBeats = beatTrack. OfType <NoteOnEvent>(). Where(e => e.NoteNumber != DownBeat && e.NoteNumber != UpBeat). ToList(); foreach (var beat in invalidBeats) { AddError($"Invalid note: {beat.NoteName} ({beat.NoteNumber}) at {GetBarInfo(midi, beat)}"); } if (invalidBeats.Count > 0) { throw new InvalidBeatTrackException("Invalid beats detected."); } }
public void AddDrumMixEvents(MidiEventCollection midi) { var drumTrack = midi.GetTrackByName(TrackName.Drums.ToString()); var existingMixEvents = drumTrack. OfType <TextEvent>(). Where(e => e.AbsoluteTime == 0 && e.MetaEventType == MetaEventType.TextEvent). Select(e => e.AsDrumMixEvent()). Where(e => e != null). ToList(); for (var difficulty = 0; difficulty < 4; difficulty++) { if (existingMixEvents.Any(e => e.Difficulty == difficulty)) { continue; } // Try to keep them in order drumTrack.Insert(difficulty + 1, DrumMixEvent.DefaultFor(difficulty)); } }
public void ConvertLastBeatToEnd(MidiEventCollection midi) { var beatTrack = midi.GetTrackByName(TrackName.Beat.ToString()); var lastBeatOn = beatTrack.OfType <NoteOnEvent>().OrderBy(e => e.AbsoluteTime).LastOrDefault(MidiEvent.IsNoteOn); if (lastBeatOn == null) { throw new InvalidBeatTrackException($"No notes were found on the {TrackName.Beat} track"); } var eventsTrack = midi.FindTrackByName(TrackName.Events.ToString()); if (eventsTrack != null) { var existingEvent = eventsTrack.FindFirstTextEvent(EventName.End.ToString()); if (existingEvent != null) { AddInfo($"{EventName.End} event already exists at {GetBarInfo(midi, existingEvent)}, left last beat in place."); return; } } else { eventsTrack = midi.AddNamedTrack(TrackName.Events.ToString()); } beatTrack.Remove(lastBeatOn); beatTrack.Remove(lastBeatOn.OffEvent); // Fix beat track end var newLastEvent = beatTrack.OfType <NoteEvent>().OrderBy(e => e.AbsoluteTime).Last(); UpdateTrackEnd(beatTrack, newLastEvent.AbsoluteTime); eventsTrack.Add(new TextEvent(EventName.End.ToString(), MetaEventType.TextEvent, lastBeatOn.AbsoluteTime)); UpdateTrackEnd(eventsTrack, lastBeatOn.AbsoluteTime); }