Java 对音频信号实现高通滤波器

Java 对音频信号实现高通滤波器,java,android,signal-processing,highpass-filter,Java,Android,Signal Processing,Highpass Filter,我能够编写一个程序来捕获音频信号,消除背景噪音,应用窗口功能并可视化该信号。我的程序一直工作到这一点,没有错误。现在我正试图在代码中实现高通滤波器。我已经找到了此部件的API。但我无法根据我的代码应用它。这是我的密码: private class RecordAudio extends AsyncTask<Void, double[], Void> { @Override protected Void doInBackground(Void... params) {

我能够编写一个程序来捕获音频信号,消除背景噪音,应用窗口功能并可视化该信号。我的程序一直工作到这一点,没有错误。现在我正试图在代码中实现高通滤波器。我已经找到了此部件的API。但我无法根据我的代码应用它。这是我的密码:

private class RecordAudio extends AsyncTask<Void, double[], Void> {
    @Override
    protected Void doInBackground(Void... params) {
        started = true;
        try {
            DataOutputStream dos = new DataOutputStream(
                    new BufferedOutputStream(new FileOutputStream(
                            recordingFile)));
            int bufferSize = AudioRecord.getMinBufferSize(frequency,
                    channelConfiguration, audioEncoding);
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    frequency, channelConfiguration, audioEncoding,
                    bufferSize);

            NoiseSuppressor.create(audioRecord.getAudioSessionId());
            short[] buffer = new short[blockSize];
            double[] toTransform = new double[blockSize];
            long t = System.currentTimeMillis();
            long end = t + 15000;
            audioRecord.startRecording();

            while (started && System.currentTimeMillis() < end) {
                int bufferReadResult = audioRecord.read(buffer, 0,
                        blockSize);
                for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
                    toTransform[i] = (double) buffer[i] / 32768.0;
                    dos.writeShort(buffer[i]);
                }
                toTransform = hann(toTransform);
                transformer.ft(toTransform);
                publishProgress(toTransform);
            } 
            audioRecord.stop();
            dos.close();
        } catch (Throwable t) {
            Log.e("AudioRecord", "Recording Failed");
        }
        return null;
    }
私有类RecordAudio扩展异步任务{
@凌驾
受保护的Void doInBackground(Void…参数){
开始=真;
试一试{
DataOutputStream dos=新的DataOutputStream(
新建BufferedOutputStream(新文件输出流(
记录文件);
int bufferSize=AudioRecord.getMinBufferSize(频率,
信道配置、音频编码);
音频记录=新的音频记录(MediaRecorder.AudioSource.MIC、,
频率、信道配置、音频编码、,
缓冲区大小);
NoiseSuppressor.create(audioRecord.getAudioSessionId());
short[]buffer=新的short[blockSize];
double[]toTransform=新的double[blockSize];
long t=System.currentTimeMillis();
长端=t+15000;
录音。开始录制();
while(已启动&System.currentTimeMillis()
是API链接

有人能帮我做这个功能吗?我会非常感激的!:)


提前感谢!

这是我从c#中找到的库中转换为java的类。我使用它,它工作得很好。你也可以将这个类用于低通滤波器

public class Filter {


/// <summary>
/// rez amount, from sqrt(2) to ~ 0.1
/// </summary>
private float resonance;

private float frequency;
private int sampleRate;
private PassType passType;


public float value;

private float c, a1, a2, a3, b1, b2;

/// <summary>
/// Array of input values, latest are in front
/// </summary>
private float[] inputHistory = new float[2];

/// <summary>
/// Array of output values, latest are in front
/// </summary>
private float[] outputHistory = new float[3];

public Filter(float frequency, int sampleRate, PassType passType, float resonance)
{
    this.resonance = resonance;
    this.frequency = frequency;
    this.sampleRate = sampleRate;
    this.passType = passType;

    switch (passType)
    {
        case Lowpass:
            c = 1.0f / (float)Math.tan(Math.PI * frequency / sampleRate);
            a1 = 1.0f / (1.0f + resonance * c + c * c);
            a2 = 2f * a1;
            a3 = a1;
            b1 = 2.0f * (1.0f - c * c) * a1;
            b2 = (1.0f - resonance * c + c * c) * a1;
            break;
        case Highpass:
            c = (float)Math.tan(Math.PI * frequency / sampleRate);
            a1 = 1.0f / (1.0f + resonance * c + c * c);
            a2 = -2f * a1;
            a3 = a1;
            b1 = 2.0f * (c * c - 1.0f) * a1;
            b2 = (1.0f - resonance * c + c * c) * a1;
            break;
    }
}

public enum PassType
{
    Highpass,
    Lowpass,
}

public void Update(float newInput)
{
    float newOutput = a1 * newInput + a2 * this.inputHistory[0] + a3 * this.inputHistory[1] - b1 * this.outputHistory[0] - b2 * this.outputHistory[1];

    this.inputHistory[1] = this.inputHistory[0];
    this.inputHistory[0] = newInput;

    this.outputHistory[2] = this.outputHistory[1];
    this.outputHistory[1] = this.outputHistory[0];
    this.outputHistory[0] = newOutput;
}


public float getValue()
{
    return this.outputHistory[0];
}


}
公共类过滤器{
/// 
///rez量,从sqrt(2)到~0.1
/// 
私人浮动共振;
私人浮动频率;
私人int采样器;
私有PassType PassType;
公众浮动价值;
专用浮球c、a1、a2、a3、b1、b2;
/// 
///输入值数组,最新值在前面
/// 
private float[]inputhhistory=新float[2];
/// 
///输出值数组,最新值在前面
/// 
私有浮点[]outputhhistory=新浮点[3];
公共滤波器(浮子频率、int采样器、PassType PassType、浮子共振)
{
这个共振=共振;
这个频率=频率;
this.sampleRate=sampleRate;
this.passType=passType;
交换机(passType)
{
外壳低通:
c=1.0f/(浮点数)数学tan(数学π*频率/采样器);
a1=1.0f/(1.0f+共振*c+c*c);
a2=2f*a1;
a3=a1;
b1=2.0f*(1.0f-c*c)*a1;
b2=(1.0f-共振*c+c*c)*a1;
打破
案例高通:
c=(浮点数)Math.tan(Math.PI*频率/采样器);
a1=1.0f/(1.0f+共振*c+c*c);
a2=-2f*a1;
a3=a1;
b1=2.0f*(c*c-1.0f)*a1;
b2=(1.0f-共振*c+c*c)*a1;
打破
}
}
公共枚举密码类型
{
高通公司,
低通,
}
公共void更新(float newInput)
{
float newOutput=a1*newInput+a2*this.inpurthistory[0]+a3*this.inpurthistory[1]-b1*this.outpurthistory[0]-b2*this.outpurthistory[1];
this.inpusthistory[1]=this.inpusthistory[0];
this.inputHistory[0]=newInput;
this.outputhhistory[2]=this.outputhhistory[1];
this.outputhhistory[1]=this.outputhhistory[0];
this.outputhHistory[0]=新输出;
}
公共浮点getValue()
{
返回此。输出历史记录[0];
}
}
我就是这样用的

    Filter filter = new Filter(15000,44100, Filter.PassType.Highpass,1);
    for (int i = 0; i < numSamples; i++)
    {
        filter.Update(floatArray[i]);
        floatArray[i] = filter.getValue();
    }
Filter-Filter=新的过滤器(1500044100,Filter.PassType.Highpass,1);
对于(int i=0;i
在得到浮点数组的fft后,您会看到它被过滤了。
希望有帮助

你3天前问了[同一个问题][1]:@Jens是的。我再次发布了它,因为它对我没有帮助。不管怎样,昨天晚上我能够实现高通滤波功能。那么我需要做什么?我需要关闭这个问题吗?因为我是stackoverflow新手。通常,你会在对第一个问题的回答中添加一条评论,澄清为什么回答没有回答您的问题。也许可以重新表述(编辑)您的原始问题以提高可读性。请记住,StackOverflow用户在提出这些问题后很长一段时间都在阅读这些问题。好的,谢谢Jens……干杯!…:)这是有效的,但我们如何将其应用于ECG?有什么想法吗