【发布时间】:2018-03-05 10:24:06
【问题描述】:
我正在按照这个示例转换为 FFT http://som-itsolutions.blogspot.com.ee/2012/01/fft-based-simple-spectrum-analyzer.html。我已经让它运行了,但我得到的结果非常奇怪。如果我使用 transofrmer(来自 FFT 类),我得到的都是 0。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.kaka);
int bufferSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
audioRecord = new AudioRecord(
MediaRecorder.AudioSource.DEFAULT, frequency,
channelConfiguration, audioEncoding, bufferSize);
buffer = new short[blockSize];
toTransform = new double[blockSize];
try {
audioRecord.startRecording();
} catch (IllegalStateException e) {
Log.e("Recording failed", e.toString());
}
transformer = new RealDoubleFFT(blockSize);
final Runnable r = new Runnable() {
public void run() {
Log.d("Amplify","HERE");
Toast.makeText(getBaseContext(), "Working!", Toast.LENGTH_LONG).show();
runOnUiThread(new Runnable() {
@Override
public void run() {
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);
text.setText("result:" + toTransform[10]);
handler.postDelayed(this, 150); // amount of delay between every cycle of volume level detection
}
});
}
};
handler.postDelayed(r, 80);
我还看到一段代码,上面说你必须从我第一次提供的链接中实现代码并添加这个方法来计算它:
public static int calculate(int sampleRate, short [] audioData){
int numSamples = audioData.length;
int numCrossing = 0;
for (int p = 0; p < numSamples-1; p++)
{
if ((audioData[p] > 0 && audioData[p + 1] <= 0) ||
(audioData[p] < 0 && audioData[p + 1] >= 0))
{
numCrossing++;
}
}
float numSecondsRecorded = (float)numSamples/(float)sampleRate;
float numCycles = numCrossing/2;
float frequency = numCycles/numSecondsRecorded;
return (int)frequency;
}
方法calculate有2个参数,第一个是samplerate,另一个是short[] audiodata。我尝试将“缓冲区”作为变量,但我得到的结果与预期的结果相去甚远。
有没有人熟悉这个例子,或者有人可以向我解释如何从:audiorecord.read(...) 获取数据。我了解您设置音频记录以记录输入的部分,但是当您 .read 数据时究竟发生了什么是我不明白的。
涉及所有 FFT 转换类确实很难,但这里是本示例中使用的 .ft:
public void ft(double x[]){
if(x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
rfftf(ndim, x, wavetable);
}
我知道这一定令人困惑,所以我会尝试总结一下,我的问题是:
audiorecord.read(..) 提供什么输出以及如何使用它?
如果我要使用计算方法,那么预期的输入是什么?
FFT 变换给我一个长度为 2048 的数组,里面的所有整数都是 0.00,我该怎么办?
也许我的做法完全错误,我不需要使用 FFT 从用户输入中获取频率。但结果我不需要绘制图表,我只需要根据频率变化(更高/更低)移动图像。
【问题讨论】:
标签: android audio fft audiorecord