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 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); }