1

我正在制作一个应用程序,它在按下键时播放声音,当松开键时声音立即停止。

我发现的问题是,如果你按下一个键,它会播放它的前几毫秒,然后无限循环它,直到你释放这个键。

我目前使用的代码如下:

        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 个或多个声音而不会永远循环播放?

4

2 回答 2

1

将私人成员添加到您的班级:

private Dictionary<Key, Boolean> KeyIsDown;

在您的 OnKeyDown 方法中,设置 KeyIsDown(currentKey) = true; 在您的 OnKeyUp 方法中,设置 KeyIsDown(currentKey) = false;

然后为 onIdle 事件添加一个委托。每当调用委托时,使用 if 语句而不是 foreach 检查 KeyIsDown 中的每个键,并根据 KeyIsDown(aKey) 是真还是假来处理每个键。

由于我没有您的代码所引用的 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);
         }
      }


   }
}
于 2013-10-17T17:20:01.967 回答
0

哈哈很好,我只是发布了一个类似的答案然后 philogon,但略有不同:

private Dictionary<Key, bool> myKeys;

在初始化时,您添加所有要按下的键(例如 Keys.D1、Keys.D2),全部为“false”。编写如下函数:

private bool getKeyState(Keys k) 

每次按下某个键时都可以使用此功能。参数将是被按下的键。如果它已经按下,忽略它。如果没有,是的,弹贝斯。

然后,我会写一个函数,如:

private void updateKeyDictionary(Key, boolean state)

在这里,您可以使用“getKeyState”检查您获得密钥的当前状态 - 如果它是相同的状态,则什么也不做,否则更新。使用一些不错的 linq 表达式,这个任务可以在 2-3 行中完成

于 2013-10-17T17:27:23.557 回答