RateTransposer.java (2969B)
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 package be.tarsos.dsp.resample; 25 26 import be.tarsos.dsp.AudioEvent; 27 import be.tarsos.dsp.AudioProcessor; 28 29 30 /** 31 * Sample rate transposer. Changes sample rate by using interpolation 32 * 33 * Together with the time stretcher this can be used for pitch shifting. 34 * @author Joren Six 35 */ 36 public class RateTransposer implements AudioProcessor { 37 38 private double factor; 39 private Resampler r; 40 41 /** 42 * Create a new sample rate transposer. The factor determines the new sample 43 * rate. E.g. 0.5 is half the sample rate, 1.0 does not change a thing and 44 * 2.0 doubles the samplerate. If the samples are played at the original 45 * speed the pitch doubles (0.5), does not change (1.0) or halves (0.5) 46 * respectively. Playback length follows the same rules, obviously. 47 * 48 * @param factor 49 * Determines the new sample rate. E.g. 0.5 is half the sample 50 * rate, 1.0 does not change a thing and 2.0 doubles the sample 51 * rate. If the samples are played at the original speed the 52 * pitch doubles (0.5), does not change (1.0) or halves (0.5) 53 * respectively. Playback length follows the same rules, 54 * obviously. 55 */ 56 public RateTransposer(double factor){ 57 this.factor = factor; 58 r= new Resampler(false,0.1,4.0); 59 } 60 61 public void setFactor(double tempo){ 62 this.factor = tempo; 63 } 64 65 @Override 66 public boolean process(AudioEvent audioEvent) { 67 float[] src = audioEvent.getFloatBuffer(); 68 //Creation of float array in loop could be prevented if src.length is known beforehand... 69 //Possible optimization is to instantiate it outside the loop and get a pointer to the 70 //array here, in the process method method. 71 float[] out = new float[(int) (src.length * factor)]; 72 r.process(factor, src, 0, src.length, false, out, 0, out.length); 73 //The size of the output buffer changes (according to factor). 74 audioEvent.setFloatBuffer(out); 75 //Update overlap offset to match new buffer size 76 audioEvent.setOverlap((int) (audioEvent.getOverlap() * factor)); 77 return true; 78 } 79 80 @Override 81 public void processingFinished() { 82 83 } 84 85 }