android - Changing block size causes FFT analysis to fail -
i'm trying record audio , frequencies. can sampling rate of 44100 , block size of 2048. bin size around 20, believe. however, if try increase block size 4096, rather accurate frequencies, same inaccurate frequency back, no magnitude/decibels.
my recording task follows:
private class recordaudio extends asynctask<void, double[], boolean> { @override protected boolean doinbackground(void... params) { int buffersize = audiorecord.getminbuffersize(frequency, channelconfiguration, audioencoding); audiorecord = new audiorecord( mediarecorder.audiosource.default, frequency, channelconfiguration, audioencoding, buffersize); int bufferreadresult; short[] buffer = new short[blocksize]; double[] totransform = new double[blocksize]; try { audiorecord.startrecording(); } catch (illegalstateexception e) { log.e("recording failed", e.tostring()); } while (started) { if (iscancelled() || (cancelled_flag == true)) { started = false; //publishprogress(cancelledresult); log.d("doinbackground", "cancelling recordtask"); break; } else { bufferreadresult = audiorecord.read(buffer, 0, blocksize); (int = 0; < blocksize && < bufferreadresult; i++) { totransform[i] = (double) buffer[i] / 32768.0; // signed 16 bit } transformer.ft(totransform); publishprogress(totransform); } } return true; } @override protected void onprogressupdate(double[]...progress) { int mpeakpos = 0; double mmaxfftsample = 150.0; (int = 100; < progress[0].length; i++) { int x = i; int downy = (int) (150 - (progress[0][i] * 10)); int upy = 150; //log.i("settt", "x: " + + " downy: " + downy + " upy: " + upy); if(downy < mmaxfftsample) { mmaxfftsample = downy; mmag = mmaxfftsample; mpeakpos = i; } } mfreq = (((1.0 * frequency) / (1.0 * blocksize)) * mpeakpos)/2; //log.i("sss", "f: " + mfreq + " / " + "m: " + mmag); log.i("settt", "freq: " + mfreq + " mag: " + mmaxfftsample); } @override protected void onpostexecute(boolean result) { super.onpostexecute(result); try{ audiorecord.stop(); } catch(illegalstateexception e){ log.e("stop failed", e.tostring()); } } }
hoping there quick fix i'm missing. thanks.
you'll need closer @ documentation of realdoublefft.ft
function. values going function real values coming out complex fft coefficients such totransform[0]
real part of first coefficient, totransform[1]
imaginary part of first coefficient , on. final array size same since complex numbers each take 2 doubles there total of n/2 coefficients last 1 coefficient samplerate/2.
next since interested in magnitude need compute magnitude of complex numbers. complex number x = + bj
, magnitude |x| = sqrt(a*a + b*b)
double maxmag = 0; int peakindex = 0; (int = 0; < progress[0].length/2; i++) { double re = progress[i*2]; double im = progress[i*2+1]; double mag = math.sqrt(re*re + im*im); if (mag > maxmag) { peakindex = i; maxmag = mag; } } double peakfreq = samplerate/fftlen * i/2; // might need bit of tweaking. double magindb = 20*math.log10(mag);
Comments
Post a Comment