2013-10-17 21 views
1

iam製作一個應用程序,當一個鍵被關閉時播放聲音,當鍵被釋放時聲音立即停止。Key down無限循環

我發現的問題是,如果按下某個鍵,它會播放它的第一個毫秒,然後無限循環直到您釋放該鍵。

代碼IAM目前使用的是以下幾點:

 public class Foo 
     { 

      public static int GetStream1(string path) 
      { 
       return Bass.BASS_StreamCreateFile(path, 0, 0, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_PRESCAN); 
      } 
      public static int GetStream2(string path) 
      { 
       return Bass.BASS_StreamCreateFile(path, 0, 0, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_PRESCAN); 
      } 
     } 

     protected override void OnKeyDown(KeyEventArgs e) 
     { 
      Bass.BASS_Init(1, 44100, BASSInit.BASS_DEVICE_DEFAULT, this.Handle); 
      Bass.BASS_Init(2, 44100, BASSInit.BASS_DEVICE_DEFAULT, this.Handle); 


       if (e.KeyCode == Keys.D1) 
       { 
        if (beatload1.Text == "Waiting 01.wav") 
        { 
         MessageBox.Show("No beat loaded"); 
         return; 
        } 
        Beat1.Image = Beatpadpc.Properties.Resources.white_square_button; 
        try 
        { 
         Bass.BASS_SetDevice(1); 
         Bass.BASS_ChannelPlay(Foo.GetStream1(path1.Text), false); 
        } 
        catch (FileNotFoundException) 
        { 
         MessageBox.Show("File has been moved." + "\n" + "Please relocate it now!"); 
        } 
       } 

       if (e.KeyCode == Keys.D2) 
       { 
        if (beatload2.Text == "Waiting 02.wav") 
        { 
         MessageBox.Show("No beat loaded"); 
         return; 
        } 
        Beat2.Image = Beatpadpc.Properties.Resources.white_square_button; 
        try 
        { 
         Bass.BASS_SetDevice(2); 
         Bass.BASS_ChannelPlay(Foo.GetStream2(path2.Text), false); 
        } 
        catch (FileNotFoundException) 
        { 
         MessageBox.Show("File has been moved." + "\n" + "Please relocate it now!"); 
        } 
       } 
     } 

     private void Window_KeyUp(object sender, KeyEventArgs e) 
     { 
     if (e.KeyCode == Keys.D1) 
      { 
       Beat1.Image = Beatpadpc.Properties.Resources.black_square_button; 
       Bass.BASS_StreamFree(Foo.GetStream1(path1.Text)); 
       Bass.BASS_SetDevice(1); 
       Bass.BASS_Free(); 
      } 
      if (e.KeyCode == Keys.D2) 
      { 
       Beat2.Image = Beatpadpc.Properties.Resources.black_square_button; 
       Bass.BASS_StreamFree(Foo.GetStream2(path2.Text)); 
       Bass.BASS_SetDevice(2); 
       Bass.BASS_Free(); 
      } 
} 

那麼,有沒有在他們得到循環永遠在同一時間玩1個或多個聲音的方法嗎?

+0

何塞,當你決定你有一個你滿意的答案時,你應該把它標記爲在左邊接受的答案,在表決之下投票和投票下箭頭。只有你,原始的海報,可以標記答案被接受。另外,當你這樣做的時候,它給了這個人更多的聲望點數(與你的名字相關的點數,你現在的數字是63) – philologon

回答

1

私有成員添加到您的類:

private Dictionary<Key, Boolean> KeyIsDown; 

在你的onkeydown方法,設置KeyIsDown(currentKey)= TRUE;在你的OnKeyUp方法中,設置KeyIsDown(currentKey)= false;

然後爲onIdle事件添加一個委託。每當調用委託時,使用if語句而不是foreach檢查KeyIsDown中的每個鍵,並根據KeyIsDown(aKey)是true還是false來處理每個鍵。

因爲我沒有你的代碼引用的Bass類,所以我只能近似看它應該是什麼樣子。你將不得不自己做出真正的改編。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Windows.Input; 

namespace WinformExcercise1 
{ 
    public partial class Form1 : Form 
    { 
     private Dictionary<Keys, bool> keyIsDown = new Dictionary<Keys,bool>(); 
     private Timer timer; 
     private int stream1; 

     public Form1() 
     { 
     InitializeComponent(); 

     keyIsDown.Add(Keys.J, false); 
     keyIsDown.Add(Keys.K, false); 
     keyIsDown.Add(Keys.L, false); 

     setupPlayer(); 
     this.KeyPreview = true; 
     } 

     private void setupPlayer() 
     { 
     // Bass.BASS_SetDevice(1); 
     stream1 = Foo.GetStream2(path1.Text); 
     // all code that is called once for setting things up goes here 
     } 

     private void Form1_KeyDown(object sender, KeyEventArgs e) 
     { 
     if (true == keyIsDown.ContainsKey(e.KeyCode)) 
     { 
      keyIsDown[e.KeyCode] = true; 
     } 
     } 

     private void Form1_KeyUp(object sender, KeyEventArgs e) 
     { 
     if (true == keyIsDown.ContainsKey(e.KeyCode)) 
     { 
      keyIsDown[e.KeyCode] = false; 
     } 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
     // This makes the computer constantly call the playKeys method 
     timer = new Timer(); 
     timer.Interval = 1000; 
     timer.Tick += new EventHandler(playKeys); 
     timer.Enabled = true; 
     } 

     private void playKeys(Object source, EventArgs e) 
     { 
     // You have to add the next 8 lines once for each key you are watching 
     // What I have here only does something for the J key. 
     if (true == keyIsDown[Keys.J]) 
     { 
      Bass.BASS_Init(1, 44100, BASSInit.BASS_DEVICE_DEFAULT, this.Handle); 
     } 
     else 
     { 
      Bass.BASS_StreamFree(Stream1); 
     } 
     } 


    } 
} 
+0

你能否把我的代碼實現到你的解決方案?謝謝。 – Joscplan

+0

我很樂意根據你的代碼來實現它。不幸的是,我今晚晚上9點東部時間(美國)之前無法給予它所需的重點程度。 – philologon

+0

沒問題,有什麼地方可以聯繫你嗎?或者在這裏發佈insted如果theres沒有問題。提前致謝。 – Joscplan

0

哈哈不錯,我只是張貼了類似的答案,然後philogon,但有細微的差別:

private Dictionary<Key, bool> myKeys; 

在初始化,添加你想按(如Keys.D1,按鍵所有按鍵.D2),全部用「假」。 寫像函數:

private bool getKeyState(Keys k) 

這個函數可以每次使用一個鍵被按下。該參數將是被按下的鍵。如果它已經按下,忽略它。如果沒有,是的,彈低音。

,然後,我會寫這樣一個功能:

private void updateKeyDictionary(Key, boolean state) 

在這裏,你可以與選中「函數GetKeyState」你拿到鑰匙的當前狀態 - 如果是相同的狀態,什麼也不做,否則更新。 有一些不錯的linq表達式這個任務可以做2-3行

+0

你能用我的代碼來做嗎?我在這方面沒有那麼多經驗。提前致謝。 – Joscplan

+0

你還需要嗎? –

+0

是的,如果可能的話。謝謝。 – Joscplan