设置持续时间和播放声音连续存储在数组列表中

本文关键字:数组 列表 存储 连续 持续时间 播放声音 设置 | 更新日期: 2023-09-27 18:19:02

我有下面的Play方法来播放存储在数组列表中的音符:

public void Play(Duration d){

            int duration = 1;
            if (d == Duration.SemiBreve)
            {
                duration = 16;
            }
            else if (d == Duration.DotMin)
            {
                duration = 10;
            }
            else if (d == Duration.minim)
            {
                duration = 8;
            }
            else if (d == Duration.Crotchet)
            {
                duration = 4;
            }
            else if (d == Duration.Quaver)
            {
                duration = 2;
            }
            else if (d == Duration.SemiQuaver)
            {
                duration = 1;
            }
            player = new SoundPlayer();
            player.SoundLocation = "pathToLocation";

            //set timer
            time = new Timer();
            time.Tick += new EventHandler(clockTick);
            time.Interval = duration * 150;
            player.Play();
            time.Start();
        }

当我用按钮调用方法时:

private void PlayButton_Click(object sender, EventArgs e)
{
        //Loops through the collection and plays each note one after the other
        foreach (MusicNote music in this.staff.Notes)
        {
            music.Play(music.Dur)
        }
    }

只播放最后一个音符。使用PlaySync(),所有音符都被播放,但持续时间不被识别。我也尝试使用线程,像这样:

foreach (MusicNote music in this.staff.Notes)
            {
                Thread t = new Thread(playMethod=>music.Play(music.Dur));  
                t.Start();
                t.Join();
            }

但它也不起作用。有什么建议,我怎么能让文件播放连续与PlaySync,但使用他们的设置持续时间?

设置持续时间和播放声音连续存储在数组列表中

你不用在任何地方等待计时器。所以在实践中,所有的音符几乎是同时演奏的,导致只有最后一个音符是有效的。


更新:使用System.Timers.Timer类的方法是为Elapsed事件注册一个处理程序,并在事件处理程序中逐个播放音符。这样可以避免UI冻结。

另一个选择是在后台线程中播放,并使用Thread.Sleep等待。在这里,你必须确保线程根据UI的状态被停止(即使用关闭当前对话框等)。

在任何一种情况下,为了避免竞争条件,您都必须解决对staff.Notes的并发访问,或者为了播放它而复制它。