C# NAudio 录制声音和显示波形图
阅读原文时间:2023年07月10日阅读:2

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
{
///

/// Interaction logic for MainWindow.xaml ///
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));  
        }  
    }

}

}


    <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>  

参考:

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

https://github.com/markheath/voicerecorder

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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章