设置持续时间和播放声音连续存储在数组列表中
本文关键字:数组 列表 存储 连续 持续时间 播放声音 设置 | 更新日期: 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
的并发访问,或者为了播放它而复制它。