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

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 NAudio.Wave;
using System.IO;
namespace TestAudio
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private IWaveIn waveIn;
        private WaveFileWriter writer;
        List<float> sampleAggregator = new List<float>();//用来储存波形数据
        private void btnStart_Click(object sender, EventArgs e)
        {
            StartRecording();
        }


        /// <summary>
        /// 开始录音
        /// </summary>
        private void StartRecording()
        {
            if (waveIn != null) return;
            Text = "start recording....";
            btnStart.Text = "正在录制....";
            btnStart.Enabled = false;

            waveIn = new WaveIn { WaveFormat = new WaveFormat(8000, 1) };//设置码率
            writer = new WaveFileWriter("test.wav", waveIn.WaveFormat);
            waveIn.DataAvailable += waveIn_DataAvailable;
            waveIn.RecordingStopped += OnRecordingStopped;
            waveIn.StartRecording();
        }

        /// <summary>
        /// 录音中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {

            writer.Write(e.Buffer, 0, e.BytesRecorded);
            byte[] buffer = e.Buffer;
            int bytesRecorded = e.BytesRecorded;
      

            for (int index = 0; index < e.BytesRecorded; index += 2)
            {
                short sample = (short)((buffer[index + 1] << 8) |
                                        buffer[index + 0]);
                float sample32 = sample / 32768f;
                sampleAggregator.Add(sample32);
            }



            int secondsRecorded = (int)(writer.Length / writer.WaveFormat.AverageBytesPerSecond);//录音时间获取
            if (secondsRecorded >= 3)//只录制6秒
            {
                waveIn.StopRecording();
                Text = "complete";
                btnStart.Text = "开始录制";
                btnStart.Enabled = true;

                //------------------------------------开始画波形图。
                Text = sampleAggregator.Min() + "," + sampleAggregator.Max();
                int baseMidHeight = 50;
                float h = 0;
                for (int i = 0; i < sampleAggregator.Count; i+=60) {//大概意思意思 60的步长是怕太多了。

                       h=  sampleAggregator[i] * 300;
                       flowLayoutPanel1.Controls.Add(new Label() { BackColor = Color.Pink, Width = 5, Height = (int)h, Margin = new Padding(0, baseMidHeight-(int)h, 0, 0) });
                
                }
                //-----------------------------------------------------



            }


        }
        /// <summary>
        /// 停止录音
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnRecordingStopped(object sender, StoppedEventArgs e)
        {

            if (waveIn != null) // 关闭录音对象
            {
                waveIn.Dispose();
                waveIn = null;
            }
            if (writer != null)//关闭文件流
            {
                writer.Close();
                writer = null;
            }
            if (e.Exception != null)
            {
                MessageBox.Show(String.Format("出现问题 " + e.Exception.Message));
            }

        }


       

        private void Form1_Load(object sender, EventArgs e)
        {
          
        }





    }
}

  

WPF 例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NAudio.Wave;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace TestAudioWPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {

            InitializeComponent();
            listView.DataContext = listView.ItemsSource = sampleAggregator;

        }


         private IWaveIn waveIn;
        private WaveFileWriter writer;
        ObservableCollection<WaveInfo> sampleAggregator = new ObservableCollection<WaveInfo> ();//用来储存波形数据
     

        /// <summary>
        /// 开始录音
        /// </summary>
        private void StartRecording()
        {
            if (waveIn != null) return;
            Title  = "start recording....";
            btnStart.Content  = "正在录制....";
            btnStart.IsEnabled  = false;
            sampleAggregator.Clear();

            waveIn = new WaveIn { WaveFormat = new WaveFormat(8000, 1) };//设置码率
            writer = new WaveFileWriter("test.wav", waveIn.WaveFormat);
            waveIn.DataAvailable += waveIn_DataAvailable;
            waveIn.RecordingStopped += OnRecordingStopped;
            waveIn.StartRecording();
        }

        /// <summary>
        /// 录音中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {

            writer.Write(e.Buffer, 0, e.BytesRecorded);
            byte[] buffer = e.Buffer;
            int bytesRecorded = e.BytesRecorded;
      
            //------------------------------------开始画波形图。
            sampleAggregator.Clear();//可以不清除,就会一直保持历史记录

                           //  short s = BitConverter.ToInt16(e.Buffer, 0);//这样采样比较少,反正是int16型的
                           //  int w= Math.Abs(s / 50);
                          //  sampleAggregator.Add(new WaveInfo() { heigth = w });

            for (int index = 0; index < e.BytesRecorded; index += 2)
            {
                short sample = (short)((buffer[index + 1] << 8) |
                                        buffer[index + 0]);
                float sample32 = sample / 32768f;

                if (sample32 > 0.03f)
                {
                    sampleAggregator.Add(new WaveInfo() { heigth = sample32*300f });
                }
            }

            //---------------------------------------------------------

            int secondsRecorded = (int)(writer.Length / writer.WaveFormat.AverageBytesPerSecond);//录音时间获取
            if (secondsRecorded >= 552)//只录制552秒
            {
                waveIn.StopRecording();
                Title  = "complete";
                btnStart.Content  = "开始录制";
                btnStart.IsEnabled  = true;



            }
        }
      
        /// <summary>
        /// 停止录音
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnRecordingStopped(object sender, StoppedEventArgs e)
        {

            if (waveIn != null) // 关闭录音对象
            {
                waveIn.Dispose();
                waveIn = null;
            }
            if (writer != null)//关闭文件流
            {
                writer.Close();
                writer = null;
            }
            if (e.Exception != null)
            {
                MessageBox.Show(String.Format("出现问题 " + e.Exception.Message));
            }

        }


       

        private void Form1_Load(object sender, EventArgs e)
        {
          
        }

        private void btnStart_Click(object sender, RoutedEventArgs e)
        {

            StartRecording();
        }



    }




    public class WaveInfo :INotifyPropertyChanged{

        public event PropertyChangedEventHandler PropertyChanged;


        private float  _heigth;

        public float heigth
        {
            get { 
                return _heigth; 
            }
            set {
       
             if (value != _heigth)
             {    _heigth = value;
                 OnPropertyChanged("heigth");
             }
            }


        }


        private string text;
        public string Text
        {
            get { return text; }
            set { text = value; OnPropertyChanged("Text"); }
        }


        protected void OnPropertyChanged(string propertyName = "")
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }


    
    }




}








<Window x:Class="TestAudioWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>


        <Button x:Name="btnStart" Click="btnStart_Click"  Content="btnStart" HorizontalAlignment="Left" Margin="145,20,0,0" VerticalAlignment="Top" Width="169" Height="37"/>
        <ListView BorderThickness="0" Name="listView" DataContext="sampleAggregator" Height="232" VerticalAlignment="Bottom">

            <ListView.ItemTemplate>
                <DataTemplate>
                    <Label Margin="0" Padding="0" Background="Pink"  Width="2" Height="{Binding heigth}"></Label>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel  IsItemsHost="True" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" Orientation="Horizontal"  />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>

        </ListView>

        <WrapPanel  ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" Orientation="Horizontal" Height="70" VerticalAlignment="Bottom">
            <Label Margin="0" Padding="0" Background="Pink"  Width="2" Height="22"></Label>
            <Label Margin="0" Padding="0" Background="Pink"  Width="2" Height="33"></Label>
            <Label Margin="0" Padding="0" Background="Pink"  Width="2" Height="44"></Label>

        </WrapPanel>

    </Grid>
</Window>

  

参考:

https://channel9.msdn.com/coding4fun/articles/AutotuneNET

https://github.com/markheath/voicerecorder

http://www.codesoso.com/code/Curve_RealTime.aspx

原文地址:https://www.cnblogs.com/wgscd/p/11771817.html