C# 如何使用SoundPlayer淡出.wav文件的音频,而不是立即停止?

C# 如何使用SoundPlayer淡出.wav文件的音频,而不是立即停止?,c#,winforms,soundplayer,C#,Winforms,Soundplayer,我试图在我松开按钮后立即停止声音,但发生的情况是该文件已完全播放。 我不想突然停止声音,因为它发生在sp.stop()上。 有办法做到这一点吗 private void button1_MouseDown(object sender, MouseEventArgs e) { if(sender == mk) { if(e.Button == MouseButtons.Left) { SoundPlayer sp = new

我试图在我松开按钮后立即停止声音,但发生的情况是该文件已完全播放。 我不想突然停止声音,因为它发生在
sp.stop()
上。 有办法做到这一点吗

private void button1_MouseDown(object sender, MouseEventArgs e)
{
    if(sender == mk)
    {
        if(e.Button == MouseButtons.Left)
        {
            SoundPlayer sp = new SoundPlayer();

            sp.SoundLocation = (@"C:\my path\sound.wav");
            sp.Play();
        }
    }
}

private void button1_MouseUp(object sender, MouseEventArgs e)
{
    if(sender == mk)
    {
        if(e.Button == MouseButtons.Left)
        { /*some code here (without sp.Stop())*/ }
    }
}

我把你的问题解释为:

如何使用
SoundPlayer
淡出.wav文件的音频,而不是立即停止

简单的回答是,您不能单独使用
SoundPlayer
。您需要使用
winmm.dll
库中的几个API

如果您对WPF感到满意,那么在其volume属性上使用带有双动画的
MediaElement
可能是更好的方法。有关这方面的信息,请参见问题

但是,如果您真的想使用WinForms,下面是一个应该可以工作的实现

关于
表格1的注释

  • 两个按钮,分别命名为
    startButton
    stopButton
  • 一个名为
    timer1
    的计时器,我用它来淡出声音
以下是使其工作的代码:

使用系统;
使用系统、媒体;
使用System.Runtime.InteropServices;
使用System.Windows.Forms;
命名空间Windows窗体应用程序1
{
公共部分类Form1:Form
{
[DllImport(“winmm.dll”,EntryPoint=“waveOutGetVolume”)]
专用静态外部int WaveOutGetVolume(IntPtr hwo、out uint dwVolume);
[DllImport(“winmm.dll”,EntryPoint=“waveOutSetVolume”)]
专用静态外部int WaveOutSetVolume(IntPtr hwo、uint dwVolume);
私人SoundPlayer=新SoundPlayer();
//粗略的三角洲时间场
私人浮动总延时;
//调整此值以确定淡入淡出的速度
专用常量浮动速度=0.001f;
公共表格1()
{
this.InitializeComponent();
//我用100毫秒作为“帧速率”
this.timer1.Interval=100;
this.stopButton.Enabled=false;
}
私有无效开始按钮单击(对象发送者,事件参数e)
{
//将音频设备音量设置为最大。
//这不是计算机的音量,所以它不会
//通过这样做来鼓起你的耳鼓,除非你
//让电脑音量超高-这不是什么
//代码错误
WaveOutSetVolume(IntPtr.Zero,uint.MaxValue);
this.startButton.Enabled=false;
this.stopButton.Enabled=true;
this.totalElapsedTime=0f;
this.player.SoundLocation=@“Music File.wav”;
this.player.Load();
这个.player.Play();
}
私有无效停止按钮\u单击(对象发送者,事件参数e)
{
//到站
this.timer1.Start();
this.stopButton.Enabled=false;
}
私有无效计时器1_刻度(对象发送方,事件参数e)
{
//要插值的量(值介于0和1之间,包括0和1)
浮动量=数学最小值(1f,此为.totalElapsedTime*速度);
//lerp后的新频道音量
float lerped=Lerp(ushort.MaxValue,0,金额);
//每个通道的音量实际上表示为一个ushort
ushort channelVolume=(ushort)lerped;
//所有频道的新音量
uint音量=(uint)信道音量|((uint)信道音量=1f)
{
//停止计时
this.timer1.Stop();
//阻止球员
this.player.Stop();
//停止完成,所以让用户重新开始
this.startButton.Enabled=true;
}
//添加经过的毫秒数(非常粗略的增量时间)
this.totalElapsedTime+=this.timer1.Interval;
}
公共静态浮动Lerp(浮动值1、浮动值2、浮动金额)
{
//进行线性插值
回报(value1+((value2-value1)*金额));
}
}
}
希望这应该是不言自明的。我想大多数人会认为这是一种粗糙的“游戏循环esqe”方法,但它似乎工作得很好。这里需要注意的是,调整淡入发生的速度是
速度
常数

代码设置为在1秒内淡出。通过查看
timer1.Interval
Velocity
可以很容易地看出这一点。1000毫秒后(10个计时器滴答声),然后1000*0.001=1,这导致停止代码完成


更改
计时器1.Interval
的唯一原因是使更多的“淡入淡出”发生。当前设置在停止之前会有10个音量衰减。

您的意思是,当您“停止”声音时,您希望它衰减或类似的声音?答案很可能是:)@test yes。做一个简单的音乐作曲家,然后像Stop()那样停止,听起来很糟糕。我想你可以逐步降低音量,在0%时停止。@Pierre Lucpinoult你将无法通过
SoundPlayer
访问音量。如果OP使用的是WPF,那么就可以使用
MediaElement
.Wow。哇。你太棒了!我设法将它们分配给实际事件,所以现在我需要它如何工作。谢谢!