2016-11-30 172 views
2

我正在玩一些C#,我正在編寫一個鋼琴應用程序。遍歷列表C#

每當用戶點擊鋼琴音符時,我將聲音(.wav)的位置存儲到列表中......以下是button1_MouseDown方法中的一些代碼。

if (e.Button == MouseButtons.Left) 
    { 
     SoundPlayer sp = new SoundPlayer(); 
     string musName = Convert.ToString(mk.pitch); 
     string loc = @"D:\OneDrive\Year 2 Semester 1\OOP\Notes-Sound files\Notes-Sound files\mapped\" + musName + ".wav"; 
     sp.SoundLocation = loc; 
     sp.Play(); 
     music.Add(loc); 
    } 

現在,我想遍歷循環播放所有點擊的鍵一次。我這樣做如下(當用戶點擊播放按鈕)

int k = 0; 
for (k = 1; k < music.Count; k++) 
{ 
    SoundPlayer sp = new SoundPlayer(); 
    sp.SoundLocation = music[k]; 
    sp.Play(); 
} 

的事情是,每當單擊播放按鈕按下唯一的最後一個音符是played.However,當我調試,不知何故,所有音符被播放。有任何想法嗎?

+0

嗨,我認爲你必須等待每一個音符演奏下一個 –

+0

我還假設喲不需額外需要每一個迭代中intialize一個新玩家以前玩過,但外循環。 – HimBromBeere

回答

5

根據MSDN,這是Play方法的描述:

播放使用一個新的線程.wav文件,如果它沒有被加載首先加載.wav文件。

所以每當你調用Play,這是異步運行,你的循環將繼續完成當前一個之前執行播放下一個wav文件。當你進行調試時,你可能在等待循環。

相反,嘗試使用PlaySync播放聲音同步

PS。此外,您可能要考慮使用的SoundPlayer的情況下,在你的列表,而不是文件名,以避免產生新的實例每次播放的wav文件時間:

List<SoundPlayer> music = new List<SoundPlayer>(); 
//... 

//In your first loop, you would add the SoundPlayer object 
music.Add(sp); 

//.. 
//Then when you're playing back: 
for (int k = 0; k < music.Count; k++) 
{ 
    music[k].PlaySync(); 
} 

注意的是,在for循環的指數應該在開始0以及

+0

這應該是公認的答案! +1 – nik0lias

+0

@KMoussa 我應該在哪裏放置 'var music = new List ();' – Axel

+0

@AxelAzzopardi取代您當前聲明的'strings'音樂列表/數組' – KMoussa

0

你的主要問題是,票據全部發揮,但隨後的音符真正開始打第一個完成之前。因此你只聽到最後一個。

使用PlaySync,它會同步播放聲音,如果您出於某種原因必須遍歷List<>並說,請在播放前檢查每個項目(至少如果您將SoundPlayer派生到另一個類,以便它實際上有東西要檢查),您可以使用支票進行PlaySync調用。

SoundPlayer sp = new SoundPlayer(); 

foreach(var note in music) 
{ 
    sp.SoundLocation = note; 
    bool everythingIsFine = false; 

    // Logic for everythingIsFine; 

    if(everythingIsFine){ 
     sp.PlaySync(); 
    } 
}