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 }