1 | function c = pvsample(b, t, hop)
|
---|
2 | % c = pvsample(b, t, hop) Interpolate an STFT array according to the 'phase vocoder'
|
---|
3 | % b is an STFT array, of the form generated by 'specgram'.
|
---|
4 | % t is a vector of (real) time-samples, which specifies a path through
|
---|
5 | % the time-base defined by the columns of b. For each value of t,
|
---|
6 | % the spectral magnitudes in the columns of b are interpolated, and
|
---|
7 | % the phase difference between the successive columns of b is
|
---|
8 | % calculated; a new column is created in the output array c that
|
---|
9 | % preserves this per-step phase advance in each bin.
|
---|
10 | % hop is the STFT hop size, defaults to N/2, where N is the FFT size
|
---|
11 | % and b has N/2+1 rows. hop is needed to calculate the 'null' phase
|
---|
12 | % advance expected in each bin.
|
---|
13 | % Note: t is defined relative to a zero origin, so 0.1 is 90% of
|
---|
14 | % the first column of b, plus 10% of the second.
|
---|
15 | % 2000-12-05 dpwe@ee.columbia.edu
|
---|
16 | % $Header: /homes/dpwe/public_html/resources/matlab/dtw/../RCS/pvsample.m,v 1.3 2003/04/09 03:17:10 dpwe Exp $
|
---|
17 |
|
---|
18 | if nargin < 3
|
---|
19 | hop = 0;
|
---|
20 | end
|
---|
21 |
|
---|
22 | [rows,cols] = size(b);
|
---|
23 |
|
---|
24 | N = 2*(rows-1);
|
---|
25 |
|
---|
26 | if hop == 0
|
---|
27 | % default value
|
---|
28 | hop = N/2;
|
---|
29 | end
|
---|
30 |
|
---|
31 | % Empty output array
|
---|
32 | c = zeros(rows, length(t));
|
---|
33 |
|
---|
34 | % Expected phase advance in each bin
|
---|
35 | dphi = zeros(1,N/2+1);
|
---|
36 | dphi(2:(1 + N/2)) = (2*pi*hop)./(N./(1:(N/2)));
|
---|
37 |
|
---|
38 | % Phase accumulator
|
---|
39 | % Preset to phase of first frame for perfect reconstruction
|
---|
40 | % in case of 1:1 time scaling
|
---|
41 | ph = angle(b(:,1));
|
---|
42 |
|
---|
43 | % Append a 'safety' column on to the end of b to avoid problems
|
---|
44 | % taking *exactly* the last frame (i.e. 1*b(:,cols)+0*b(:,cols+1))
|
---|
45 | b = [b,zeros(rows,1)];
|
---|
46 |
|
---|
47 | ocol = 1;
|
---|
48 | for tt = t
|
---|
49 | % Grab the two columns of b
|
---|
50 | bcols = b(:,floor(tt)+[1 2]);
|
---|
51 | tf = tt - floor(tt);
|
---|
52 | bmag = (1-tf)*abs(bcols(:,1)) + tf*(abs(bcols(:,2)));
|
---|
53 | % calculate phase advance
|
---|
54 | dp = angle(bcols(:,2)) - angle(bcols(:,1)) - dphi';
|
---|
55 | % Reduce to -pi:pi range
|
---|
56 | dp = dp - 2 * pi * round(dp/(2*pi));
|
---|
57 | % Save the column
|
---|
58 | c(:,ocol) = bmag .* exp(j*ph);
|
---|
59 | % Cumulate phase, ready for next frame
|
---|
60 | ph = ph + dphi' + dp;
|
---|
61 | ocol = ocol+1;
|
---|
62 | end
|
---|