plectrum

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

PitchProcessor.java (4582B)


      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.pitch;
     26 
     27 import be.tarsos.dsp.AudioEvent;
     28 import be.tarsos.dsp.AudioProcessor;
     29 
     30 
     31 /**
     32  * Is responsible to call a pitch estimation algorithm. It also calculates progress. 
     33  * The underlying pitch detection algorithm must implement the {@link PitchDetector} interface. 
     34  * @author Joren Six
     35  */
     36 public class PitchProcessor implements AudioProcessor {
     37 	
     38 	/**
     39 	 * A list of pitch estimation algorithms.
     40 	 * @author Joren Six
     41 	 */
     42 	public enum PitchEstimationAlgorithm {
     43 		/**
     44 		 * See {@link Yin} for the implementation. Or see <a href=
     45 		 * "http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf"
     46 		 * >the YIN article</a>.
     47 		 */
     48 		YIN,
     49 		/**
     50 		 * See {@link McLeodPitchMethod}. It is described in the article "<a
     51 		 * href=
     52 		 * "http://miracle.otago.ac.nz/postgrads/tartini/papers/A_Smarter_Way_to_Find_Pitch.pdf"
     53 		 * >A Smarter Way to Find Pitch</a>".
     54 		 */
     55 		MPM,
     56 		/**
     57 		 * A YIN implementation with a faster  {@link FastYin} for the implementation. Or see <a href=
     58 		 * "http://recherche.ircam.fr/equipes/pcm/cheveign/ps/2002_JASA_YIN_proof.pdf"
     59 		 * >the YIN article</a>.
     60 		 */
     61 		FFT_YIN,
     62 		/**
     63 		 * An implementation of a dynamic wavelet pitch detection algorithm (See
     64 		 * {@link DynamicWavelet}), described in a paper by Eric Larson and Ross
     65 		 * Maddox <a href= http://online.physics.uiuc
     66 		 * .edu/courses/phys498pom/NSF_REU_Reports/2005_reu/Real
     67 		 * -Time_Time-Domain_Pitch_Tracking_Using_Wavelets.pdf">"Real-Time
     68 		 * Time-Domain Pitch Tracking Using Wavelets</a>
     69 		 */
     70 		DYNAMIC_WAVELET,
     71 		/**
     72 		 * Returns the frequency of the FFT-bin with most energy.
     73 		 */
     74 		FFT_PITCH,
     75 		/**
     76 		 * A pitch extractor that extracts the Average Magnitude Difference
     77 		 * (AMDF) from an audio buffer. This is a good measure of the Pitch (f0)
     78 		 * of a signal.
     79 		 */
     80 		AMDF;
     81 		
     82 		/**
     83 		 * Returns a new instance of a pitch detector object based on the provided values.
     84 		 * @param sampleRate The sample rate of the audio buffer.
     85 		 * @param bufferSize The size (in samples) of the audio buffer.
     86 		 * @return A new pitch detector object.
     87 		 */
     88 		public PitchDetector getDetector(float sampleRate,int bufferSize){
     89 			PitchDetector detector;
     90 			if (this == MPM ) {
     91 				detector = new McLeodPitchMethod(sampleRate, bufferSize);
     92 			} else if(this == DYNAMIC_WAVELET ) {
     93 				detector = new DynamicWavelet(sampleRate,bufferSize);
     94 			} else if(this == FFT_YIN){
     95 				detector = new FastYin(sampleRate, bufferSize);
     96 			} else if(this==AMDF){
     97 				detector = new AMDF(sampleRate, bufferSize);
     98 			} else if (this == FFT_PITCH){
     99 				detector = new FFTPitch(Math.round(sampleRate),bufferSize);
    100 			} else {
    101 				detector = new Yin(sampleRate, bufferSize);
    102 			}
    103 			return detector;
    104 		}
    105 		
    106 	};
    107 	
    108 	/**
    109 	 * The underlying pitch detector;
    110 	 */
    111 	private final PitchDetector detector;
    112 	
    113 	private final PitchDetectionHandler handler;
    114 	
    115 	/**
    116 	 * Initialize a new pitch processor.
    117 	 * 
    118 	 * @param algorithm
    119 	 *            An enum defining the algorithm.
    120 	 * @param sampleRate
    121 	 *            The sample rate of the buffer (Hz).
    122 	 * @param bufferSize
    123 	 *            The size of the buffer in samples.
    124 	 * @param handler
    125 	 *            The handler handles detected pitch.
    126 	 */
    127 	public PitchProcessor(PitchEstimationAlgorithm algorithm, float sampleRate,
    128 			int bufferSize,
    129 			PitchDetectionHandler handler) {
    130 		detector = algorithm.getDetector(sampleRate, bufferSize);
    131 		this.handler = handler;	
    132 	}
    133 	
    134 	@Override
    135 	public boolean process(AudioEvent audioEvent) {
    136 		float[] audioFloatBuffer = audioEvent.getFloatBuffer();
    137 		
    138 		PitchDetectionResult result = detector.getPitch(audioFloatBuffer);
    139 		
    140 		
    141 		handler.handlePitch(result,audioEvent);
    142 		return true;
    143 	}
    144 
    145 	@Override
    146 	public void processingFinished() {
    147 	}
    148 
    149 	
    150 }