gpt4 book ai didi

audio - 在 XNA/Monogame 中更改音调时,声音文件的播放持续时间如何变化?

转载 作者:行者123 更新时间:2023-12-01 19:34:05 27 4
gpt4 key购买 nike

使用 XNA 中的 SoundEffects 类(或 XNA 的替代实现,如 MonoGame 或 FNA),声音效果具有一定的播放持续时间,等于存储在以下位置的声音文件的长度:

SoundEffect.Duration

但是,当播放的音调发生变化(在 1 和 -1 之间)时,这也会改变播放的有效持续时间(例如,较低的音调 = 较慢的播放),从而使 SoundEffect.Duration 中的值变得无用。

根据播放音调计算持续时间的数学表达式是什么?

我想要做的是在例如播放期间平滑地淡出声音效果。播放的最后一秒。但为了在最后一秒线性降低音量,我需要知道播放何时真正结束,从而确定其(音调调制的、实际的)持续时间。

最佳答案

我为此写了一个扩展方法,不是 100% 准确,但非常接近:

public static TimeSpan GetEstimatedDuration(this SoundEffect sfx, float pitch)
{
return TimeSpan.FromMilliseconds(sfx.Duration.TotalMilliseconds * (0.2514 * Math.Pow(pitch, 2) - 0.74 * pitch + 1));
}
<小时/>

背景

我也很不幸地找到了这背后的“真正”数学,所以我写了一个像这样的小函数:

private void DurationTest(string sfxAssetName)
{
for (float pitch = -1; pitch <= 1; pitch += 0.5f)
{
var sfx = this.Content.Load<SoundEffect>(sfxAssetName);
using (var instance = sfx.CreateInstance())
{
instance.Pitch = pitch;
//var estimatedDuration = sfx.GetEstimatedDuration(pitch);
instance.Play();
var sw = System.Diagnostics.Stopwatch.StartNew();
while (instance.State == SoundState.Playing)
{ }
sw.Stop();
var duration = sw.Elapsed;
System.Diagnostics.Debug.WriteLine("sfx={0} | pitch={1:0.00} | duration={2:0.00}secs", sfxAssetName, pitch, duration.TotalSeconds);
//System.Diagnostics.Debug.WriteLine("sfx={0} | pitch={1:0.00} | estimated={2:0.00}secs | actual={3:0.00}secs", sfxAssetName, pitch, estimatedDuration.TotalSeconds, duration.TotalSeconds);
}
}
}
// output
sfx=bombfuse | pitch=-1.00 | duration=3.89secs
sfx=bombfuse | pitch=-0.50 | duration=2.75secs
sfx=bombfuse | pitch= 0.00 | duration=1.95secs
sfx=bombfuse | pitch= 0.50 | duration=1.38secs
sfx=bombfuse | pitch= 1.00 | duration=0.98secs

利用这些数据,我构建了一个包含多项式趋势线的图表,并在 Excel 中显示公式,这是您在 GetEstimatedDuration 中看到的计算结果。然后我推进了 DurationTest 进行比较(上面的注释行) - 输出如下:

// output bombfuse (short)
sfx=bombfuse | pitch=-1.00 | estimated=3.88secs | actual=3.89secs
sfx=bombfuse | pitch=-0.50 | estimated=2.79secs | actual=2.76secs
sfx=bombfuse | pitch= 0.00 | estimated=1.95secs | actual=1.95secs
sfx=bombfuse | pitch= 0.50 | estimated=1.35secs | actual=1.38secs
sfx=bombfuse | pitch= 1.00 | estimated=1.00secs | actual=0.98secs
// output dreiklang (long)
sfx=dreiklang | pitch=-1.00 | estimated=24.67secs | actual=24.77secs
sfx=dreiklang | pitch=-0.50 | estimated=17.75secs | actual=17.52secs
sfx=dreiklang | pitch= 0.00 | estimated=12.39secs | actual=12.39secs
sfx=dreiklang | pitch= 0.50 | estimated= 8.58secs | actual= 8.76secs
sfx=dreiklang | pitch= 1.00 | estimated= 6.33secs | actual= 6.20secs

希望这对您有所帮助,请随意根据您自己的需要和比较使用这些方法。

关于audio - 在 XNA/Monogame 中更改音调时,声音文件的播放持续时间如何变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34827986/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com