using NAudio.Wave;
using System;
using System.Collections.Generic;

namespace WinFromBaidu
{
class NAudioRecorder
{
#region var

/// <summary>
/// 录音机对象
/// </summary>
public WaveIn waveSource = null;
/// <summary>
/// 录音写入磁盘记录者 用于截取声音测试
/// </summary>
public WaveFileWriter waveFile = null;
/// <summary>
/// 录音保存格式
/// </summary>
private string fileName = string.Empty;
/// <summary>
/// 委托声音触发时间
/// </summary>
public Action<byte[]> ReciveMaxData;
/// <summary>
/// 缓存截取声音片段
/// </summary>
private List<byte> CacheBuffer = new List<byte>();
/// <summary>
/// 记录有人说话时间
/// </summary>
private DateTime BeginTime = DateTime.Now;
/// <summary>
/// 是否有人说话标志
/// </summary>
private bool IsSpeeak = false;
/// <summary>
/// 声音响度标准
/// </summary>
public float LoudnessStant = 0.08F;

#endregion

/// <summary>
/// 开始录音方法
/// </summary>
public void StartRec()
{
waveSource = new WaveIn();
waveSource.WaveFormat = new WaveFormat(16000, 16, 1); // 16bit,16KHz,Mono的录音格式
waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);
waveFile = new WaveFileWriter(fileName, waveSource.WaveFormat);
waveSource.StartRecording();
}

/// <summary>
/// 停止录音
/// </summary>
public void StopRec()
{
waveSource.StopRecording();

// Close Wave(Not needed under synchronous situation)
if (waveSource != null)
{
waveSource.Dispose();
waveSource = null;
}

if (waveFile != null)
{
waveFile.Dispose();
waveFile = null;
}
}

/// <summary>
/// 录音结束后保存的文件路径
/// </summary>
/// <param name="fileName">保存wav文件的路径名</param>
public void SetFileName(string fileName)
{
this.fileName = fileName;
}

/// <summary>
/// 开始录音回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void waveSource_DataAvailable(object sender, WaveInEventArgs e)
{
if (waveFile != null)
{
//waveFile.Write(e.Buffer, 0, e.BytesRecorded);
//waveFile.Flush();
}
AnalyzeVoice(e.Buffer);
}

/// <summary>
/// 录音结束回调函数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void waveSource_RecordingStopped(object sender, StoppedEventArgs e)
{
if (waveSource != null)
{
waveSource.Dispose();
waveSource = null;
}

if (waveFile != null)
{
waveFile.Dispose();
waveFile = null;
}
}

/// <summary>
/// 语音分析
/// </summary>
/// <param name="buf"></param>
private void AnalyzeVoice(byte[] buf)
{
float max = LoudnessStant;
int maxNumber = 0;
// interpret as 16 bit audio
for (int index = 0; index < buf.Length; index += 2)
{
short sample = (short)((buf[index + 1] << 8) |
buf[index + 0]);
// to floating point
var sample32 = sample / 32768f;
// absolute value
if (sample32 < 0) sample32 = -sample32;
// is this the max value?
if (sample32 > max)
{
max = sample32;
maxNumber++;
}
}

if (max != LoudnessStant)
{
CacheBuffer.AddRange(buf);
IsSpeeak = true;
BeginTime = DateTime.Now;
}
else
{
if (IsSpeeak)
{
if ((DateTime.Now - BeginTime).TotalSeconds < 2)
{
CacheBuffer.AddRange(buf);
}
else
{
CacheBuffer.AddRange(buf);
//waveFile.Write(CacheBuffer.ToArray(), 0, CacheBuffer.Count);
//waveFile.Flush();
//回调声音触发方法
ReciveMaxData(CacheBuffer.ToArray());
CacheBuffer.Clear();
IsSpeeak = false;
}
}
else
{
if (CacheBuffer.Count > 3200 * 6)
{
CacheBuffer.RemoveRange(0, 3200);
}
CacheBuffer.AddRange(buf);
}

}
}
}
}

C# NAudio 检测声音的更多相关文章

  1. Unity Microphone 录音时 检测声音大小

    刚开始以为只取录音时的最后一个sample来判断音量大小,发现都检测不到. 后来搜索了一下,原来需要取一段sample来判断,有的是这一段取平均值作为音量大小.我这里是取出一段sample中的峰值(p ...

  2. C# NAudio 录制声音和显示波形图

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. Knock: 使用压电传感器来检测敲击

    原文链接:https://www.arduino.cc/en/Tutorial/Knock 敲击检测 本教程介绍如何使用压电传感器检测振动,比如敲门.桌子或其他固体表面. 压电传感器是一种能够在振动. ...

  4. 关于Unity中的声音管理模块(专题七)

    声音的要素 1: 音频文件AudioClip2: 音源AudioSource;3: 耳朵AudioListener;//全局只能有一个4: 2D/3D音频;//2D只是简单地播放声音,3D可以根据距离 ...

  5. iOS 检测耳机插入/拔出

    http://www.verydemo.com/demo_c134_i28481.html 开发过程中录音和播放这块碰到了一些问题,麻烦的主要有三个: 检测是否有声音输入设备 当有多个声音输出设备时, ...

  6. 「雕爷学编程」Arduino动手做(35)——模拟量声音传感器

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  7. 机器学习&数据挖掘笔记_14(GMM-HMM语音识别简单理解)

    为了对GMM-HMM在语音识别上的应用有个宏观认识,花了些时间读了下HTK(用htk完成简单的孤立词识别)的部分源码,对该算法总算有了点大概认识,达到了预期我想要的.不得不说,网络上关于语音识别的通俗 ...

  8. HGE基础教程

    作者:寰子 来源:http://www.hgechina.com/前言: 写道: 无意中发现了hge中文社区,听朋友介绍,认识了hge,然后开始对它进行研究,并使用hge开始制作游戏. 因为我所得的资 ...

  9. Android 音视频同步机制

    一.概述 音视频同步(avsync),是影响多媒体应用体验质量的一个重要因素.而我们在看到音视频同步的时候,最先想到的就是对齐两者的pts,但是实际使用中的各类播放器,其音视频同步机制都比这些复杂的多 ...

  10. LabVIEW(一):知识入门

    一.DAQ基础知识简介 1.DAQ是英文Data Acquisition (数据采集)的缩写. 数据采集(DAQ)是指测量:电压.电流.温度.压力.声音.编码数据等电气或物理现象的过程. 2.数据采集 ...

随机推荐

  1. ceph常用操作

    //修复一批数据不一致的pg ceph health detail|grep acting|awk -F' ' '{print $2}'|xargs -n1 ceph pg repair //修复os ...

  2. 修改、编辑pdf

    Python 操作 PDF 会用到两个库,分别是:PyPDF2 和 pdfplumber 其中 PyPDF2 可以更好的读取.写入.分割.合并PDF文件,而 pdfplumber 可以更好的读取 PD ...

  3. SED fitting

    Using the Robitaille (2017) YSO SED models https://notebook.community/hyperion-rt/paper-2017-sed-mod ...

  4. DoTween结束后删除对象

    using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; ...

  5. Quartus II 17.1新建一个流水灯

    诸图排序:从左到右,从上到下 一.软件设置 1.新建工程并添加FPGA芯片 2.新建.v文件并添加至顶层实体 3.元器件特性设置 4.分析与阐述(生成网表文件) 5.引脚分配 6.编译(包含分析与综合 ...

  6. Vulnhub 靶场 CORROSION: 1

    Vulnhub 靶场 CORROSION: 1 前期准备: 靶机地址:https://www.vulnhub.com/entry/corrosion-1,730/ kali攻击机ip:192.168. ...

  7. ABC136 E - Max GCD 题解

    题面 给定一个长度为 $N$ 的整数序列:$A_1, A_2, \ldots, A_n$. 您可以执行以下操作 $0 \sim K$ 次: 选择两个整数 $i$ 和 $j$,满足 $i \ne j$ ...

  8. SVNKit操作SVN

    系统集成SVN(SVNKit操作SVN) 网址:https://svnkit.com/documentation.html 文档:https://svnkit.com/javadoc/index.ht ...

  9. java技术系列(二) 反射

    能够分析类能力的程序称为反射. 反射能力: 在运行中分析类的能力. 在运行中查看对象,例如:编写一个toString方法供所有类使用. 实现通用的数组操作代码. 利用Method对象.

  10. Msp430 编写交通灯程序

    题目:我想想... 红灯亮,按下按键后倒计时10秒,倒计时十秒后,绿灯点亮,红灯熄灭,进入绿灯的15秒倒计时,在只剩下3秒的时候,绿灯闪烁. 代码如下,有点麻烦 当时这么写的 就不改了 #includ ...