我在我的应用程序中经常看到一个错误被报告。我知道它发生在哪里,我只是不知道为什么。这个应用程序播放声音效果(不是背景音乐),我使用的是Xna.Audio,我有定时调用FrameworkDispatcher.Update()的计时器。我使用的是SoundEffect.CreateInstance,所以我可以使用音效循环。似乎在更改卷时会发生错误。但我不知道为什么。有已知的例子可以失败吗?
函数:偏移
xxx_RaiseException:32
WatsonUnhandledManagedException::300
Dbg_NotifyManagedException::136
FirstPassException::1044
TransitionStub:0
Microsoft.Xna.Framework.Helpers.ThrowExceptionFromErrorCode::76
Microsoft.Xna.Framework.Audio.SoundEffectInstance.set_Volume::232
Microsoft.Xna.Framework.Audio.SoundEffectInstance..ctor::232
Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance::192个
AgiliTrain.PhoneyTools.Media.SoundEffectPlayer..ctor::96
WildSafari.ClassicModeGame.animalVisibleTimer_Tick:344
...snip...
对于那些询问者,这里有更多的代码。SoundEffectPlayer接受一个SoundEffect,创建一个实例,并启动XNA FrameworkDispatcher (通过GameTimer)。这段代码取自PhoneyTools,因此如果需要更多上下文,请查看codeplex项目。当我想要发挥效果时,我只需要一个新的SoundEffectPlayer,并传递我想要的。
public class SoundEffectPlayer
{
GameTimer _xnaTimer = new GameTimer();
SoundEffectInstance _effect = null;
public float _duration;
public SoundEffectPlayer(SoundEffect effect, bool loop)
{
_effect = effect.CreateInstance();
_effect.IsLooped = loop;
_duration = (float)effect.Duration.TotalSeconds;
}
public void Play(float volume)
{
_xnaTimer.Start();
_effect.Play();
_effect.Volume = volume;
}
public void Stop()
{
_effect.Stop(true);
_xnaTimer.Stop();
}
}
public class GameTimer
{
DispatcherTimer _timer = new DispatcherTimer()
{
Interval = TimeSpan.FromMilliseconds(50),
};
public GameTimer()
{
_timer.Tick += new EventHandler(_timer_Tick);
}
void _timer_Tick(object sender, EventArgs e)
{
FrameworkDispatcher.Update();
}
public void Start()
{
if (!_timer.IsEnabled) _timer.Start();
}
public void Stop()
{
if (_timer.IsEnabled) _timer.Stop();
}
}发布于 2011-08-05 21:21:49
想帮忙,虽然我没有有效的解决办法.
SoundEffectInstance的setter属性并不像人们可能认为的那样简单:
set
{
lock (this.voiceHandleLock)
{
if (this.IsDisposed)
{
throw new ObjectDisposedException(base.GetType().Name, FrameworkResources.ObjectDisposedException);
}
if ((value < 0f) || (value > 1f))
{
throw new ArgumentOutOfRangeException("value");
}
Helpers.ThrowExceptionFromErrorCode(SoundEffectUnsafeNativeMethods.SetVolume(this.voiceHandle, value));
this.currentVolume = value;
}
}从根本上说,我们要找的是前一段时间。
如果来自SoundEffectUnsafeNativeMethods.SetVolume的调用返回小于0的任何代码,则将触发所得到的异常。
下面是不安全方法内部发生的情况:
public static unsafe int modopt(IsLong) SetVolume(uint soundEffectInstanceHandle, float volume)
{
lock (SoundEffectSubsystemSyncObject)
{
if ((soundEffectInstanceHandle != 0) && (soundEffectInstanceHandle != uint.MaxValue))
{
CHandleTable* tablePtr = ?g_pTable@CHandleTable@@0PAV1@A;
KernelSoundEffectInstance* instancePtr = CHandleTable.LookUp<class Microsoft::Xna::Framework::Audio::KernelSoundEffectInstance>((CHandleTable modopt(IsConst)* modopt(IsConst) modopt(IsConst)) ?g_pTable@CHandleTable@@0PAV1@A, soundEffectInstanceHandle, 0);
if (instancePtr == null)
{
return -2147024809;
}
return **(((int*) instancePtr))[0x34](instancePtr, volume);
}
return -2147024809;
}
}您可以尝试将_effect.CreateInstance的创建围绕在try...catch中,并重新抛出一个更全面和有用的异常,该异常将包含您要创建的SoundEffect对象的信息(基本上可以记录其字段的所有值以供检查)。(不确定您从MS获得的只是堆栈跟踪或实际的异常消息)。
在WP7上,设置音量的调用似乎指向了某个OS指针表,该表在幕后发挥了一些神奇的作用,并在这个表中寻找声音效果句柄。
如果由于某种原因没有找到它或者类似的东西(不知道为什么,也许我们可以和XNA开发人员一起使用它),它会抛出您正在获得的异常。
我知道这不是一个解决办法,但也许这是朝着正确方向迈出的一步。
发布于 2011-08-02 08:55:03
通常,只要您构建了XNA兼容层(details 这里),就不应该为您所描述的情况抛出异常。
然而,我注意到您正在使用PhoneyTools.Media.SoundEffectPlayer -为什么?这可能是你处境中问题的原因。
而且,您似乎有不明确的引用-- effect和_effect --您在播放内容时使用的是哪一种?
https://stackoverflow.com/questions/6885298
复制相似问题