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

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -