gpt4 book ai didi

java - Android应用程序可实时录制声音并识别频率

转载 作者:太空狗 更新时间:2023-10-29 12:47:05 24 4
gpt4 key购买 nike

我需要开发一个应用程序来使用手机的麦克风实时记录频率,然后显示它们(以文本形式)。我在这里发布我的代码。 FFT 和复数类已从 http://introcs.cs.princeton.edu/java/97data/FFT.java.html 开始使用和 http://introcs.cs.princeton.edu/java/97data/Complex.java.html .问题是当我在模拟器上运行它时,频率从某个随机值开始并一直增加到 7996。然后它重复整个过程。有人可以帮我吗?

public class Main extends Activity {

TextView disp;
private static int[] sampleRate = new int[] { 44100, 22050, 11025, 8000 };
short audioData[];
double finalData[];
int bufferSize,srate;
String TAG;
public boolean recording;
AudioRecord recorder;
Complex[] fftArray;
float freq;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
disp = (TextView) findViewById(R.id.display);

Thread t1 = new Thread(new Runnable(){

public void run() {

Log.i(TAG,"Setting up recording");
for (int rate : sampleRate) {
try{

Log.d(TAG, "Attempting rate " + rate);

bufferSize=AudioRecord.getMinBufferSize(rate,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT)*3; //get the buffer size to use with this audio record

if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {

recorder = new AudioRecord (MediaRecorder.AudioSource.MIC,rate,AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,2048); //instantiate the AudioRecorder
Log.d(TAG, "BufferSize " +bufferSize);
srate = rate;

}

} catch (Exception e) {
Log.e(TAG, rate + "Exception, keep trying.",e);
}
}
bufferSize=2048;
recording=true; //variable to use start or stop recording
audioData = new short [bufferSize]; //short array that pcm data is put into.
Log.i(TAG,"Got buffer size =" + bufferSize);
while (recording) { //loop while recording is needed
Log.i(TAG,"in while 1");
if (recorder.getState()==android.media.AudioRecord.STATE_INITIALIZED) // check to see if the recorder has initialized yet.
if (recorder.getRecordingState()==android.media.AudioRecord.RECORDSTATE_STOPPED)
recorder.startRecording(); //check to see if the Recorder has stopped or is not recording, and make it record.

else {
Log.i(TAG,"in else");
// audiorecord();
finalData=convert_to_double(audioData);
Findfft();
for(int k=0;k<fftArray.length;k++)
{
freq = ((float)srate/(float) fftArray.length) *(float)k;
runOnUiThread(new Runnable(){
public void run()
{
disp.setText("The frequency is " + freq);
if(freq>=15000)
recording = false;
}
});


}


}//else recorder started

} //while recording

if (recorder.getState()==android.media.AudioRecord.RECORDSTATE_RECORDING)
recorder.stop(); //stop the recorder before ending the thread
recorder.release(); //release the recorders resources
recorder=null; //set the recorder to be garbage collected.

}//run

});
t1.start();
}





private void Findfft() {
// TODO Auto-generated method stub
Complex[] fftTempArray = new Complex[bufferSize];
for (int i=0; i<bufferSize; i++)
{
fftTempArray[i] = new Complex(finalData[i], 0);
}
fftArray = FFT.fft(fftTempArray);
}


private double[] convert_to_double(short data[]) {
// TODO Auto-generated method stub
double[] transformed = new double[data.length];

for (int j=0;j<data.length;j++) {
transformed[j] = (double)data[j];
}

return transformed;

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}

最佳答案

您的问题已得到简洁回答,但是,为了进一步实现您的目标并完成循环...

是的,FFT 在有限的 CPU 上不是最佳的音调/频率识别。 YIN 描述了一种更优化的方法 here .您可以在 Tarsos 找到一个实现.您将面临的问题是 ADK 中缺少 javax.sound.sampled,因此将短裤/字节从 AudioRecord 转换为引用实现所需的 float 。

关于java - Android应用程序可实时录制声音并识别频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16982623/

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