Пытаюсь помочь, хотя у меня нет действительного решения ...
Свойство setter для SoundEffectInstance не так просто, как может показаться:
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 и rethrow более подробное и полезное исключение, которое будет содержать, например, информацию об объекте SoundEffect, который вы пытаетесь создать (в основном вы можете запишите все значения его поля для проверки. (не уверен, что то, что вы получаете от MS, - это только трассировка стека или фактическое сообщение об исключении).
Похоже, что в WP7 вызов для установки громкости переходит к некоторой таблице указателей ОС, которая делает некоторые закулисные действия и ищет дескриптор звукового эффекта в этой таблице.
Если по какой-то причине он не найден или что-то в этом роде (не знаю почему, может быть, мы можем взять его с разработчиками XNA), он выдаст это исключение, которое вы получаете.
Я знаю, что это не решение, но, возможно, это шаг в правильном направлении.