Note that there are some explanatory texts on larger screens.

plurals
  1. POAsynctask and Handler Thread at the same time?
    primarykey
    data
    text
    <p>I am using FFT to analyze audio coming into the mic in real time and this only seems to work when using asyntask. I also need to run another thread in the background. Both items only need to run for 3 seconds. </p> <p>If I try to do both, the ANR times out. Is there a way to get these to work together? </p> <p>I do not need FFT to be in asynctask since I am only writing to files not the display. However, when I pull FFT out of asynctask I get errors on my toTransform array.</p> <p>Any help is appreciated.</p> <pre><code>public class SoundRecord extends Activity implements OnClickListener { boolean started = false; int sampleRate = 8000; // originally from http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html // and modified by Steve Pomeroy &lt;steve@staticfree.info&gt; private final int duration = 3; // seconds private final int numSamples = duration * sampleRate; private final double sample[] = new double[numSamples]; private final double freqOfTone = 1500; // hz private final byte generatedSnd[] = new byte[2 * numSamples]; Handler handler = new Handler(); Timer timer = new Timer(); public int channelConfiguration = AudioFormat.CHANNEL_IN_MONO; public int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; //FFT private RealDoubleFFT transformer; int blockSize = 256; Button startStopButton; int frequency = 8000; double freq; String freqValue; int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding); AudioRecord audioRecord = new AudioRecord( MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, bufferSize); GetFrequency recordTask; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_SoundRecord); Button button = (Button) findViewById(R.id.start); button.setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.SoundRecord, menu); return true; } @Override public void onClick(View v) { if (started) { started = false; recordTask.cancel(true); } else { final Thread soundout = new Thread(new Runnable() { public void run() { genTone(); handler.post(new Runnable() { public void run() { playSound(); } }); } }); soundout.start(); //Analyze frequency recordTask = new GetFrequency(); try { recordTask.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } void genTone(){ // fill out the array for (int i = 0; i &lt; numSamples; ++i) { sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone)); } // convert to 16 bit pcm sound array // assumes the sample buffer is normalised. int idx = 0; for (final double dVal : sample) { // scale to maximum amplitude final short val = (short) ((dVal * 32767)); // in 16 bit wav PCM, first byte is the low order byte generatedSnd[idx++] = (byte) (val &amp; 0x00ff); generatedSnd[idx++] = (byte) ((val &amp; 0xff00) &gt;&gt;&gt; 8); } } void playSound(){ final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, numSamples, AudioTrack.MODE_STATIC); audioTrack.write(generatedSnd, 0, generatedSnd.length); audioTrack.play(); } private class GetFrequency extends AsyncTask&lt;Void, double[], Void&gt; { @Override protected Void doInBackground(Void... params) { try { short[] buffer = new short[blockSize]; double[] toTransform = new double[blockSize]; audioRecord.startRecording(); while (started) { int bufferReadResult = audioRecord.read(buffer, 0, blockSize); for (int i = 0; i &lt; blockSize &amp;&amp; i &lt; bufferReadResult; i++) { toTransform[i] = (double) buffer[i] / 32768.0; // signed // 16 // bit } transformer.ft(toTransform); publishProgress(toTransform); timer.schedule(new TimerTask() { public void run() { handler.post(new Runnable() { public void run() { audioRecord.stop(); } }); } }, 3000); //Stop after 3 seconds } } catch (Throwable t) { Log.e("AudioRecord", "Recording Failed"); } return null; } protected void onProgressUpdate(double[]... toTransform) { File freqFile = new File("/mnt/sdcard/Test APKs/frequency.file"); File magFile = new File("/mnt/sdcard/Test APKs/magnitude.file"); int blockSize = 256; double[] audioDataDoubles = new double[(blockSize*2)]; String mydate = java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()); if (!freqFile.exists()) { try { freqFile.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (!magFile.exists()) { try { magFile.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for ( int x = 0; x &lt; toTransform[0].length; x++) { audioDataDoubles[2*x] = toTransform[0][x]; audioDataDoubles[(2*x)+1] = 0.0; } double[] re = new double[blockSize]; double[] im = new double[blockSize]; double[] magnitude = new double[blockSize]; // Calculate the Real and imaginary and Magnitude. for(int i = 0; i &lt; 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[(2*i)+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 &lt; blockSize; i++){ if(peak &lt; magnitude[i]) peak = magnitude[i]; String magValue = String.valueOf(peak); try { BufferedWriter buf = new BufferedWriter(new FileWriter(magFile, true)); buf.append(mydate + " - " + magValue); buf.newLine(); buf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // calculated the frequency freq = (frequency * peak)/blockSize; freqValue = String.valueOf(freq); //Toast.makeText(Main.this, freqValue, Toast.LENGTH_SHORT).show(); try { BufferedWriter buf = new BufferedWriter(new FileWriter(freqFile, true)); buf.append(mydate + " - " + freqValue); buf.newLine(); buf.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } </code></pre> <p>}</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload