Android AudioRecord 过滤频率范围 [英] Android AudioRecord filter range of frequency

查看:41
本文介绍了Android AudioRecord 过滤频率范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用android平台,从以下参考问题我知道使用返回原始数据的AudioRecord类我可以过滤音频范围取决于我的需要,但为此我需要算法,有人可以帮我吗找出算法来过滤范围 b/w 14,400 bph 和 16,200 bph.

I am using android platform, from the following reference question I come to know that using AudioRecord class which returns raw data I can filter range of audio frequency depends upon my need but for that I will need algorithm, can somebody please help me out to find algorithm to filter range b/w 14,400 bph and 16,200 bph.

我尝试过JTransform",但我不知道是否可以使用 JTransform 来实现?目前我正在使用jfftpack"来显示效果很好的视觉效果,但我无法使用它实现音频过滤.

I tried "JTransform" but i don't know can I achieve this with JTransform or not ? Currently I am using "jfftpack" to display visual effects which works very well but i can't achieve audio filter using this.

参考这里

感谢帮助 提前致谢.以下是我上面提到的代码,我正在使用jfftpack"库来显示您可能会在代码中找到这个库引用,请不要与此混淆

help appreciated Thanks in advance. Following is my code as i mentioned above i am using "jfftpack" library to display you may find this library reference in the code please don't get confuse with that

private class RecordAudio extends AsyncTask<Void, double[], Void> {
        @Override
        protected Void doInBackground(Void... params) {
try {
    final AudioRecord audioRecord = findAudioRecord();
                    if(audioRecord == null){
                        return null;
                    }

                    final short[] buffer = new short[blockSize];
                    final double[] toTransform = new double[blockSize];

                    audioRecord.startRecording();


    while (started) {
                        final int bufferReadResult = audioRecord.read(buffer, 0, blockSize);

                        for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                            toTransform[i] = (double) buffer[i] / 32768.0; // signed 16 bit
                        }

                        transformer.ft(toTransform);
                        publishProgress(toTransform);

                    }
audioRecord.stop();
                audioRecord.release();
} catch (Throwable t) {
                Log.e("AudioRecord", "Recording Failed");
            }
            return null;

/**
         * @param toTransform
         */
        protected void onProgressUpdate(double[]... toTransform) {
            canvas.drawColor(Color.BLACK);
            for (int i = 0; i < toTransform[0].length; i++) {
                int x = i;
                int downy = (int) (100 - (toTransform[0][i] * 10));
                int upy = 100;
                canvas.drawLine(x, downy, x, upy, paint);
            }
            imageView.invalidate();
        }

推荐答案

在这个过程中有很多微小的细节可能会让你陷入困境.这段代码没有经过测试,我也不经常进行音频过滤,所以你应该非常在这里怀疑.这是过滤音频的基本过程:

There are a lot of tiny details in this process that can potentially hang you up here. This code isn't tested and I don't do audio filtering very often so you should be extremely suspicious here. This is the basic process you would take for filtering audio:

  1. 获取音频缓冲区
  2. 可能的音频缓冲区转换(字节到浮点数)
  3. (可选)应用加窗函数,即 Hanning
  4. 进行 FFT
  5. 过滤频率
  6. 进行逆 FFT

我假设您对 Android 和录音有一些基本的了解,因此将在此处介绍第 4-6 步.

I'm assuming you have some basic knowledge of Android and audio recording so will cover steps 4-6 here.

//it is assumed that a float array audioBuffer exists with even length = to 
//the capture size of your audio buffer

//The size of the FFT will be the size of your audioBuffer / 2
int FFT_SIZE = bufferSize / 2;
FloatFFT_1D mFFT = new FloatFFT_1D(FFT_SIZE); //this is a jTransforms type

//Take the FFT
mFFT.realForward(audioBuffer);

//The first 1/2 of audioBuffer now contains bins that represent the frequency
//of your wave, in a way.  To get the actual frequency from the bin:
//frequency_of_bin = bin_index * sample_rate / FFT_SIZE

//assuming the length of audioBuffer is even, the real and imaginary parts will be
//stored as follows
//audioBuffer[2*k] = Re[k], 0<=k<n/2
//audioBuffer[2*k+1] = Im[k], 0<k<n/2

//Define the frequencies of interest
float freqMin = 14400;
float freqMax = 16200;

//Loop through the fft bins and filter frequencies
for(int fftBin = 0; fftBin < FFT_SIZE; fftBin++){        
    //Calculate the frequency of this bin assuming a sampling rate of 44,100 Hz
    float frequency = (float)fftBin * 44100F / (float)FFT_SIZE;

    //Now filter the audio, I'm assuming you wanted to keep the
    //frequencies of interest rather than discard them.
    if(frequency  < freqMin || frequency > freqMax){
        //Calculate the index where the real and imaginary parts are stored
        int real = 2 * fftBin;
        int imaginary = 2 * fftBin + 1;

        //zero out this frequency
        audioBuffer[real] = 0;
        audioBuffer[imaginary] = 0;
    }
}

//Take the inverse FFT to convert signal from frequency to time domain
mFFT.realInverse(audioBuffer, false);

这篇关于Android AudioRecord 过滤频率范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆