按下无限循环

时间:2013-10-17 17:07:35

标签: c# bass

当一个应用程序在按键关闭时播放声音时,声音会在按键释放时立即停止。

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

目前使用的代码如下:

        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个或多个声音,而不会让它们循环播放?

2 个答案:

答案 0 :(得分: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);
         }
      }


   }
}

答案 1 :(得分: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行完成