PhaseVocoder extends FrameOverlapAddSource { public int computeOutputLength(int inputLengthInSamples) { int f = frameProvider.getFrameLengthSamples(); int so = blockSize; int si = frameProvider.getFrameShiftSamples(); assert si == getInputFrameshift(so); int n = (int) Math.ceil(((double)inputLengthInSamples - f) / si); int delta = f+n*si - inputLengthInSamples; assert delta < si; int lo = f+n*so - delta; return lo; } PhaseVocoder(DoubleDataSource inputSource, int samplingRate, double rateChangeFactor); int computeOutputLength(int inputLengthInSamples); static void main(String[] args); static final int DEFAULT_FRAMELENGTH; }
@Test public void testStretch1() { double[] signal = FFTTest.getSampleSignal(16000); int samplingRate = 8000; double rateFactor = 0.5; PhaseVocoder pv = new PhaseVocoder(new BufferedDoubleDataSource(signal), samplingRate, rateFactor); double[] result = pv.getAllData(); int expectedLength = pv.computeOutputLength(signal.length); assertTrue("Expected result length: " + expectedLength +", found: "+result.length, result.length == expectedLength); }