C# 窗口刷新音频
所以我遇到了一点问题,我正在编写一个拍手传感器,当有人拍手并执行某个命令时,它会听到C# 窗口刷新音频,c#,wpf,audio,naudio,C#,Wpf,Audio,Naudio,所以我遇到了一点问题,我正在编写一个拍手传感器,当有人拍手并执行某个命令时,它会听到 //CLAP private float bigValue; WaveIn waveIn; private double MaxValue; private void button1_Loaded(object sender, RoutedEventArgs e) { if (Convert.ToInt16(text
//CLAP
private float bigValue;
WaveIn waveIn;
private double MaxValue;
private void button1_Loaded(object sender, RoutedEventArgs e)
{
if (Convert.ToInt16(textBox1.Text) > 100)
{
MessageBox.Show("Invalid Value");
return;
}
else
MaxValue = Convert.ToDouble(textBox1.Text) / 100;
bigValue = 0;
waveIn = new WaveIn();
int waveInDevices = waveIn.DeviceNumber;
//Get Device Count
for ( int waveInDevice = 0; waveInDevice < waveInDevices; waveInDevice++)
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
}
waveIn.DeviceNumber = 0;
waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
int sampleRate = 8000;
int channels = 1;
waveIn.WaveFormat = new WaveFormat(sampleRate, channels);
waveIn.StartRecording();
}
//CLAP
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
for (int index = 0; index < e.BytesRecorded; index += 2)
{
short sample = (short)((e.Buffer[index + 1] << 8) | e.Buffer[index + 0]);
float sample32 = sample / 32768f;
label1.Content = sample32.ToString();
if (bigValue < sample32)
{
bigValue = sample32;
label2.Content = bigValue.ToString();
if (bigValue > MaxValue)
{
waveIn.StopRecording();
SendMessage(MONITOR_ON, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_ON);
MessageBox.Show("Did you Clap?");
}
}
}
}
//CLAP
私人价值;
韦文韦文;
私有双最大值;
已加载私有无效按钮1_(对象发送方,路由目标)
{
如果(转换为16(textBox1.Text)>100)
{
MessageBox.Show(“无效值”);
返回;
}
其他的
MaxValue=Convert.ToDouble(textBox1.Text)/100;
bigValue=0;
waveIn=新的waveIn();
int waveInDevices=waveIn.DeviceNumber;
//获取设备计数
对于(int-waveInDevice=0;waveInDevice
代码本身按原样工作,但我需要它能够根据需要多次重置自身。该程序基本上会侦听一个拍子并唤醒监视器并启动它。每当我添加另一个“waveIn.StartRecording();”时,该程序就会中断
有没有关于如何刷新页面或使其永久侦听的想法?以下是一个将
WaveIn
逻辑移动到后台线程的示例。它应该为您提供足够的启动时间。请检查以获取包含后台线程取消的完整示例
//CLAP
private float bigValue;
WaveIn waveIn;
private double MaxValue;
private BackgroundWorker worker;
private void button1_Loaded(object sender, RoutedEventArgs e)
{
if (Convert.ToInt16(textBox1.Text) > 100)
{
MessageBox.Show("Invalid Value");
return;
}
else
MaxValue = Convert.ToDouble(textBox1.Text) / 100;
bigValue = 0;
// You'll need to handle the thread cancellation
// when the user clicks the button again
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += (s, e) =>
{
waveIn = new WaveIn();
int waveInDevices = waveIn.DeviceNumber;
//Get Device Count
for ( int waveInDevice = 0; waveInDevice < waveInDevices; waveInDevice++)
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
}
waveIn.DeviceNumber = 0;
waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
int sampleRate = 8000;
int channels = 1;
waveIn.WaveFormat = new WaveFormat(sampleRate, channels);
waveIn.StartRecording();
};
worker.ProgressChanged += (s, e) =>
{
SendMessage(MONITOR_ON, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_ON);
MessageBox.Show("Did you Clap?");
};
worker.RunWorkerAsync();
}
//CLAP
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
for (int index = 0; index < e.BytesRecorded; index += 2)
{
short sample = (short)((e.Buffer[index + 1] << 8) | e.Buffer[index + 0]);
float sample32 = sample / 32768f;
label1.Content = sample32.ToString();
if (bigValue < sample32)
{
bigValue = sample32;
label2.Content = bigValue.ToString();
if (bigValue > MaxValue)
{
worker.ReportProgress(0);
break;
}
}
}
}
//CLAP
私人价值;
韦文韦文;
私有双最大值;
私人背景工人;
已加载私有无效按钮1_(对象发送方,路由目标)
{
如果(转换为16(textBox1.Text)>100)
{
MessageBox.Show(“无效值”);
返回;
}
其他的
MaxValue=Convert.ToDouble(textBox1.Text)/100;
bigValue=0;
//您需要处理线程取消
//当用户再次单击按钮时
worker=新的BackgroundWorker();
worker.WorkerReportsProgress=true;
worker.worker支持扫描单元=true;
worker.DoWork+=(s,e)=>
{
waveIn=新的waveIn();
int waveInDevices=waveIn.DeviceNumber;
//获取设备计数
对于(int-waveInDevice=0;waveInDevice
{
SendMessage(监视器打开,WM系统命令,SC监视器电源,监视器打开);
显示(“你鼓掌了吗?”);
};
worker.RunWorkerAsync();
}
//拍手
无效waveIn_数据可用(对象发送方,WaveInEventArgs e)
{
对于(int index=0;index
基本上,您的代码所做的是打开waveIn
接收音频数据,然后检查数据中是否有响亮的样本。当它接收到超过阈值的样本时,它会停止监听并发出命令
如前所述,在检测到第一个大样本后,代码停止。不再接收音频数据,等等。可能不是您想要的。相反,您需要改进clap检测,以便它在检测到第一个大样本后的一段时间内(比如几秒钟)停止处理传入数据。不要停止接收音频数据o数据,停止对其作出反应
在类中添加一个DataTime
字段,该字段记录上次clap检测的时间戳。在waveIn_DataAvailable
方法开始时,检查自上次检测以来经过的时间是否小于静默时间,如果是,只需返回而不处理音频块。当检测到足够大的样本时,触发事件并更新最后一个clap检测字段
大概是这样的:
DateTime LastDetection = DateTime.Now.AddMinutes(-1);
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
if (LastDetection.AddSeconds(3) >= DateTime.Now)
return;
if (DetectClap(e.Buffer))
{
LastDetection = DateTime.Now;
SendMessage(MONITOR_ON, WM_SYSCOMMAND, SC_MONITORPOWER, MONITOR_ON);
MessageBox.Show("Clap detected.");
}
}
bool DetectClap(byte[] audiobytes)
{
for (int i = 0; i < audiobytes.Length; i += 2)
{
float sample32 = (float)((short)((audiobytes[0] << 8) | audiobytes[1]))/32768f;
if (sample32 > MaxValue)
return true;
}
return false;
}
DateTime LastDetection=DateTime.Now.AddMinutes(-1);
无效waveIn_数据可用(对象发送方,WaveInEventArgs e)
{
如果(LastDetection.AddSeconds(3)>=DateTime.Now)
返回;
if(检测捕捉(如缓冲区))
{
LastDetection=DateTime.Now;
SendMessage(监视器打开,WM系统命令,SC监视器电源,监视器打开);
MessageBox.Show(“检测到Clap”);
}
}
bool DetectClap(字节[]音频字节)
{
对于(int i=0;i
所以最后我选择了一种不同于两种建议答案的方式
private float bigValue;
WaveIn waveIn;
private double MaxValue;
private void button1_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (Convert.ToInt16(textBox1.Text) > 100)
{
MessageBox.Show("Invalid Value");
return;
}
else
MaxValue = Convert.ToDouble(textBox1.Text) / 100;
bigValue = 0;
waveIn = new WaveIn();
int waveInDevices = waveIn.DeviceNumber;
//Get Device Count
for (int waveInDevice = 0; waveInDevice < waveInDevices; waveInDevice++)
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
}
waveIn.DeviceNumber = 0;
waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
int sampleRate = 8000;
int channels = 1;
waveIn.WaveFormat = new WaveFormat(sampleRate, channels);
waveIn.StartRecording();
}
private void button1_Loaded(object sender, RoutedEventArgs e)
{
if (Convert.ToInt16(textBox1.Text) > 100)
{
MessageBox.Show("Invalid Value");
return;
}
else
MaxValue = Convert.ToDouble(textBox1.Text) / 100;
bigValue = 0;
waveIn = new WaveIn();
int waveInDevices = waveIn.DeviceNumber;
for (int i = 0; i <= 100; i++)
{
}
//Get Device Count
for (int waveInDevice = 0; waveInDevice < waveInDevices; waveInDevice++)
{
WaveInCapabilities deviceInfo = WaveIn.GetCapabilities(waveInDevice);
}
waveIn.DeviceNumber = 0;
waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
int sampleRate = 8000;
int channels = 1;
waveIn.WaveFormat = new WaveFormat(sampleRate, channels);
waveIn.StartRecording();
}
int i = 0;
void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
for (int index = 0; index < e.BytesRecorded; index += 2)
{
short sample = (short)((e.Buffer[index + 1] << 8) | e.Buffer[index + 0]);
float sample32 = sample / 32768f;
label1.Content = sample32.ToString();
if (bigValue < sample32)
{
bigValue = sample32;
label2.Content = bigValue.ToString();
if (bigValue > MaxValue)
{
waveIn.StopRecording();
if (IsOdd(i))
{
button1.IsEnabled = false;
}
else
{
button1.IsEnabled = true;
}
MessageBox.Show("Did you Clap?");
i++;
}
}
}
}
public static bool IsOdd(int value)
{
return value % 2 != 0;
}
}
private float bigValue;
韦文韦文;
私有双最大值;
私有无效按钮1\u无法更改(对象发送方,DependencyPropertyChangedEventArgs e)
{
如果(转换为16(textBox1.Text)>100)
{
MessageBox.Show(“无效值”);
返回;
}
其他的
MaxValue=Co