同时重复播放30个音效
本文关键字:30个 音效 播放 | 更新日期: 2023-09-27 18:13:48
我试图在Windows Phone 7上的XNA应用程序中同时播放大约30个钢琴音符。我已经导入并加载了如下的wave文件
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
sound3 = Content.Load<SoundEffect>("1");
sound5 = Content.Load<SoundEffect>("3");
sound6 = Content.Load<SoundEffect>("4");
sound7 = Content.Load<SoundEffect>("5");
sound8 = Content.Load<SoundEffect>("6");
}
每个音效文件的播放时间都不到1秒,所以我尽量同时播放所有的音效文件。我使用每秒运行一次的for循环播放它们。(每次循环播放30个声音,然后继续播放,每秒播放同样的30个声音)它在几秒钟内正常工作,但突然停止播放任何声音(循环仍在工作),然后再次开始工作一两次,再次停止工作。它有时也会发出一些不好的噪音,好像音频系统不能同时播放太多的声音。
我不知道如何解决这个问题,如果它是一个缓冲区问题或线程
Nico Schertler是对的!我遇到过同样的问题,并通过管理实例解决了这个问题。通常当你播放音效时,你总是得到实例!默认情况下,你必须希望XNA/Monogame会关心它,但事实并非如此。当你有太多的活动实例时(即使是停止的),你会得到休息,噪音,甚至沉默。
我为我所有的声音效果保存矩形数组,每个最多4个实例,如果我有一个声音的实例,我想要播放而不是创建,我会停止最老的(按时间戳),播放它并记住当前的时间戳。
请看下面的代码:
private const int MAX_INST_OF_ONE_SOUND = 4;
private SoundEffectInstance[][] sndInstArray = null;
private float[][] sndInstTimes = null;
public init()
{
sndArray = new SoundEffect[SoundsSchema.sounds.Length];
sndInstArray = new SoundEffectInstance[SoundsSchema.sounds.Length][];
sndInstTimes = new float[SoundsSchema.sounds.Length][];
for (int i = 0; i < SoundsSchema.sounds.Length; i++)
{
try
{
sndArray[i] = content.Load<SoundEffect>(SoundsSchema.sounds[i]);//SoundsSchema is string list holder class
}
catch (System.Exception)
{
}
sndInstArray[i] = new SoundEffectInstance[MAX_INST_OF_ONE_SOUND];
sndInstTimes[i] = new float[MAX_INST_OF_ONE_SOUND];
}
}
private SoundEffectInstance getValidInstance(int sound)
{
if (sound < 0 || sound > sndInstArray.Length)
return null;
SoundEffectInstance inst = null;
for (int i = 0; i < MAX_INST_OF_ONE_SOUND; i++)
{
if (sndInstArray[sound][i] == null || (sndInstArray[sound][i] != null && sndInstArray[sound][i].IsDisposed))
{
sndInstArray[sound][i] = sndArray[sound].CreateInstance();
sndInstTimes[sound][i] = MyEngine.CurTime;
inst = sndInstArray[sound][i];
break;
}
}
if (inst == null)
{
float min_time = float.MaxValue;
int ind = -1;
for (int i = 0; i < MAX_INST_OF_ONE_SOUND; i++)
{
if (sndInstArray[sound][i] != null && sndInstTimes[sound][i] < min_time)
{
min_time = sndInstTimes[sound][i];
ind = i;
}
}
if (ind == -1)
ind = 0;
if (sndInstArray[sound][ind].IsDisposed)
sndInstArray[sound][ind] = sndArray[sound].CreateInstance();
else
{
try
{
sndInstArray[sound][ind].Stop();
}
catch
{}
}
sndInstTimes[sound][ind] = MyEngine.CurTime;
inst = sndInstArray[sound][ind];
}
return inst;
}
public virtual void playSound(int sound, float volume, float panoram, bool loop)
{
if (sound < 0 || sound > sndArray.Length)
return null;
if (!mMuted && mVolume > 0)
{
SoundEffectInstance sndinst = getValidInstance(sound);
if (sndinst == null)
return null;
try
{
sndinst.IsLooped = loop;
sndinst.Pan = panoram;
sndinst.Volume = mVolume * vol;
sndinst.Play();
}
catch
{
}
}
}