plectrum

Plectrum: instrument tuner for Android
Log | Files | Refs | README | LICENSE

SilenceDetector.java (4033B)


      1 /*
      2 *      _______                       _____   _____ _____  
      3 *     |__   __|                     |  __ \ / ____|  __ \ 
      4 *        | | __ _ _ __ ___  ___  ___| |  | | (___ | |__) |
      5 *        | |/ _` | '__/ __|/ _ \/ __| |  | |\___ \|  ___/ 
      6 *        | | (_| | |  \__ \ (_) \__ \ |__| |____) | |     
      7 *        |_|\__,_|_|  |___/\___/|___/_____/|_____/|_|     
      8 *                                                         
      9 * -------------------------------------------------------------
     10 *
     11 * TarsosDSP is developed by Joren Six at IPEM, University Ghent
     12 *  
     13 * -------------------------------------------------------------
     14 *
     15 *  Info: http://0110.be/tag/TarsosDSP
     16 *  Github: https://github.com/JorenSix/TarsosDSP
     17 *  Releases: http://0110.be/releases/TarsosDSP/
     18 *  
     19 *  TarsosDSP includes modified source code by various authors,
     20 *  for credits and info, see README.
     21 * 
     22 */
     23 
     24 
     25 package be.tarsos.dsp;
     26 
     27 
     28 /**
     29  * The continuing silence detector does not break the audio processing pipeline when silence is detected.
     30  */
     31 public class SilenceDetector implements AudioProcessor {
     32 	
     33 	public static final double DEFAULT_SILENCE_THRESHOLD = -70.0;//db
     34 	
     35 	private final double threshold;//db
     36 	
     37 	private final boolean breakProcessingQueueOnSilence;
     38 	
     39 	/**
     40 	 * Create a new silence detector with a default threshold.
     41 	 */
     42 	public SilenceDetector(){
     43 		this(DEFAULT_SILENCE_THRESHOLD,false);
     44 	}
     45 	
     46 	/**
     47 	 * Create a new silence detector with a defined threshold.
     48 	 * 
     49 	 * @param silenceThreshold
     50 	 *            The threshold which defines when a buffer is silent (in dB).
     51 	 *            Normal values are [-70.0,-30.0] dB SPL.
     52 	 * @param breakProcessingQueueOnSilence 
     53 	 */
     54 	public SilenceDetector(final double silenceThreshold,boolean breakProcessingQueueOnSilence){
     55 		this.threshold = silenceThreshold;
     56 		this.breakProcessingQueueOnSilence = breakProcessingQueueOnSilence;
     57 	}
     58 
     59 	/**
     60 	 * Calculates and returns the root mean square of the signal. Please
     61 	 * cache the result since it is calculated every time.
     62 	 * @param floatBuffer The audio buffer to calculate the RMS for.
     63 	 * @return The <a
     64 	 *         href="http://en.wikipedia.org/wiki/Root_mean_square">RMS</a> of
     65 	 *         the signal present in the current buffer.
     66 	 */
     67 	public static double calculateRMS(float[] floatBuffer){
     68 		double rms = 0.0;
     69 		for (int i = 0; i < floatBuffer.length; i++) {
     70 			rms += floatBuffer[i] * floatBuffer[i];
     71 		}
     72 		rms = rms / Double.valueOf(floatBuffer.length);
     73 		rms = Math.sqrt(rms);
     74 		return rms;
     75 	}
     76 
     77 	/**
     78 	 * Returns the dBSPL for a buffer.
     79 	 * 
     80 	 * @param buffer
     81 	 *            The buffer with audio information.
     82 	 * @return The dBSPL level for the buffer.
     83 	 */
     84 	private static double soundPressureLevel(final float[] buffer) {
     85 		double rms = calculateRMS(buffer);
     86 		return linearToDecibel(rms);
     87 	}
     88 
     89 	/**
     90 	 * Converts a linear to a dB value.
     91 	 * 
     92 	 * @param value
     93 	 *            The value to convert.
     94 	 * @return The converted value.
     95 	 */
     96 	private static double linearToDecibel(final double value) {
     97 		return 20.0 * Math.log10(value);
     98 	}
     99 	
    100 	double currentSPL = 0;
    101 	public double currentSPL(){
    102 		return currentSPL;
    103 	}
    104 
    105 	/**
    106 	 * Checks if the dBSPL level in the buffer falls below a certain threshold.
    107 	 * 
    108 	 * @param buffer
    109 	 *            The buffer with audio information.
    110 	 * @param silenceThreshold
    111 	 *            The threshold in dBSPL
    112 	 * @return True if the audio information in buffer corresponds with silence,
    113 	 *         false otherwise.
    114 	 */
    115 	public boolean isSilence(final float[] buffer, final double silenceThreshold) {
    116 		currentSPL = soundPressureLevel(buffer);
    117 		return currentSPL < silenceThreshold;
    118 	}
    119 
    120 	public boolean isSilence(final float[] buffer) {
    121 		return isSilence(buffer, threshold);
    122 	}
    123 
    124 
    125 	@Override
    126 	public boolean process(AudioEvent audioEvent) {
    127 		boolean isSilence = isSilence(audioEvent.getFloatBuffer());
    128 		//break processing chain on silence?
    129 		if(breakProcessingQueueOnSilence){
    130 			//break if silent
    131 			return !isSilence;
    132 		}else{
    133 			//never break the chain
    134 			return true;
    135 		}
    136 	}
    137 
    138 
    139 	@Override
    140 	public void processingFinished() {
    141 	}
    142 }