我有一个由MusicNotes填充的数组。每个MusicNote都是一个具有它属性的对象,例如音高和持续时间。持续时间是使用MusicNote类中的计时器创建的。
问题在于,当我遍历数组并播放所有声音时,每个MusicNote的持续时间都会丢失,并且它将播放整个wav文件(对于每个音符)。
我知道问题与计时器有关,我知道它可能与MusicNote中的Play()方法有关,但我对如何修复它没有任何想法。我已经发布了与此问题相关的代码。
public class MusicNote : PictureBox
{
Timer tmr1 = new Timer();
int tmr1duration;
public SoundPlayer sp = new SoundPlayer();
public Timer tmr = new Timer();
public int pitch; //The no. of the music key (e.g. the sound freuency).
public int noteDuration; //Shape of note.
public string noteShape;
static int xLoc = 0;
int yLoc = 100;
public MusicNote(int iPitch, int iNoteDuration)
: base()
{
pitch = iPitch;
noteDuration = iNoteDuration;
Size = new Size(40, 40);
this.BackColor = Color.Transparent;
this.MouseClick += new MouseEventHandler(MusicNote_MouseClick);
this.MouseDown += new MouseEventHandler(MusicNote_MouseDown);
this.MouseUp += new MouseEventHandler(MusicNote_MouseUp);
tmr1.Tick += new EventHandler(tmr1_Tick);
tmr.Tick += new EventHandler(ClockTick);
}
public void ShowNote()
{
if (this.noteDuration == 1) noteShape = "Quaver.png";
if (this.noteDuration == 4) noteShape = "Crotchet.png";
if (this.noteDuration == 7) noteShape = "minim.png";
if (this.noteDuration == 10) noteShape = "DotMin.png";
if (this.noteDuration == 12) noteShape = "SemiBreve.png";
this.BackgroundImage = Image.FromFile(noteShape);
this.BackColor = Color.Transparent;
Location = new Point(xLoc, yLoc);
xLoc = xLoc + 40;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
public void Play()
{
sp.SoundLocation = this.pitch + ".wav";
sp.Play();
//Timer to play the duration
this.tmr.Interval = 100 * this.noteDuration;
this.tmr.Start();
}
void ClockTick(object sender, EventArgs e)
{
sp.Stop();
tmr.Stop();
}
private void MusicNote_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Play();
}
}
}
}
这是我有阵列的课程......
public class MusicStaff: Panel
{
public ArrayList musicNotes = new ArrayList(); //Array to store the Music Notes.
SoundPlayer sp = new SoundPlayer();
public void AddNote(MusicNote newNote) //Method to add the notes.
{
musicNotes.Add(newNote);
}
public int ListSize()
{
return musicNotes.Count; //Returns the size of the list.
}
public void PlayAll()
{
foreach (MusicNote m in musicNotes)
{
m.Play();
}
我已从类中删除了一些未重新插入问题的代码,因此问题不会太长。任何帮助如何解决这个问题将不胜感激。 TKS。
答案 0 :(得分:0)
尝试这样的事情:
public void PlayAll()
{
foreach (MusicNote m in musicNotes)
{
m.sp.Stop();
m.sp.PlaySync();
Thread.Sleep(m.noteDuration); //duration should be in milliseconds
}
}
如果这项工作正常,您可以完全移除计时器。
我建议你研究在C#中使用Properties来不让字段公开。 顺便说一下,两年前我做了这个任务:)