4

Can anyone show me an algorithm of removing white noise from a byte[] sound? I work for a personal audio recording app for android and I use android API for recording. Below is the method used to write the recording to file (in wav format).

 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)
    {}
};

I want to apply some transformations to buffer to remove the white noise which can be heard during playback of the recording. If anybody know some algorithm/link to some low-pass filter (or anything else that might be helpful), please help.

Thanks.

4

3 回答 3

1

如果您知道,您可以平均采样:采样频率 (8,16,32,64,128) 和位深度 (8,16,32) 和记录的通道(单声道、立体声)。

.wav 音频以比特深度大小交替写入或交错排列在数组中。(我认为它从左声道开始)

16kHz 16 位是一个短 [],每秒有 16,000 个音频条目

64kHZ 32 位是一个 int[] 与 64,000 " "

您可以平均从立体声到单声道的 16 位通道 (short[even]+short[odd])/2

你可以平均 16 位频率 128kHz 到 16kHz(8 比 1)短 [0,2,4,6,8,10,12,14]/8

平均低于 16kHZ 的频率可能听起来更糟

根据音频的量化方式(模拟到数字线性或对数 a-law/u-law/linear),您可能需要尝试不同的方法。

于 2013-07-06T03:14:30.020 回答
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 回答
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 回答