显示使用Android录制时不断更新的双倍(频率)

我正在构建一个Android应用程序,它使用FFT算法显示持续音符的频率。 我正在使用Jtransform方法。 我目前的问题是我无法在屏幕上显示频率。 以下代码是fft频率计算和AsynchTask,它应该在文本框中显示频率

import edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D; public class Tuning extends Activity implements OnClickListener{ int audioSource = MediaRecorder.AudioSource.MIC; // Audio source is the device mic int channelConfig = AudioFormat.CHANNEL_IN_MONO; // Recording in mono int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; // Records in 16bit private DoubleFFT_1D fft; // The fft double array int blockSize = 1024; // deal with this many samples at a time int sampleRate = 44100; // Sample rate in Hz public double frequency = 0.0; // the frequency given RecordAudio recordTask; // Creates a Record Audio command TextView tv; // Creates a text view for the frequency // On Start Up @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.tuning); tv = (TextView) findViewById(R.id.lbl1); } // The Record and analysis class private class RecordAudio extends AsyncTask{ @Override protected Void doInBackground(Void... params){ /*Calculates the fft and frequency of the input*/ try{ int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioEncoding); // Gets the minimum buffer needed AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioEncoding, bufferSize); // The RAW PCM sample recording short[] buffer = new short[blockSize]; // Save the raw PCM samples as short bytes double[] audioDataDoubles = new double[(blockSize*2)]; // Same values as above, as doubles double[] re = new double[blockSize]; double[] im = new double[blockSize]; double[] magnitude = new double[blockSize]; audioRecord.startRecording(); // Start working fft = new DoubleFFT_1D(blockSize); while(started){ /* Reads the data from the microphone. it takes in data * to the size of the window "blockSize". The data is then * given in to audioRecord. The int returned is the number * of bytes that were read*/ int bufferReadResult = audioRecord.read(buffer, 0, blockSize); // Read in the data from the mic to the array for(int i = 0; i < blockSize && i < bufferReadResult; i++) { /* dividing the short by 32768.0 gives us the * result in a range -1.0 to 1.0. * Data for the compextForward is given back * as two numbers in sequence. Therefore audioDataDoubles * needs to be twice as large*/ audioDataDoubles[2*i] = (double) buffer[i]/32768.0; // signed 16 bit audioDataDoubles[(2*i)+1] = 0.0; } //audiodataDoubles now holds data to work with fft.complexForward(audioDataDoubles); // Calculate the Real and imaginary and Magnitude. for(int i = 0; i < blockSize; i++){ // real is stored in first part of array re[i] = audioDataDoubles[i*2]; // imaginary is stored in the sequential part im[i] = audioDataDoubles[(i*2)+1]; // magnitude is calculated by the square root of (imaginary^2 + real^2) magnitude[i] = Math.sqrt((re[i] * re[i]) + (im[i]*im[i])); } double peak = -1.0; // Get the largest magnitude peak for(int i = 0; i < blockSize; i++){ if(peak < magnitude[i]) peak = magnitude[i]; } // calculated the frequency frequency = (sampleRate * peak)/blockSize; /* calls onProgressUpdate * publishes the frequency */ publishProgress(frequency); } } catch(Throwable t){ Log.e("AudioRecord", "Recording Failed"); } return null; } // This should display the Frequency protected void onProgressUpdate(Double value){ //print the frequency setContentView(R.layout.tuning); String info = Double.toString(value); //TextView doubleView = (TextView) findViewById(R.id.DoubleView); tv.setText(info); } // For the click of the button public void onClick(View v){ if(started){ started = false; startStopButton.setText("Start"); recordTask.cancel(true); } else { started = true; startStopButton.setText("Stop"); recordTask = new RecordAudio(); recordTask.execute(); } } 

我检查了其他类似的问题,我在代码中找不到错误。

编辑 :添加onClick()代码。 我知道频率正在计算中,根据Eclipse的说法, onProgressUpdate()不会被调用。

除了阿列克谢所说的 , 在他的回答中 ,我认为你还错误地编码了onProgressUpdate()的方法签名:

 protected void onProgressUpdate(Double value){ 

这意味着您的onProgressUpdate()版本实际上没有覆盖AsyncTask中的任何内容,并且永远不会被调用。

因此,包括重复调用setContentView()的观点,您的最终方法应如下所示:

 protected void onProgressUpdate(Double... frequencies){ //print the frequency String info = Double.toString(frequencies[0]); tv.setText(info); } 

onProgressUpdate中的SetContentView是一个错误。 你真的不想改变布局xml

尝试更换

 protected void onProgressUpdate(Double value){ //print the frequency setContentView(R.layout.tuning); String info = Double.toString(value); 

 protected void onProgressUpdate(Double... value){ //print the frequency String info = Double.toString(value[0]); 

对于没有jtransforms.jar的其他人,请参阅http://sourceforge.net/projects/jtransforms/