gpt4 book ai didi

java - 识别 Android 中录制的声音的主频率

转载 作者:行者123 更新时间:2023-12-02 10:35:46 25 4
gpt4 key购买 nike

我正在尝试转换位于 https://github.com/rraval/pied-piper/blob/master/decode.py到 Android Java 文件。

第一步是确定主频率。我编写了以下 Java 程序来执行此操作

private class RecordAudio
extends AsyncTask<Void, Void, Void> {

@Override
protected Void doInBackground(Void... paramVarArgs) {
int audioSource = AudioSource.MIC;
int sampleRateInHz = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
byte Data[] = new byte[bufferSizeInBytes];

AudioRecord audioRecorder = new AudioRecord(audioSource,
sampleRateInHz,
channelConfig,
audioFormat,
bufferSizeInBytes);
audioRecorder.startRecording();

boolean isRecording = true;
while (isRecording) {
audioRecorder.read(Data, 0, Data.length);
fftPrint(Data, bufferSizeInBytes);
}
return null;
}

boolean fftPrint(byte[] waveArray, int bufferSizeInBytes) {
double HANDSHAKE_START_HZ = 8192;
double HANDSHAKE_END_HZ = 8192 + 512;
int len = waveArray.length;
double[] waveTransformReal = new double[len];
double[] waveTransformImg = new double[len];

for (int i = 0; i < len; i++) {
waveTransformReal[i] = waveArray[i]; //copy of original
waveTransformImg[i] = waveArray[i]; //FFT transformed below
}

RealDoubleFFT p = new RealDoubleFFT(bufferSizeInBytes);
p.ft(waveTransformImg);

//Calculating abs
double[] abs = new double[len];
for (int i = 0; i < len; i++) {
abs[i] = (Math.sqrt(waveTransformReal[i] * waveTransformReal[i] + waveTransformImg[i] * waveTransformImg[i]));
}

//calculating maxIndex
int maxIndex = 0;
for (int i = 0; i < len; i++) {
if (abs[i] > abs[maxIndex])
maxIndex = i;
}

double dominantFrequency = (maxIndex * 44100) / len;
if (dominantFrequency > 0) Log.d("Freq: ", String.format("%f", dominantFrequency));

if (match(dominantFrequency, HANDSHAKE_START_HZ)) {
Log.i("Handshake start:", "FOUND START");
}
if (match(dominantFrequency, HANDSHAKE_END_HZ)) {
Log.i("Handshake end:", "FOUND END");
return true;
}
return false;
}

boolean match(double freq1, double freq2) {
return (Math.abs(freq1 - freq2) < 20);
}

注意:RealDoubleFFT 来自 ca.uol.aig.fftpack

我不确定我是否做对了。我在 Logcat 中打印了频率,但他们没有找到正在播放的音频中存在的 HANDSHAKE_START_HZ。我做错了什么?

最佳答案

请注意,FFT 幅度峰值的频率分辨率取决于 FFT 的长度(以及窗口等)。您的代码中未指定或限制此长度,因此您不知道任何 FFT 结果箱是否有可能位于目标频率的 20 Hz 范围内。

关于java - 识别 Android 中录制的声音的主频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53305123/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com