android中调用fft函数,J使用PCM数据在Android中转换FFT(JTransforms FFT in Android from PCM data)...
J使用PCM數(shù)據(jù)在Android中轉(zhuǎn)換FFT(JTransforms FFT in Android from PCM data)
我一直在玩這個(gè)游戲已經(jīng)有一段時(shí)間了,我無(wú)法弄清楚我在這里要做的事情。
我正在將PCM音頻數(shù)據(jù)讀入一個(gè)audioData數(shù)組中:
recorder.read(audioData,0,bufferSize); //read the PCM audio data into the audioData array
我想使用Piotr Wendykier的JTransform庫(kù),以便對(duì)我的PCM數(shù)據(jù)進(jìn)行FFT預(yù)處理以獲得頻率。
import edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D;
目前我有這個(gè):
DoubleFFT_1D fft = new DoubleFFT_1D(1024); // 1024 is size of array
for (int i = 0; i < 1023; i++) {
a[i]= audioData[i];
if (audioData[i] != 0)
Log.v(TAG, "audiodata=" + audioData[i] + " fft= " + a[i]);
}
fft.complexForward(a);
我無(wú)法理解如何工作,有人可以給我一些建議嗎? 在這之后我需要進(jìn)行任何計(jì)算嗎?
我確信我走了,任何事情將不勝感激!
本
I've been playing with this now for sometime, I cant work out what I am meant to be doing here.
I am reading in PCM audio data into an audioData array:
recorder.read(audioData,0,bufferSize); //read the PCM audio data into the audioData array
I want to use Piotr Wendykier's JTransform library in order to preform an FFT on my PCM data in order to obtain the frequency.
import edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D;
At the moment I have this:
DoubleFFT_1D fft = new DoubleFFT_1D(1024); // 1024 is size of array
for (int i = 0; i < 1023; i++) {
a[i]= audioData[i];
if (audioData[i] != 0)
Log.v(TAG, "audiodata=" + audioData[i] + " fft= " + a[i]);
}
fft.complexForward(a);
I cant make sense of how to work this, can somebody give me some pointers? Will i have to perform any calculations after this?
I'm sure I'm way off, anything would be greatly appreciated!
Ben
原文:https://stackoverflow.com/questions/7649003
更新時(shí)間:2020-01-09 15:32
最滿意答案
如果您只是在輸入波形中查找單個(gè)正弦波音調(diào)的頻率,那么您需要找到幅度最大的FFT峰值,其中:
Magnitude = sqrt(re*re + im*im)
這個(gè)最大幅度峰值的指數(shù)i會(huì)告訴你你的正弦波的大概頻率:
Frequency = Fs * i / N
哪里:
Fs = sample rate (Hz)
i = index of peak
N = number of points in FFT (1024 in this case)
If you're just looking for the frequency of a single sinusoidal tone in the input waveform then you need to find the FFT peak with the largest magnitude, where:
Magnitude = sqrt(re*re + im*im)
The index i of this largest magnitude peak will tell you the approximate frequency of your sinusoid:
Frequency = Fs * i / N
where:
Fs = sample rate (Hz)
i = index of peak
N = number of points in FFT (1024 in this case)
2011-10-04
相關(guān)問(wèn)答
你的輸入都是0。 short s = 32767;
double d = s/32768;
System.out.println("dividing a short yields a truncated result " + d);
d = (double) s / 32768;
System.out.println("casting to a double and then dividing yields " + d);
Your inputs are all 0. short s = 327
...
首先,您需要確保您獲得的結(jié)果正確轉(zhuǎn)換為float / double。 我不知道短[]版本是如何工作的,但是byte []版本只返回原始字節(jié)版本。 然后,該字節(jié)數(shù)組需要正確轉(zhuǎn)換為浮點(diǎn)數(shù)。 轉(zhuǎn)換代碼應(yīng)該如下所示: double[] micBufferData = new double[];
final int bytesPerSample = 2; // As it is 16bit PCM
final double amplificat
...
您可以使用AudioTrack播放PCM數(shù)據(jù)! 也許是這樣的: int bufsize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audio = new AudioTrack(AudioManager.STREAM_MUSIC,
...
我應(yīng)該使用NDK來(lái)避免這種情況嗎? 不,你會(huì)得到與NDK相同的結(jié)果。 AudioRecord提供對(duì)原始PCM數(shù)據(jù)的訪問(wèn)。 設(shè)備之間的差異發(fā)生,因?yàn)樗鼈兪褂貌煌囊纛l模塊。 這些模塊具有不同的硬件功能 (低通濾波器/靈敏度),您無(wú)法通過(guò)軟件禁用它們。 其背后的原因是這些功能可以降低噪音。 should i use NDK to avoid that? No, you will get the same results with the NDK. AudioRecord provides alread
...
您需要首先將字節(jié)數(shù)組轉(zhuǎn)換為適合您樣本的數(shù)組類型,然后反轉(zhuǎn)該數(shù)組。 例如,如果您的樣本是16位,那么您將要轉(zhuǎn)換為短數(shù)組。 或者,在16位情況下,您可以將數(shù)據(jù)保存為字節(jié)然后反向 - 但是以成對(duì)字節(jié)為單位。 public void reverse(byte[] array) {
if (array == null) {
return;
}
int i = 0;
int j = array.length - 1;
byte t
...
如果您只是在輸入波形中查找單個(gè)正弦波音調(diào)的頻率,那么您需要找到幅度最大的FFT峰值,其中: Magnitude = sqrt(re*re + im*im)
這個(gè)最大幅度峰值的指數(shù)i會(huì)告訴你你的正弦波的大概頻率: Frequency = Fs * i / N
哪里: Fs = sample rate (Hz)
i = index of peak
N = number of points in FFT (1024 in this case)
If you're just looking for
...
假設(shè)音頻是立體聲的,一旦你有兩個(gè)第一個(gè)字節(jié)的原始PCM對(duì)應(yīng)左聲道音頻,兩個(gè)跟隨右聲道音頻,所以你可以將它們視為短路然后第一個(gè)短路代表左聲道和第二個(gè)正確的渠道。 因此,如果您想獲得左聲道數(shù)據(jù),則必須使用輸入原始PCM進(jìn)行循環(huán)并保存每一個(gè)短路。 喜歡這個(gè): void demux(short in[], short left[], short right[], int len) {
for (int i=0; i
left[i] = in[i];
...
是的,它是原始PCM,您可以使用Android SDK掛接到PCM播放。 Yes it's raw PCM , you can hook into the PCM playback with the Android SDK.
來(lái)自android-ndk-r8b / docs / opensles / index.html PCM數(shù)據(jù)格式 PCM數(shù)據(jù)格式只能與緩沖區(qū)隊(duì)列一起使用。 所以SLDataFormat_PCM 不能像我假設(shè)的那樣與SLDataLocator_Address一起使用。 我可以使用緩沖區(qū)隊(duì)列執(zhí)行我想要的操作,而不是像這樣使用一個(gè)大隊(duì)列 bufferqueueitf->Enqueue(bufferqueueitf,dataChunk,dataSize);
from android-ndk-r8b/do
...
你的問(wèn)題是java中的短路是bigendian,但是如果從WAV文件中獲取數(shù)據(jù),那么數(shù)據(jù)就是小端。 Your problem is that shorts in java are bigendian, but if you got your data from a WAV file the data is little endian.
總結(jié)
以上是生活随笔為你收集整理的android中调用fft函数,J使用PCM数据在Android中转换FFT(JTransforms FFT in Android from PCM data)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android端发送字符到Wed端,An
- 下一篇: android sina oauth2.