2014-09-23 119 views
0

我想添加一個過濾器到音頻文件(.wav)通過修改字節,但我的問題是,聲音有噪音。音頻過濾器算法

public class MainActivity extends ActionBarActivity { 
    private int bufferSize = 0; 
    private static final int RECORDER_BPP = 16; 
    private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav"; 
    private static final String AUDIO_RECORDER_FOLDER = "ks"; 

    private static final int RECORDER_SAMPLERATE = 44100; 
    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO; 
    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, 
       RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 

     String file1 = "/storage/emulated/0/File/rec.wav"; 
     String file2 = "/storage/emulated/0/File/rec2.wav"; 
     copyWaveFile(file1,file2); 
    } 

    static final float ALPHA = 0.15f; 

    private float[] lowPass(float[] input, float[] output) { 
     if (output == null) 
      return input; 


     for (int n = 0; n < input.length; n++) { 
      output[n] = output[n] + ALPHA * (input[n] - output[n]); 
     } 
     return output; 

    } 

    private static float[] toFloatArray(byte[] buffer) { 
     ByteArrayInputStream bas = new ByteArrayInputStream(buffer); 
     DataInputStream ds = new DataInputStream(bas); 
     float[] fArr = new float[buffer.length/4]; // 4 bytes per float 
     for (int i = 0; i < fArr.length; i++) { 
      try { 
       fArr[i] = ds.readFloat(); 
      } catch (IOException e) { 
       Log.e("E", "eRRO :" + e.getMessage()); 
       e.printStackTrace(); 
      } 
     } 
     return fArr; 
    } 

    private static byte[] toByteArray(float[] fArr) { 
     ByteArrayOutputStream bas = new ByteArrayOutputStream(); 
     DataOutputStream ds = new DataOutputStream(bas); 
     for (float f : fArr) 
      try { 
       ds.writeFloat(f); 
      } catch (IOException e) { 
       Log.i("", "ERROR:" + e.getMessage()); 
       e.printStackTrace(); 
      } 
     byte[] bytes = bas.toByteArray(); 

     return bytes; 
    } 

    private void copyWaveFile(String file1, String file2) { 
     FileInputStream in1 = null; 
     FileOutputStream out = null; 
     long totalAudioLen = 0; 
     long totalDataLen = totalAudioLen + 36; 
     long longSampleRate = RECORDER_SAMPLERATE; 
     int channels = 2; 
     long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8; 

     byte[] data = new byte[bufferSize]; 
     byte[] dataOut = new byte[bufferSize]; 
     float[] floatArray = null; 
     try { 
      in1 = new FileInputStream(file1); 
      out = new FileOutputStream(file2); 

      totalAudioLen = in1.getChannel().size(); 
      totalDataLen = totalAudioLen + 36; 

      WriteWaveFileHeader(out, totalAudioLen, totalDataLen, 
        longSampleRate, channels, byteRate); 

      while (in1.read(data) != -1) { 

       floatArray = lowPass(toFloatArray(data), toFloatArray(dataOut)); 
       // out.write(data); original 
       out.write(toByteArray(floatArray)); 
      } 

      out.close(); 
      in1.close(); 

      Toast.makeText(this, "Done!!", Toast.LENGTH_LONG).show(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen, 
      long totalDataLen, long longSampleRate, int channels, long byteRate) 
      throws IOException { 

     byte[] header = new byte[44]; 

     header[0] = 'R'; // RIFF/WAVE header 
     header[1] = 'I'; 
     header[2] = 'F'; 
     header[3] = 'F'; 
     header[4] = (byte) (totalDataLen & 0xff); 
     header[5] = (byte) ((totalDataLen >> 8) & 0xff); 
     header[6] = (byte) ((totalDataLen >> 16) & 0xff); 
     header[7] = (byte) ((totalDataLen >> 24) & 0xff); 
     header[8] = 'W'; 
     header[9] = 'A'; 
     header[10] = 'V'; 
     header[11] = 'E'; 
     header[12] = 'f'; // 'fmt ' chunk 
     header[13] = 'm'; 
     header[14] = 't'; 
     header[15] = ' '; 
     header[16] = 16; // 4 bytes: size of 'fmt ' chunk 
     header[17] = 0; 
     header[18] = 0; 
     header[19] = 0; 
     header[20] = 1; // format = 1 
     header[21] = 0; 
     header[22] = (byte) channels; 
     header[23] = 0; 
     header[24] = (byte) (longSampleRate & 0xff); 
     header[25] = (byte) ((longSampleRate >> 8) & 0xff); 
     header[26] = (byte) ((longSampleRate >> 16) & 0xff); 
     header[27] = (byte) ((longSampleRate >> 24) & 0xff); 
     header[28] = (byte) (byteRate & 0xff); 
     header[29] = (byte) ((byteRate >> 8) & 0xff); 
     header[30] = (byte) ((byteRate >> 16) & 0xff); 
     header[31] = (byte) ((byteRate >> 24) & 0xff); 
     header[32] = (byte) (2 * 16/8); // block align 
     header[33] = 0; 
     header[34] = RECORDER_BPP; // bits per sample 
     header[35] = 0; 
     header[36] = 'd'; 
     header[37] = 'a'; 
     header[38] = 't'; 
     header[39] = 'a'; 
     header[40] = (byte) (totalAudioLen & 0xff); 
     header[41] = (byte) ((totalAudioLen >> 8) & 0xff); 
     header[42] = (byte) ((totalAudioLen >> 16) & 0xff); 
     header[43] = (byte) ((totalAudioLen >> 24) & 0xff); 

     out.write(header, 0, 44); 
    } 
} 

有人誰可以幫我奇怪的聲音,以及如何獲得音頻過濾器的多個算法和實現。

回答

0

您可以嘗試使用Matlab來查看波形類型以及噪聲存在的頻率。然後您可以設計低通濾波器以在噪聲邊界處具有截止頻率。

+0

您是否有示例或教程? – Giancarlo 2014-09-23 23:59:55

+0

[鏈接](http://www.mathworks.com/help/matlab/ref/fft.html)。該鏈接提供了用於實現快速傅立葉變換的matlab函數。基本上fft將把波形從時域變換到頻域。您可以觀察與頻率有關的輸出波形幅度。從那裏你可以確定信號和噪聲的主要頻​​率分量在哪裏,並且可以決定如何實現濾波器。希望這有幫助 – user3806339 2014-09-24 22:13:16

0

如果您正在嘗試構建無限脈衝響應(IIR)濾波器(我想您是來自代碼),則濾波器方程將是當前輸入樣本和先前輸出樣本的加權和。

由於output[n]還沒有在等式的右邊進行計算,您的噪音可能會出現。

至於設計過濾器,我希望你的數學很好 - 你需要通過第一個原則來理解它是如何工作的。許多人在決定使用過濾器類型和順序後,使用MatLab實際計算係數。

至於教程 - 看看免費的大學課件 - 這是電子工程學位的本科第一年和第二年的材料。

0

兩件事。

首先,一個WAV文件不包含浮點數,它包含整數。通過將它們解碼爲浮點數,你會得到一個完全不合適的信號 - 我很驚訝你可以在輸出中聽到任何東西。

二,您的lowPass函數不做低通濾波器。即使這樣做,你也需要檢查溢出/下溢,並將這些值限制在有效範圍內。

+0

哦,謝謝,但什麼樣的格式最好添加過濾器?,你知道任何一種算法? – Giancarlo 2014-09-25 22:41:37