/// <summary> /// SectionPlayer 추가 /// </summary> /// <param name="player"></param> /// <param name="layermixers"></param> /// <param name="sectionMixerCtrl"></param> public void AttachSectionPlayer(SectionPlayer player, IAutomationControl sectionMixerCtrl) { // 적당한 idx 찾기 int idx = 0; for (; idx < c_playerCount; idx++) { if (m_secplayer[idx] == null) { break; } } if (idx >= c_playerCount) { throw new System.InvalidOperationException(); } // m_secplayer[idx] = player; m_secplayerCtrl[idx] = sectionMixerCtrl; }
SectionPlayer CreateSectionPlayer(UnityEngine.Audio.AudioMixer[] layermixers, IAutomationControl transCtrl, IAutomationControl [] tensionCtrl) { var player1 = gameObject.AddComponent<LibSequentiaPlayer>(); player1.SetTargetMixers(layermixers); var player2 = gameObject.AddComponent<LibSequentiaPlayer>(); player2.SetTargetMixers(layermixers); var secPlayer = new SectionPlayer(this); secPlayer.SetPlayerComponents(player1, player2); secPlayer.SetTransitionAutomationTarget(transCtrl); secPlayer.SetTensionAutomationTargets(tensionCtrl); return secPlayer; }
TransitionTimeInfo DoProgress(SectionPlayer.TransitionType ttype, bool reverse, int sectionIdxOverride = int.MinValue) { // 트랜지션을 해도 괜찮은 상황인지 체크 if (sidePlayer.isReadyOrFinished) // 다른쪽 플레이어가 재생중이 아니거나 루프 종료된 경우 스위칭. 새로 재생할 플레이어가 currentPlayer가 된다 { SwitchPlayer(); if (sectionIdxOverride == int.MinValue) // 다음 섹션 idx를 오버라이드하지 않은 경우엔 자동으로 +1 { m_sectionIdx++; } else { // 오버라이드한 경우 m_sectionIdx = sectionIdxOverride; } //Debug.Log("switch player. section idx : " + m_sectionIdx); } // 트랜지션 시간 구하기 double transitionTime = CalcSectionTransitionTimeLength(m_sectionIdx, ttype); // 여기서부터는 sidePlayer => 기존에 재생중이던 플레이어가 됨 TransitionTimeInfo tinfo = new TransitionTimeInfo(); tinfo.transitionStart = -1; tinfo.transitionEnd = -1; // 기존 재생중이던 플레이어가 트랜지션 진행중이지 않고, 좀더 상위의 트랜지션을 걸 때 if (!sidePlayer.isOnTransition && (int)ttype > (int)sidePlayer.currentEndTransition) { //Debug.LogWarningFormat("transition check - m_sectionIdx : {0}, m_suppressProgress : {1}", m_sectionIdx, m_suppressProgress); if(((!reverse && m_sectionIdx > 0) || (reverse && m_sectionIdx < m_track.sectionCount - 1)) && !m_suppressProgress && !sidePlayer.isReadyOrFinished) // 처음 섹션이 아니고 재생을 끝내는 경우도 아닐 때만 { tinfo.transitionStart = sidePlayer.FadeoutSection(ttype, transitionTime); //Debug.LogWarning("fadeout triggered"); } else { // 그 외의 경우엔 전부 다음 비트에 트랜지션 시작하는 것으로 tinfo.transitionStart = m_clock.CalcNextSafeBeatTime(); } if ((!reverse && m_sectionIdx < m_track.sectionCount) || (reverse && m_sectionIdx >= 0)) // 더 진행할 섹션이 있는 경우에만 { //Debug.LogWarning("start : " + ttype); currentPlayer.StartSection(m_track.GetSection(m_sectionIdx), m_clock, ttype, tinfo.transitionStart); tinfo.transitionEnd = currentPlayer.firstLoopStartDspTime; } else { // TODO : 필요할지는 모르겠는데, 새 섹션이 시작되지 않는 경우에도 올바른 트랜지션 종료 타이밍을 계산해서 집어넣게 수정해야 할지도... tinfo.transitionEnd = tinfo.transitionStart; } // 트랜지션 추적 (step을 올바르게 업데이트하기 위해서) m_curTransition = ttype; StartTransitionMonitor(tinfo); } else { Debug.Log(string.Format("sidePlayer.isOnTransition : {0}, sidePlayer.currentEndTransition : {1}", sidePlayer.isOnTransition, sidePlayer.currentEndTransition)); } return tinfo; }
/// <summary> /// 특정 세션이 전환되어 들어올 때 걸리는 시간을 계산 /// </summary> /// <param name="sectionindex"></param> /// <param name="ttype"></param> /// <returns></returns> public double CalcSectionTransitionTimeLength(int sectionindex, SectionPlayer.TransitionType ttype) { int trbeats = 4; if (sectionindex < m_track.sectionCount && sectionindex >= 0) // 다음에 올 섹션이 있다면 해당 섹션의 앞쪽 부분을 기준으로 계산 { var nextsec = m_track.GetSection(sectionindex); trbeats = nextsec.beatStart; if (ttype == SectionPlayer.TransitionType.Manual) // 강제 전환은 fillin 앞부분이 잘림 { trbeats -= nextsec.beatFillIn; } else if (ttype == SectionPlayer.TransitionType.Instant) // 즉시 전환은 전환시간 없음 { trbeats = 0; } } return m_clock.CalcBeatTimeLength(trbeats); }
/// <summary> /// SectionPlayer 추가 /// </summary> /// <param name="player"></param> /// <param name="layermixers"></param> /// <param name="sectionMixerCtrl"></param> public void AttachSectionPlayer(SectionPlayer player, IAutomationControl sectionMixerCtrl) { // 적당한 idx 찾기 int idx = 0; for(; idx < c_playerCount; idx++) { if (m_secplayer[idx] == null) break; } if (idx >= c_playerCount) throw new System.InvalidOperationException(); // m_secplayer[idx] = player; m_secplayerCtrl[idx] = sectionMixerCtrl; }