当一个应用程序在按键关闭时播放声音时,声音会在按键释放时立即停止。
我发现的问题是,如果你按一个键它会播放它的第一个毫秒,然后无限循环直到你释放键。
目前使用的代码如下:
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 :(得分: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)
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行完成