2011-04-21 122 views
4

我正在创建一个WP7应用程序,需要在循环播放的背景音乐上播放各种音效(按下按钮时)。背景音乐通过按下按钮1启动并循环播放。当我按下按钮3(触发声音效果)时,首次按下后,音效就会叠加在背景音乐上。但是,当我再次按下按钮3时,背景音乐停止。我无法弄清楚为什么会发生这种情况!?我已经粘贴了以下代码的相关部分。将不胜感激任何帮助。同时播放两个声音c#

public partial class MainPage : PhoneApplicationPage 
{ 
    SoundEffect soundEffect; 
    Stream soundfile; 

    // Constructor 
    public MainPage() 
    { 
     InitializeComponent(); 
    } 



    static protected void LoopClip(SoundEffect soundEffect) 
    { 
     { 
     SoundEffectInstance instance = soundEffect.CreateInstance(); 
     instance.IsLooped = true; 
     FrameworkDispatcher.Update(); 
     instance.Play(); 
     } 
    } 

    public void PlaySound(string soundFile) 
    { 
     using (var stream = TitleContainer.OpenStream(soundFile)) 
     { 

      var effect = SoundEffect.FromStream(stream); 
      effect.Play(); 
     } 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     soundfile = TitleContainer.OpenStream("BackgroundMusic.wav"); 
     soundEffect = SoundEffect.FromStream(soundfile); 
     LoopClip(soundEffect); 
    } 


    private void button3_Click(object sender, RoutedEventArgs e) 
    { 
     PlaySound("sound3.wav"); 
    } 

} 

}

+0

您是否尝试线程或后台工作? – Marshal 2011-04-21 16:44:02

+0

这与Java中发生的事情完全相反...... – JavaAndCSharp 2011-05-23 18:47:17

回答

4

这应该工作,如果你总是用实例工作,所以你的代码改成这样,它应该清理的问题:

public partial class MainPage : PhoneApplicationPage 
{ 

    SoundEffectInstance loopedSound = null; 

    // Constructor 
    public MainPage() 
    { 
     InitializeComponent(); 
    } 

    static protected void LoopClip(SoundEffect soundEffect) 
    { 
     loopedSound = soundEffect.CreateInstance(); 
     loopedSound.IsLooped = true; 
     loopedSound.Play(); 
    } 

    public void PlaySound(string soundFile) 
    { 
     SoundEffect sound = SoundEffect.FromStream(Application.GetResourceStream(new Uri(soundFile, UriKind.Relative)).Stream); 
     SoundEffectInstance instance = sound.CreateInstance(); 
     instance.Play(); 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     SoundEffect sound = SoundEffect.FromStream(Application.GetResourceStream(new Uri(@"BackgroundMusic.wav", UriKind.Relative)).Stream); 
     LoopClip(sound); 
    } 


    private void button3_Click(object sender, RoutedEventArgs e) 
    { 
     PlaySound("sound3.wav"); 
    } 

} 

上面的例子假设你的声音文件设置与生成操作=内容和位于顶级目录中。

+0

非常感谢!不幸的是,我只是尝试了你的代码,我有相同的原始问题 - button3被点击超过2次后,背景音乐停止(第一次点击button3就可以正常工作..) – sv77 2011-04-21 20:49:35

+0

@ sv77你是对的。我跑了我的代码,并重复你的问题。我已经更新了我的代码,现在它应该适合你。关键是要保持循环的soundeffectinstance在它自己的变量中。 – theChrisKent 2011-04-21 21:00:49

+0

现在完美工作,很有意义。谢谢! – sv77 2011-04-21 21:32:18

0

你需要从一个单独的线程发挥各自的声音。

这里似乎正在发生的是,不同的Play方法调用互相干扰,因为它们在同一个线程中。

试着把背景音乐放在一个单独的线程中,看看是否解决了你在问题中提到的问题。如果是这样,也将其他人分开。

+0

谢谢。请给我一些关于如何开始一个新线程的更多细节?我以前没有做过,似乎也无法让它编译。 [Thread backgroundThread = new Thread(new ThreadStart(LoopClip))]; – sv77 2011-04-21 17:47:37

+0

从你的评论中的代码,你应该改用'Thread backgroundThread = new Thread(new ParameterizedThreadStart(LoopClip))'或类似的东西,并使用'ParameterizedThreadStart'提供的参数传入参数('soundEffect')。 – 2011-04-21 19:13:35

+0

仍有问题:“LoopClip没有与委托相匹配的过载。”我能够使用ThreadStart调用一个非参数化的函数,然后调用LoopClip。然而,当程序运行时,我仍然有相同的原始问题。我应该在button1_Click或其他地方创建一个新线程吗? – sv77 2011-04-21 20:19:28