protected MidiParser() { ActiveNotes = new ushort[128]; HangingNotes = new NoteTimer[32]; for (int i = 0; i < HangingNotes.Length; i++) { HangingNotes[i] = new NoteTimer(); } Tracks = new Track[120]; TimerRate = 0x4A0000; _ppqn = 96; tempo = 500000; _psecPerTick = 5208;// 500000 / 96 _nextEvent = new EventInfo(); _nextEvent.Start = 0; _nextEvent.Delta = 0; _nextEvent.Event = 0; Position = new Tracker(); }
public bool JumpToTick(uint tick, bool fireEvents = false, bool stopNotes = true, bool dontSendNoteOn = false) { if (ActiveTrack >= NumTracks) return false; Debug.Assert(!_jumpingToTick); // This function is not re-entrant _jumpingToTick = true; Tracker currentPos = new Tracker(Position); var currentEvent = new EventInfo(_nextEvent); ResetTracking(); Position.PlayPos = Tracks[ActiveTrack].Position; ParseNextEvent(_nextEvent); if (tick > 0) { while (true) { EventInfo info = _nextEvent; if (Position.LastEventTick + info.Delta >= tick) { Position.PlayTime += (int)(tick - Position.LastEventTick) * _psecPerTick; Position.PlayTick = (int)tick; break; } Position.LastEventTick += info.Delta; Position.LastEventTime += (int)info.Delta * _psecPerTick; Position.PlayTick = (int)Position.LastEventTick; Position.PlayTime = Position.LastEventTime; // Some special processing for the fast-forward case if (info.Command == 0x9 && dontSendNoteOn) { // Don't send note on; doing so creates a "warble" with // some instruments on the MT-32. Refer to patch #3117577 } else if (info.Event == 0xFF && info.MetaType == 0x2F) { // End of track // This means that we failed to find the right tick. Position = currentPos; _nextEvent = currentEvent; _jumpingToTick = false; return false; } else { ProcessEvent(info, fireEvents); } ParseNextEvent(_nextEvent); } } if (stopNotes) { if (_smartJump || currentPos.PlayPos == 0) { AllNotesOff(); } else { var targetEvent = new EventInfo(_nextEvent); var targetPosition = new Tracker(Position); Position = currentPos; _nextEvent = currentEvent; HangAllActiveNotes(); _nextEvent = targetEvent; Position = targetPosition; } } AbortParse = true; _jumpingToTick = false; return true; }