studio programacion para herramientas fundamentos desarrollo con avanzado aplicaciones java android android-asynctask fft frequency

java - programacion - Mostrando un doble(frecuencia) que se actualiza constantemente durante la grabaciĆ³n con Android



manual android studio avanzado (3)

SetContentView en onProgressUpdate es un error. Realmente no desea cambiar el diseño xml

Estoy construyendo una aplicación de Android que muestra la frecuencia de una nota sostenida con el algoritmo de FFT. Estoy usando métodos de Jtransform. Mi problema actualmente es que no puedo mostrar la frecuencia en la pantalla. El siguiente código es el cálculo de fft freqency y el AsynchTask que debe mostrar la frecuencia en un cuadro de texto

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<Void, Double, Void>{ @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(); } }

He verificado otras preguntas similares y no puedo encontrar el error en mi código.

EDITAR : agregó onClick() al código. Sé que se está calculando la frecuencia y, de acuerdo con Eclipse, en ningún momento se onProgressUpdate() al onProgressUpdate() .


Intenta reemplazar

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

con

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

Para otros que no tengan jtransforms.jar, consulte http://sourceforge.net/projects/jtransforms/


Además de lo que dijo Alexei , en su respuesta , creo que también ha codificado incorrectamente la firma de método de onProgressUpdate() :

protected void onProgressUpdate(Double value){

Esto significa que su versión de onProgressUpdate() no está anulando nada de AsyncTask , y nunca se llamará.

Entonces, incluyendo el punto sobre no llamar a setContentView() repetidamente, su método final debería verse así:

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