首页 文章

反复播放30种音效

提问于
浏览
1

我正试图在Windows Phone 7上的XNA应用程序中同时播放大约30个钢琴音符 . 我已经导入并加载了下面的波形文件

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");

    }

每个声音效果文件都不到一秒钟,所以我试图同时播放所有声音效果文件 . 我使用每秒运行一次的for循环播放它们 . (所以在每个循环播放30个声音然后它继续播放并且每秒播放相同的30个声音)它可以正常工作几秒但突然停止播放任何声音(循环仍在工作)然后再次开始工作一次或两次并再次停止工作 . 它有时会产生一些不好的噪音,好像音频系统不能同时支持太多的声音 .

我不知道如何解决问题,如果它是缓冲问题或线程 .

1 回答

  • 0

    Nico Schertler是对的!我遇到了同样的问题并通过管理实例来修复它 . 通常当你玩soundeffect时,你总是得到实例!默认情况下,你不得不希望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 
            {
            }
        }
    }
    

相关问题