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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM