C#實現麥克風採集與播放


在網絡聊天系統中。採集麥克風的聲音並將其播放出來。是最基礎的模塊之中的一個。本文我們就介紹怎樣高速地實現這個基礎模塊。

一. 基礎知識

  有幾個與聲音採集和播放相關的專業術語必需要先了解一下,否則。后面的介紹將無法展開。語音採集指的是從麥克風採集音頻數據。即聲音樣本轉換成數字信號。

其涉及到幾個重要的參數:採樣率、採樣位數、聲道數。

  簡單的來說:

       採樣率:即採樣頻率,就是在1秒內進行採集動作的次數。

       採樣位數:又叫採樣深度。就是每次採集動作得到的數據長度,即使用多少個bit來記錄一個樣本。

       聲道數:通常是單聲道或雙聲道(立體聲)。普通的麥克風採集差點兒都是單聲道的。

  這樣。1秒鍾採集得到的聲音數據的大小為(單位byte):(採樣頻率×採樣位數×聲道數×時間)/8。

  音頻幀:通常一個音頻幀的時長為10ms,即每10ms的數據構成一個音頻幀。假設:採樣率16k、採樣位數16bit、聲道數1,那么一個10ms的音頻幀的大小為:(16000*16*1*0.01)/8 = 320 字節。計算式中的0.01為秒。即10ms

二. 怎樣採集、播放?

  假設直接基於底層的DirectX來進行麥克風的採集與播放。那將是十分繁瑣的。

好在我們有現成的組件來完畢這個工作。MCapture 用於採集硬件設備(如麥克風、攝像頭、聲卡、屏幕等)。MPlayer 用於播放採集到的數據。

1.採集麥克風

  MCapture提供了IMicrophoneCapturer。用於採集麥克風輸入的聲音。其每隔20ms觸發一次AudioCaptured事件,通過事件的參數byte[]暴露這20ms採集得到的數據。

  IMicrophoneCapturer 相關採集參數的值是這種:

       採樣頻率:16000,採樣位數:16bit。聲道數:1。

       所以,依照上面的公式進行計算,我們能夠得到AudioCaptured事件的參數byte[]的長度為640。

2. 播放聲音數據

  MPlayer提供了IAudioPlayer,用於播放聲音數據。在創建IAudioPlayer實例時,要正確的設置採樣頻率、採樣位數、聲道數這些參數的值。假設它們與即將要播放的聲音數據的特征不一致,播放將出現錯誤。

  我們在拿到MCapture採集的聲音數據后,將其提交給IAudioPlayer的Play方法進行播放就可以。

三.Demo實現

  在有了前面的介紹作為基礎后,接下來實現麥克風的採集和播放就相當簡單了。在接下來的demo中。不僅演示了播放從麥克風採集到的聲音,並且多加了一個功能。就是直接播放wav聲音文件,這些實現都是相當簡單的。  

復制代碼
    public partial class Form1 : Form
    {
        private IAudioPlayer audioPlayer;
        private IMicrophoneCapturer microphoneCapturer;

        public Form1()
        {
            InitializeComponent();
        }

        private void button_mic_Click(object sender, EventArgs e)
        {
            try
            {
                this.microphoneCapturer = CapturerFactory.CreateMicrophoneCapturer(int.Parse(this.textBox_mic.Text));
                this.microphoneCapturer.AudioCaptured += new ESBasic.CbGeneric<byte[]>(microphoneCapturer_AudioCaptured);
                this.audioPlayer = PlayerFactory.CreateAudioPlayer(int.Parse(this.textBox_speaker.Text), 16000, 1, 16, 2);
                this.microphoneCapturer.Start();

                this.label_msg.Text = "正在採集麥克風,並播放 . . .";
                this.label_msg.Visible = true;
                this.button_wav.Enabled = false;
                this.button_mic.Enabled = false;
                this.button_stop.Enabled = true;
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }

        void microphoneCapturer_AudioCaptured(byte[] audioData) { if (this.audioPlayer != null) { this.audioPlayer.Play(audioData); } } private void button_wav_Click(object sender, EventArgs e)
        {
            try
            {
                string path = ESBasic.Helpers.FileHelper.GetFileToOpen2("請選擇要播放的wav文件", AppDomain.CurrentDomain.BaseDirectory, ".wav");
                if (path == null)
                {
                    return;
                }

                AudioInformation info = PlayerFactory.ParseWaveFile(path);
                if (info.FormatTag != (int)WaveFormats.Pcm)
                {
                    MessageBox.Show("只支持PCM編碼方式的語音數據!");
                    return;
                }

                int secs = info.GetTimeInMsecs() / 1000; //聲音數據的播放時長
                this.audioPlayer = PlayerFactory.CreateAudioPlayer(int.Parse(this.textBox_speaker.Text), info.SampleRate, info.ChannelCount, info.BitsNumber, secs + 1);

                this.audioPlayer.Play(info.AudioData);

                this.label_msg.Text = "正在播放wav文件 . . .";
                this.label_msg.Visible = true;
                this.button_wav.Enabled = false;
                this.button_mic.Enabled = false;
                this.button_stop.Enabled = true;
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.microphoneCapturer != null)
            {
                this.microphoneCapturer.Stop();
                this.microphoneCapturer.Dispose();
                this.microphoneCapturer = null;
            }

            if (this.audioPlayer != null)
            {
                this.audioPlayer.Dispose();
                this.audioPlayer = null;
            }
        }

        private void button_stop_Click(object sender, EventArgs e)
        {
            if (this.audioPlayer == null)
            {
                return;
            }

            if (this.microphoneCapturer != null)
            {
                this.microphoneCapturer.Stop();
                this.microphoneCapturer.Dispose();
                this.microphoneCapturer = null;
            }

            this.audioPlayer.Clear();
            this.audioPlayer.Dispose();
            this.audioPlayer = null;

            this.label_msg.Visible = false;
            this.button_wav.Enabled = true;
            this.button_mic.Enabled = true;
            this.button_stop.Enabled = false;
        }        
    }
復制代碼

  看看demo執行的效果圖:

  

    麥克風採集與播放Demo源代碼下載




免責聲明!

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



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