【问题标题】:Key down infinite loop按键无限循环
【发布时间】:2013-10-17 17:07:35
【问题描述】:

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

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

我目前使用的代码如下:

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

【问题讨论】:

  • 何塞,当您决定自己有一个满意的答案时,您应该在左边的赞成和反对箭头下将其标记为已接受的答案。只有您(原始发帖人)可以将答案标记为已接受。此外,当你这样做时,它会给这个人额外的 15 点声望点(与你的名字相关的点数。你现在是 63>)

标签: c# bass


【解决方案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);
         }
      }


   }
}

【讨论】:

  • 我很乐意根据您的代码实现它。不幸的是,直到今晚东部时间(美国)晚上 9 点之后,我才能给予它所需的关注程度。
  • 没问题有什么地方可以联系你吗?或者如果没有问题,请在此处发布。提前致谢。
  • 是的,使用我个人资料中的电子邮件地址。 (点击 philogon 查看我的个人资料。)
  • 那一定是“付费观看”之类的东西。 paul.schrum@gmail.com
  • 好的,我会在东部时间(美国)晚上 9 点左右与您联系,再次感谢您的帮助。
【解决方案2】:

哈哈很好,我只是发布了一个与 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 行中完成

【讨论】:

  • 你能用我的代码来做吗?我在这方面没有太多经验。提前致谢。
  • 你还需要吗?
  • 是的,如果可能的话。谢谢。
猜你喜欢
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 2020-11-04
  • 1970-01-01
相关资源
最近更新 更多