当前位置: 首页 > 工具软件 > NAudio > 使用案例 >

C# NAudio检测声音

海嘉赐
2023-12-01
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);
                }

            }
        }
    }
}
 类似资料: