首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >[Android][Kotlin]用AudioRecord实现带通过滤器并写入16位PCM文件

[Android][Kotlin]用AudioRecord实现带通过滤器并写入16位PCM文件
EN

Stack Overflow用户
提问于 2020-10-27 08:12:51
回答 2查看 524关注 0票数 1

摘要:使用Android的AudioRecord,我试图实现一个带通过滤器,并将过滤后的音频写入PCM文件。

到目前为止,我的库尝试过的是:https://github.com/berndporr/iirj/blob/master/src/test/java/uk/me/berndporr/iirj/ButterworthTest.java https://github.com/psambit9791/jDSP/blob/master/src/main/java/com/github/psambit9791/jdsp/filter/Butterworth.java

结果:当查看过滤后的PCM文件时,两者都会导致失真的过滤音频输出。目前使用jDSP巴特沃斯带通滤波器实现。我认为我没有正确地从ByteArray转换为Double,反之亦然。以下是用于此实现的主要信息。

代码语言:javascript
复制
/**
 * This constructor initialises the prerequisites
 * required to use Butterworth filter.
 * @param s Signal to be filtered
 * @param Fs Sampling frequency of input signal
 */
public Butterworth(double[] s, double Fs) {
    this.signal = s;
    this.samplingFreq = Fs;
}

/**
 * This method implements a band pass filter with given parameters, filters the signal and returns it.
 * @param order Order of the filter
 * @param lowCutoff The lower cutoff frequency for the filter in Hz
 * @param highCutoff The upper cutoff frequency for the filter in Hz
 * @throws java.lang.IllegalArgumentException The lower cutoff frequency is greater than the higher cutoff frequency
 * @return double[] Filtered signal
 */
public double[] bandPassFilter(int order, double lowCutoff, double highCutoff) throws IllegalArgumentException{
    if (lowCutoff >= highCutoff) {
        throw new IllegalArgumentException("Lower Cutoff Frequency cannot be more than the Higher Cutoff Frequency");
    }
    double centreFreq = (highCutoff + lowCutoff)/2.0;
    double width = Math.abs(highCutoff - lowCutoff);
    this.output = new double[this.signal.length];
    uk.me.berndporr.iirj.Butterworth bp = new uk.me.berndporr.iirj.Butterworth();
    bp.bandPass(order, this.samplingFreq, centreFreq, width);
    for (int i=0; i<this.output.length; i++) {
        this.output[i] = bp.filter(this.signal[i]);
    }
    return this.output;
}

private val AudioSource = MediaRecorder.AudioSource.MIC
private val SampleRate = 44100
private val Channel = AudioFormat.CHANNEL_IN_MONO
private val EncodingType = AudioFormat.ENCODING_PCM_16BIT

private var bufferSizeInByte: Int = 0

private fun writeDatatoFile() {
    var audioData = ByteArray(bufferSizeInByte)
    val file1 = UNFILTEREDPCM
    val file2 = FILTEREDPCM
    file1.createNewFile()
    file2.createNewFile()

    val out1 = BufferedOutputStream(FileOutputStream(file1))
    val out2 = BufferedOutputStream(FileOutputStream(file2))
    var length = 0

    while (isRecord && audioRecorder != null) {
        length = audioRecorder!!.read(audioData, 0, bufferSizeInByte) // get audio data
        val butterworth = Butterworth(doubleArrayOf(ByteBuffer.wrap(audioData).getDouble()),44100.0)
        val result = butterworth.bandPassFilter(2, 1525.0, 1625.0)
        if (AudioRecord.ERROR_INVALID_OPERATION != length) {
            out1.write(audioData, 0, length) // write file
            out1.flush()
            for (i in 0 until result.size) {
                val newBuffer = ByteBuffer.allocate(bufferSizeInByte).putDouble(result[i]).array()
                out2.write(newBuffer, 0, length)
            }
            out2.flush()
        }
    }
    out1.close()
    out2.close()
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-03 03:47:38

我真的想通了。使用https://github.com/JorenSix/TarsosDSP,库在过滤后不需要转换。它还包含在FFT库中。

票数 0
EN

Stack Overflow用户

发布于 2020-11-01 09:34:10

我认为这个项目可以帮助你:https://github.com/soygabimoreno/RT

具体来说,您可以深入了解这个类:https://github.com/soygabimoreno/RT/blob/master/app/src/main/java/com/appacoustic/rt/domain/calculator/processing/FilterIIR.kt

代码语言:javascript
复制
fun DoubleArray.filterIIR(
    butterworthCoefficients: ButterworthCoefficients
): DoubleArray {
    val nOrder = butterworthCoefficients.nOrder
    val bufferSize = nOrder * 2 + 1
    val buffer = DoubleArray(bufferSize)
    val out = DoubleArray(size)

    for (n in indices) {
        for (i in 0 until bufferSize - 1) {
            buffer[i] = buffer[i + 1]
        }

        buffer[bufferSize - 1] = 0.0
        for (i in 0 until bufferSize) {
            buffer[i] += this[n] * butterworthCoefficients.numeratorDenominator.b[i]
        }

        for (i in 0 until bufferSize - 1) {
            buffer[i + 1] += -buffer[0] * butterworthCoefficients.numeratorDenominator.a[i + 1]
        }
        out[n] = buffer[0]
    }

    return out
}

另一个用来写文件的:https://github.com/soygabimoreno/RT/blob/master/app/src/main/java/com/appacoustic/rt/framework/audio/recorder/Recorder.kt

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64550399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档