WIP: StartOffset
This commit is contained in:
@@ -16,6 +16,9 @@ namespace OCES.Audio
|
||||
public double BaseDspTime; // 读取Source Segment 的 dspTime
|
||||
public int SampleRate; // Source Segment 的采样率
|
||||
public bool Ready;
|
||||
public double SourceStartOffset;
|
||||
public double TargetAudioTime;
|
||||
public double StartPlayTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -41,10 +44,12 @@ namespace OCES.Audio
|
||||
CurrentContainerId = containerId;
|
||||
CurrentVolume = startVolume;
|
||||
CurrentHandle = this.m_player.Play(containerId);
|
||||
Debug.Log($"[ChannelFader] StartNew: containerId={containerId}, CurrentHandle={CurrentHandle}");
|
||||
}
|
||||
|
||||
public void StopCurrent()
|
||||
{
|
||||
Debug.Log($"[ChannelFader] StopCurrent called! CurrentHandle={CurrentHandle}, stack=\n{Environment.StackTrace}");
|
||||
StopHandle(CurrentHandle);
|
||||
CurrentHandle = null;
|
||||
CurrentContainerId = 0;
|
||||
@@ -84,7 +89,8 @@ namespace OCES.Audio
|
||||
/// 淡入分支:等待 FadeInOffset 后启动新音乐并淡入。
|
||||
/// 主协程 yield return 此分支,以便 DoTransition 在新音乐就绪后才结束。
|
||||
/// </summary>
|
||||
internal IEnumerator FadeInBranch(uint newContainerId, ITransitionConfig transition, SyncPointState syncState = null, Action onContainerStarted = null)
|
||||
internal IEnumerator FadeInBranch(uint newContainerId, ITransitionConfig transition, SyncPointState syncState = null,
|
||||
Action onContainerStarted = null)
|
||||
{
|
||||
if (transition?.FadeInOffset > 0f)
|
||||
{
|
||||
@@ -94,7 +100,7 @@ namespace OCES.Audio
|
||||
|
||||
if (newContainerId == 0)
|
||||
{
|
||||
CurrentHandle = null;
|
||||
CurrentHandle = null;
|
||||
CurrentContainerId = 0;
|
||||
if (syncState != null) syncState.Ready = true;
|
||||
yield break;
|
||||
@@ -102,43 +108,63 @@ namespace OCES.Audio
|
||||
|
||||
float startVolume = transition?.FadeInTime > 0f ? 0f : 1f;
|
||||
StartNew(newContainerId, startVolume);
|
||||
onContainerStarted?.Invoke();
|
||||
|
||||
// SyncPoint: 获取新 Segment 的 AudioSource 并设置 timeSamples
|
||||
if (syncState is { Mode: SyncPoint.SameAsCurrentSegment })
|
||||
switch (syncState)
|
||||
{
|
||||
AudioSource newSource = CurrentHandle?.GetFirstLeafSource();
|
||||
if (newSource && newSource.clip)
|
||||
// SyncPoint: 获取新 Segment 的 AudioSource 并设置 timeSamples
|
||||
case { Mode: SyncPoint.SameAsCurrentSegment }:
|
||||
{
|
||||
// 计算从读取Source Segment 到现在经过的 samples
|
||||
double elapsedSeconds = AudioSettings.dspTime - syncState.BaseDspTime;
|
||||
int elapsedSamples = (int)(elapsedSeconds * syncState.SampleRate);
|
||||
int targetTimeSamples = syncState.BaseTimeSamples + elapsedSamples;
|
||||
|
||||
if (targetTimeSamples < newSource.clip.samples)
|
||||
AudioSource newSource = CurrentHandle?.GetFirstLeafSource();
|
||||
if (newSource && newSource.clip)
|
||||
{
|
||||
newSource.timeSamples = targetTimeSamples;
|
||||
double targetAudioTime = syncState.TargetAudioTime;
|
||||
if (targetAudioTime > 0)
|
||||
{
|
||||
int targetTimeSamples = (int)(targetAudioTime * newSource.clip.frequency);
|
||||
if (targetTimeSamples >= 0 && targetTimeSamples < newSource.clip.samples)
|
||||
{
|
||||
newSource.timeSamples = targetTimeSamples;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError(
|
||||
$"[ChannelFader] SyncPoint: 目标 samples({targetTimeSamples}) 超出范围 [0, {newSource.clip.samples}),降级为 Start");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 新音频 samples({newSource.clip.samples}) <= 目标 samples({targetTimeSamples}),降级为 Start");
|
||||
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 未能获取新 Segment 的 AudioSource,降级为 Start");
|
||||
}
|
||||
syncState.Ready = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
case { Mode: SyncPoint.Start, StartPlayTime: > 0 }:
|
||||
{
|
||||
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 未能获取新 Segment 的 AudioSource,降级为 Start");
|
||||
AudioSource newSource = CurrentHandle?.GetFirstLeafSource();
|
||||
if (!newSource || !newSource.clip)
|
||||
yield break;
|
||||
|
||||
//在赋值的时候减过fade in time了
|
||||
int targetTimeSamples = (int)(syncState.StartPlayTime * newSource.clip.frequency);
|
||||
|
||||
if (targetTimeSamples >= 0 && targetTimeSamples < newSource.clip.samples)
|
||||
{
|
||||
newSource.timeSamples = targetTimeSamples;
|
||||
}
|
||||
break;
|
||||
}
|
||||
syncState.Ready = true;
|
||||
}
|
||||
|
||||
onContainerStarted?.Invoke();
|
||||
|
||||
|
||||
|
||||
if (transition?.FadeInTime > 0f)
|
||||
{
|
||||
yield return this.m_coroutineHost.StartCoroutine(
|
||||
FadeIn(CurrentHandle, transition.FadeInTime));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IEnumerator FadeOut(ContainerPlayHandle handle, float fromVolume, float duration)
|
||||
{
|
||||
//Debug.Log($"Fading out in {duration} seconds.");
|
||||
|
||||
Reference in New Issue
Block a user