private void OnMidiEventRx(InstrumentMidiEventEvent midiEv) { var uid = midiEv.Uid; if (!EntityManager.TryGetComponent(uid, out InstrumentComponent? instrument)) { return; } var renderer = instrument.Renderer; if (renderer != null) { // If we're the ones sending the MidiEvents, we ignore this message. if (instrument.IsInputOpen || instrument.IsMidiOpen) { return; } } else { // if we haven't started or finished some sequence if (instrument.SequenceStartTick == 0) { // we may have arrived late SetupRenderer(uid, true, instrument); } // might be our own notes after we already finished playing return; } if (instrument.SequenceStartTick <= 0) { instrument.SequenceStartTick = midiEv.MidiEvent.Min(x => x.Tick) - 1; } var sqrtLag = MathF.Sqrt(_netManager.ServerChannel !.Ping / 1000f); var delay = (uint)(renderer.SequencerTimeScale * (.2 + sqrtLag)); var delta = delay - instrument.SequenceStartTick; instrument.SequenceDelay = Math.Max(instrument.SequenceDelay, delta); var currentTick = renderer.SequencerTick; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < midiEv.MidiEvent.Length; i++) { var ev = midiEv.MidiEvent[i]; var scheduled = ev.Tick + instrument.SequenceDelay; if (scheduled <= currentTick) { instrument.SequenceDelay += currentTick - ev.Tick; scheduled = ev.Tick + instrument.SequenceDelay; } instrument.Renderer?.ScheduleMidiEvent(ev, scheduled, true); } }
private void OnMidiEventRx(InstrumentMidiEventEvent msg, EntitySessionEventArgs args) { var uid = msg.Uid; if (!EntityManager.TryGetComponent(uid, out InstrumentComponent? instrument)) { return; } if (!instrument.Playing || args.SenderSession != instrument.InstrumentPlayer || instrument.InstrumentPlayer == null || args.SenderSession.AttachedEntity is not { } attached) { return; } var send = true; var minTick = msg.MidiEvent.Min(x => x.Tick); if (instrument.LastSequencerTick > minTick) { instrument.LaggedBatches++; if (instrument.RespectMidiLimits) { if (instrument.LaggedBatches == (int)(MaxMidiLaggedBatches * (1 / 3d) + 1)) { attached.PopupMessage( Loc.GetString("instrument-component-finger-cramps-light-message")); } else if (instrument.LaggedBatches == (int)(MaxMidiLaggedBatches * (2 / 3d) + 1)) { attached.PopupMessage( Loc.GetString("instrument-component-finger-cramps-serious-message")); } } if (instrument.LaggedBatches > MaxMidiLaggedBatches) { send = false; } } if (++instrument.MidiEventCount > MaxMidiEventsPerSecond || msg.MidiEvent.Length > MaxMidiEventsPerBatch) { instrument.BatchesDropped++; send = false; } if (send || !instrument.RespectMidiLimits) { RaiseNetworkEvent(msg); } var maxTick = msg.MidiEvent.Max(x => x.Tick); instrument.LastSequencerTick = Math.Max(maxTick, minTick); }