private void UpdateLipSyncFrame(bool direct)
        {
            if (_isSinging)
            {
                var       currentTime = playerControl.relativeTime;
                LipDeform deform;

                if (direct)
                {
                    deform = _currLipDeform;
                }
                else
                {
                    if (currentTime < _lipSyncStartTime + LipTransitionTime)
                    {
                        var t = (currentTime - _lipSyncStartTime) / LipTransitionTime;
                        deform = LipDeform.Lerp(_prevLipDeform, _currLipDeform, t);
                    }
                    else
                    {
                        deform = _currLipDeform;
                    }
                }

                PutLipFrame(in deform);
            }
            else
            {
                PutLipFrame(LipDeform.Silence());
            }
        }
        private void OnScenarioEventEmitted(object sender, [NotNull] ScenarioSignalEventArgs e)
        {
            var ev = e.Data;

            _currentTick = ev.tick;

            switch (ev.type)
            {
            case (int)ScenarioDataType.SingControl: {
                if (ev.mute.Length >= placement.formationNumber)
                {
                    _isSinging = ev.mute[placement.formationNumber - 1];
                }

                break;
            }

            case (int)ScenarioDataType.LipSync: {
                if (_isSinging)
                {
                    var lipCode = (LipCode)ev.param;

                    if (lipCode.IsVoice())
                    {
                        _prevLipDeform    = _currLipDeform;
                        _currLipDeform    = LipDeform.FromLipCode(lipCode);
                        _lipSyncStartTime = playerControl.relativeTime;
                    }
                }

                break;
            }

            case (int)ScenarioDataType.FacialExpression: {
                if (ev.idol == placement.formationNumber - 1)
                {
                    ProcessFacialExpression(ev);
                }

                break;
            }

            default:
                break;
            }
        }
        private void InitStates()
        {
            _currentTick = 0;

            _isSinging = true;

            _currLipDeform = LipDeform.Silence();
            _prevLipDeform = LipDeform.Silence();

            Array.Clear(_currFacialExpression, 0, _currFacialExpression.Length);
            Array.Clear(_prevFacialExpression, 0, _prevFacialExpression.Length);
            _currFacialExprKey = 0;
            _prevFacialExprKey = 0;

            _prevEyeClosed = false;
            _currEyeClosed = false;

            Array.Clear(_currBlendShapeValues, 0, _currBlendShapeValues.Length);

            AnimateFace(true);
        }