2012-04-30 69 views
2

byte[]サウンドからホワイトノイズを除去するアルゴリズムを誰にでも教えてもらえますか?私はアンドロイドのためのパーソナルオーディオレコーディングアプリのために働き、私は録音のためにアンドロイドAPIを使用します。以下は、録音をファイルに書き込む方法(wav形式)です。java - バイト配列wavファイルからノイズを除去

private AudioRecord.OnRecordPositionUpdateListener updateListener = new AudioRecord.OnRecordPositionUpdateListener() 
{ 
    public void onPeriodicNotification(AudioRecord recorder) 
    { 
     aRecorder.read(buffer, 0, buffer.length); 
     try 
     { 
      fWriter.write(buffer); // Write buffer to file 
      payloadSize += buffer.length; 
      if (bSamples == 16) 
      { 
       for (int i=0; i<buffer.length/2; i++) 
       { // 16bit sample size 
        short curSample = getShort(buffer[i*2], buffer[i*2+1]); 
        if (curSample > cAmplitude) 
        { // Check amplitude 
         cAmplitude = curSample; 
        } 
       } 
      } 
      else 
      { // 8bit sample size 
       for (int i=0; i<buffer.length; i++) 
       { 
        if (buffer[i] > cAmplitude) 
        { // Check amplitude 
         cAmplitude = buffer[i]; 
        } 
       } 
      } 
     } 
     catch (IOException e) 
     { 
      Log.e(AudioRecorder2.class.getName(), "Error occured in updateListener, recording is aborted"); 
     } 
    } 

    public void onMarkerReached(AudioRecord recorder) 
    {} 
}; 

バッファリングにいくつかの変換を適用して、録音再生中に聞こえる白色ノイズを除去したいとします。 誰かが何らかのアルゴリズムを知っている/いくつかの低域フィルター(または役立つかもしれない他のもの)へのリンクがあれば、助けてください。

ありがとうございました。

+4

、あなたの前処理段階で、次のだろう、あなたのオーディオ信号について何かを知っている限り、あなたは、ホワイトノイズを削除することはできません。たとえば、特定の周波数帯域しか占有していないことがわかっている場合は、ローパスフィルタを使用して高周波ノイズを除去できます。しかし、一般的な解決策はありません。 –

+0

私も同じ騒音を得ています。解決策を見つけましたか? – Manoj

+0

いいえ、私はこのプロジェクトを後にしました。見つけたら、ここに返信してください。私はあなたの答えを受け入れます。 –

答えて

0

ローパスを実装する最も簡単な方法は、複数のサンプルを平均することです。あなたはn個のサンプルを持っている場合、あなたはそのような何かを行うことができます:あなたが見ることができるように

// your sample data array 
int[] samples 
//number of samples you want to average 
int AVERAGE_SAMPLE_COUNT = 3; 

for(int i=0; i<samples.length-AVERAGE_SAMPLE_COUNT; i++){ 
    //variable for storing the values of multiple samples 
    int avgSample = 0; 
    for(int a=0; a<AVERAGE_SAMPLE_COUNT; a++){ 
     //add up the current and the next n samples 
     avgSample += samples[i+a] 
    } 
    //devide by the number of samples to average them 
    avgSample /= AVERAGE_SAMPLE_COUNT; 
    //replace first sample with the averaged value 
    samples[i] = avgSample 
} 

、唯一の欠点は、出力がAVERAGE_SAMPLE_COUNTだけ短いを取得していること、であるかもしれません。 AVERAGE_SAMPLE_COUNTを変更することで、アルゴの強さを簡単に試すことができます。 また、インプレースで作業中です。つまり、初期入力データが変更されます。

+1

アベレージングは​​ローパスフィルタとして非常に貧弱です。また、帯域幅の2/3を捨てると、オーディオ品質が悪くなります。 –

+0

ありがとう、私はこのフィルタを実装し、結果を参照してみます。 –

+0

実際、出力の品質はオリジナルよりも悪いです(元々は「少し」のノイズがありますので、そのままにしておきます - 将来的には音の理論を深く勉強し始めますDreams :))お返事ありがとうございました。ありがとうございました。 –

1

あなたがわかっている場合は、サンプルを平均化できます サンプル周波数(8,16,32,64,128)と ビット深度(8,16,32)及び(モノラル、ステレオ)を記録 チャンネルを。

.wavオーディオは、交互に書き込まれるか、またはビット深度のサイズの配列にインターレースされます。 は

16kHzの16ビットは「」

64,000と短い[]オーディオの毎秒16,000エントリと

の64kHz、32ビットがINT []は(私はそれが左チャンネルから始まると思います)

あなたは、[(ショート[さえ] +短い[奇数])/ 2

あなたは16kHzの16ビット周波数128kHzを平均化することができた(8 1)短いステレオからモノラルに行く16ビットのチャネルを平均化することができ0,2,4,6,8,10,12,14]/8

平均16kHz未満周波数はおそらく悪くなるでしょう

オーディオが量子化された方法(アナログからデジタルに線形または対数的にa-law/u-law/linear)によって異なる方法を試す必要があります。

+0

ありがとう、私はモノラルを最初にモノにしようとしています(もし私が間違っていないなら、.wavフレーム(16ビット深度)は2サンプル(4バイト)で構成されます - 右チャンネル用に1サンプル、左用に1サンプル)モノ出力としての結果。 –

0

別のアプローチは、一般的には

recorder.read(data, 0, data.length); 
if(isAudible(data)) { 
    // TODO further processing can go here 
} 

public static boolean isAudible(short[] data) { 
    double rms = getRootMeanSquared(data); 
    return (rms > 198 && 5600 > rms); 
} 

public static double getRootMeanSquared(short[] data) { 
    double ms = 0; 
    for (int i = 0; i < data.length; i++) { 
     ms += data[i] * data[i]; 
    } 
    ms /= data.length; 
    return Math.sqrt(ms); 
} 
関連する問題