Android Open Source - audio-analyzer-for-android Recorder Monitor






From Project

Back to project page audio-analyzer-for-android.

License

The source code is released under:

Apache License

If you think the Android project audio-analyzer-for-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.google.corp.productivity.specialprojects.android.samples.fft;
/* w  w w  . j a  va  2  s . c o  m*/
import android.os.SystemClock;
import android.util.Log;

public class RecorderMonitor {
  final String TAG0 = "RecorderMonitor::";
  String TAG;
  long timeUpdateOld, timeUpdateInterval, timeStarted;  // in ms
  long lastOverrunTime;
  long nSamplesRead;
  int sampleRate;
  int bufferSampleSize;
  double sampleRateReal;
  boolean lastCheckOverrun = false;
  
  public RecorderMonitor(int sampleRateIn, int bufferSampleSizeIn, String TAG1) {
    sampleRate = sampleRateIn;
    bufferSampleSize = bufferSampleSizeIn;
    timeUpdateInterval = 2000;
    TAG = TAG1 + TAG0;
  }

  // When start recording, call this
  public void start() {
    nSamplesRead = 0;
    lastOverrunTime = 0;
    timeStarted = SystemClock.uptimeMillis();
    timeUpdateOld = timeStarted;
    sampleRateReal = sampleRate;
  }

  // Input number of audio frames that read
  // Return true if an overrun check is performed, otherwise false.
  public boolean updateState(int numOfReadShort) {
    long timeNow = SystemClock.uptimeMillis();
    if (nSamplesRead == 0) {      // get overrun checker synchronized
      timeStarted = timeNow - numOfReadShort*1000/sampleRate;
    }
    nSamplesRead += numOfReadShort;
    if (timeUpdateOld + timeUpdateInterval > timeNow) {
      return false;  // do the checks below every timeUpdateInterval ms
    }
    timeUpdateOld += timeUpdateInterval;
    if (timeUpdateOld + timeUpdateInterval <= timeNow) {
      timeUpdateOld = timeNow;  // catch up the time (so that at most one output per timeUpdateInterval)
    }
    long nSamplesFromTime = (long)((timeNow - timeStarted) * sampleRateReal / 1000);
    double f1 = (double) nSamplesRead / sampleRateReal;
    double f2 = (double) nSamplesFromTime / sampleRateReal;
//    Log.i(TAG, "Buffer"
//        + " should read " + nSamplesFromTime + " (" + Math.round(f2*1000)/1000.0 + "s),"
//        + " actual read " + nSamplesRead + " (" + Math.round(f1*1000)/1000.0 + "s)\n"
//        + " diff " + (nSamplesFromTime-nSamplesRead) + " (" + Math.round((f2-f1)*1000)/1e3 + "s)"
//        + " sampleRate = " + Math.round(sampleRateReal*100)/100.0);
    // Check if buffer overrun occur
    if (nSamplesFromTime > bufferSampleSize + nSamplesRead) {
      Log.w(TAG, "Looper::run(): Buffer Overrun occured !\n"
          + " should read " + nSamplesFromTime + " (" + Math.round(f2*1000)/1000.0 + "s),"
          + " actual read " + nSamplesRead + " (" + Math.round(f1*1000)/1000.0 + "s)\n"
          + " diff " + (nSamplesFromTime-nSamplesRead) + " (" + Math.round((f2-f1)*1000)/1e3 + "s)"
          + " sampleRate = " + Math.round(sampleRateReal*100)/100.0
          + "\n Overrun counter reseted.");
      lastOverrunTime = timeNow;
      nSamplesRead = 0;  // start over
    }
    // Update actual sample rate
    if (nSamplesRead > 10*sampleRate) {
      sampleRateReal = 0.9*sampleRateReal + 0.1*(nSamplesRead * 1000.0 / (timeNow - timeStarted));
      if (Math.abs(sampleRateReal-sampleRate) > 0.0145*sampleRate) {  // 0.0145 = 25 cent
        Log.w(TAG, "Looper::run(): Sample rate inaccurate, possible hardware problem !\n"
            + " should read " + nSamplesFromTime + " (" + Math.round(f2*1000)/1000.0 + "s),"
            + " actual read " + nSamplesRead + " (" + Math.round(f1*1000)/1000.0 + "s)\n"
            + " diff " + (nSamplesFromTime-nSamplesRead) + " (" + Math.round((f2-f1)*1000)/1e3 + "s)"
            + " sampleRate = " + Math.round(sampleRateReal*100)/100.0
            + "\n Overrun counter reseted.");
        nSamplesRead = 0;
      }
    }
    lastCheckOverrun = lastOverrunTime == timeNow;
    return true;  // state updated during this check
  }
  
  public boolean getLastCheckOverrun() {
    return lastCheckOverrun;
  }
  
  public long getLastOverrunTime() {
    return lastOverrunTime;
  }
  
  public double getSampleRate() {
    return sampleRateReal;
  }
}




Java Source Code List

com.google.corp.productivity.specialprojects.android.fft.RealDoubleFFT_Mixed.java
com.google.corp.productivity.specialprojects.android.fft.RealDoubleFFT.java
com.google.corp.productivity.specialprojects.android.samples.fft.AnalyzeActivity.java
com.google.corp.productivity.specialprojects.android.samples.fft.AnalyzeView.java
com.google.corp.productivity.specialprojects.android.samples.fft.ColorMapArray.java
com.google.corp.productivity.specialprojects.android.samples.fft.DoubleSineGen.java
com.google.corp.productivity.specialprojects.android.samples.fft.FramesPerSecondCounter.java
com.google.corp.productivity.specialprojects.android.samples.fft.InfoRecActivity.java
com.google.corp.productivity.specialprojects.android.samples.fft.MyPreferences.java
com.google.corp.productivity.specialprojects.android.samples.fft.RecorderMonitor.java
com.google.corp.productivity.specialprojects.android.samples.fft.SBNumFormat.java
com.google.corp.productivity.specialprojects.android.samples.fft.STFT.java
com.google.corp.productivity.specialprojects.android.samples.fft.SelectorText.java
com.google.corp.productivity.specialprojects.android.samples.fft.WavWriter.java