4

byte[]サウンドからホワイト ノイズを除去するアルゴリズムを教えてもらえますか? 私はAndroid用の個人用オーディオ録音アプリで働いており、録音にはAndroid APIを使用しています。以下は、録音をファイル (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

3 に答える 3

1

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

.wav オーディオは、チャネルを交互に書き込むか、ビット深度のサイズの配列でインターレースします。(左チャンネルから始まると思います)

16kHz 16 ビットは short[] で、1 秒あたり 16,000 エントリのオーディオ

64kHZ 32 ビットは、64,000 " " の int[] です

ステレオからモノへの 16 ビット チャネルを平均化できます (short[even]+short[odd])/2

16 ビット周波数 128kHz から 16kHz (8 から 1) を平均化できます short[0,2,4,6,8,10,12,14]/8

16kHZ よりも低い周波数を平均すると、おそらく音質が悪くなります。

オーディオがどのように量子化されたか (アナログからデジタルへの線形または対数 a-law/u-law/linear) に応じて、さまざまな方法を試す必要がある場合があります。

于 2013-07-06T03:14:30.020 に答える
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);
}
于 2015-06-08T15:23:56.947 に答える
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 を変更することで、アルゴリズムのさまざまな強度を簡単に試すことができます。また、インプレースで動作しているため、最初の入力データが変更されます。

于 2012-04-30T11:19:48.237 に答える