2013-01-17 66 views
2

我正在構建一個將麥克風音頻記錄到文件(.mp3)的應用程序。我希望我的應用程序只在檢測到足夠高的幅度時纔將數據寫入文件。我在嘗試保存選定的數據時遇到問題。我得到的只是一個快速失真,與記錄的數據甚至不盡相同。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; 

namespace NAudio_Testing 
{ 
    public partial class Form1 : Form 
    { 
     int counter = 0; 
     int passed = 0; 
     private BufferedWaveProvider bufferedWaveProvider; 
     WaveIn waveIn; 
     WaveFileWriter writer; 
     string output = "C:/Users/klein/AppData/Roaming/Microsoft/Windows/gravacao.mp3"; 
     public Form1() 
     { 
      InitializeComponent(); 
      waveIn = new WaveIn(); 
      writer = new WaveFileWriter(output, waveIn.WaveFormat); 

      waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(new_dataAvailable); 

      bufferedWaveProvider = new BufferedWaveProvider(waveIn.WaveFormat); 
      bufferedWaveProvider.DiscardOnBufferOverflow = true; 
      waveIn.StartRecording(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      timer1.Interval = 1000; 
      timer1.Start(); 
     } 

     void new_dataAvailable(object sender, WaveInEventArgs e) 
     { 
      for (int i = 0; i < e.BytesRecorded; i+=2) 
      { 
       short sample = (short)((e.Buffer[i + 1] << 8) | e.Buffer[i + 0]); 
       float sample32 = sample/32768f; 
       if (sample32 > 0.02) //0.02~0.03 
       { 
        writer.WriteSample(sample); 
       } 
      } 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      waveIn.StopRecording(); 
      waveIn.Dispose(); 
      waveIn = null; 
      writer.Close(); 
      writer = null; 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      textBox1.Text = counter++.ToString(); 
     } 

    } 
} 

編輯:我能夠成功地錄製音頻,如果我刪除選擇,如果和剛纔添加的線,這個問題當然是,那麼我無法

writer.WriteByte(e.Buffer[i + 0]); 
writer.WriteByte(e.Buffer[i + 1]); 

像這樣:

void new_dataAvailable(object sender, WaveInEventArgs e) 
    { 
     for (int i = 0; i < e.BytesRecorded; i+=2) 
     { 
      short sample = (short)((e.Buffer[i + 1] << 8) | e.Buffer[i + 0]); 
      float sample32 = sample/32768f; 

      writer.WriteByte(e.Buffer[i + 0]); 
      writer.WriteByte(e.Buffer[i + 1]); 

     } 
    } 

謝謝根據音頻的幅度來記錄或不。

回答

5

您的方法基本上是將所有樣本丟棄在過零點附近,無論當時的整體音頻是否很大。它會扭曲信號並加速它,因爲音頻信號通常每秒都有很多零交叉點。相反,您需要在短時間內測量所有樣品的最大體積(多長時間取決於您,但一次可以做1秒)。如果在這段時間內任何採樣比指定的最小值都大,那麼你記錄整個塊。

你的代碼的第二個問題是你實際上並沒有創建一個MP3文件。 WaveFileWriter製作一個WAV文件。將您的文件名更改爲以WAV結尾,並聽取其中的內容以聽取您錄製的結果。然後,您需要在錄製後轉換爲MP3作爲第二步。 (我有一篇關於如何在格式here之間進行轉換的文章)。

0

您應該比較樣本的絕對值,因爲樣本已簽名。

if (Abs(sample32) > 0.02) //0.02~0.03 
    { 
     writer.WriteSample(sample); 
    }