Path: ...!weretis.net!feeder8.news.weretis.net!pi2.pasdenom.info!from-devjntp Message-ID: <-8fWpQBluWWE7LoCNTcHx5RX6Bk@jntp> JNTP-Route: news2.nemoweb.net JNTP-DataType: Article Subject: Re: Pitch shifting References: <608a7a5e$0$3262$426a34cc@news.free.fr> <608adea5$0$32492$426a74cc@news.free.fr> <608b05aa$0$6174$426a74cc@news.free.fr> <608bb025$0$12711$426a34cc@news.free.fr> <608bb843$0$3688$426a74cc@news.free.fr> <608bf667$0$6472$426a74cc@news.free.fr> <608c0887$0$12712$426a34cc@news.free.fr> <608d79fc$0$21591$426a74cc@news.free.fr> Newsgroups: fr.sci.maths,fr.sci.biologie JNTP-HashClient: 2JUbAwf8AusGWprF_uQu5aERZ1M JNTP-ThreadID: 608a7a5e$0$3262$426a34cc@news.free.fr JNTP-Uri: http://news2.nemoweb.net/?DataID=-8fWpQBluWWE7LoCNTcHx5RX6Bk@jntp User-Agent: Nemo/0.999a JNTP-OriginServer: news2.nemoweb.net Date: Mon, 03 May 21 07:28:25 +0000 Organization: Nemoweb JNTP-Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0 Injection-Info: news2.nemoweb.net; posting-host="e246572f689810fcc28c9472f2c6ec1b62db7f04"; logging-data="2021-05-03T07:28:25Z/5611802"; posting-account="44@news2.nemoweb.net"; mail-complaints-to="newsmaster@news2.nemoweb.net" JNTP-ProtocolVersion: 0.21.1 JNTP-Server: PhpNemoServer/0.94.5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-JNTP-JsonNewsGateway: 0.96 From: pehache Bytes: 8124 Lines: 209 Le 01/05/2021 à 17:55, François Guillet a écrit : > > Les vocoders qui font ça existe. > S'il y a peut-être du bricolage pour peaufiner le son, je pense qu'il y > a quand même une méthode pour traiter la phase, et c'est ce que je > cherche. Voir ce code Matlab (qui tourne OK aussi dans Octave) que j'avais récupéré il y a pas mal d'années. J'avais testé, il faisait ce qu'il était censé faire, mais il me semble aussi que j'avais noté quelques problèmes (mais je ne me souviens plus lesquels). %********************************************************************************** function y = pvoc(x, r, n) % y = pvoc(x, r, n) Time-scale a signal to r times faster with phase vocoder % x is an input sound. n is the FFT size, defaults to 1024. % Calculate the 25%-overlapped STFT, squeeze it by a factor of r, % inverse spegram. % 2000-12-05, 2002-02-13 dpwe@ee.columbia.edu. Uses pvsample, stft, istft % $Header: /homes/dpwe/public_html/resources/matlab/RCS/pvoc.m,v 1.2 2002/02/13 16:14:54 dpwe Exp $ if nargin < 3 n = 1024; end % With hann windowing on both input and output, % we need 25% window overlap for smooth reconstruction hop = n/4; % Effect of hanns at both ends is a cumulated cos^2 window (for % r = 1 anyway); need to scale magnitudes by 2/3 for % identity input/output scf = 2/3; % Calculate the basic STFT, magnitude scaled X = scf * stft(x', n, n, hop); % Calculate the new timebase samples [rows, cols] = size(X); t = 0:r:(cols-2); % Have to stay two cols off end because (a) counting from zero, and % (b) need col n AND col n+1 to interpolate % Generate the new spectrogram X2 = pvsample(X, t, hop); % Invert to a waveform y = istft(X2, n, n, hop)'; %********************************************************************************** function c = pvsample(b, t, hop) % c = pvsample(b, t, hop) Interpolate an STFT array according to the 'phase vocoder' % b is an STFT array, of the form generated by 'specgram'. % t is a vector of (real) time-samples, which specifies a path through % the time-base defined by the columns of b. For each value of t, % the spectral magnitudes in the columns of b are interpolated, and % the phase difference between the successive columns of b is % calculated; a new column is created in the output array c that % preserves this per-step phase advance in each bin. % hop is the STFT hop size, defaults to N/2, where N is the FFT size % and b has N/2+1 rows. hop is needed to calculate the 'null' phase % advance expected in each bin. % Note: t is defined relative to a zero origin, so 0.1 is 90% of % the first column of b, plus 10% of the second. % 2000-12-05 dpwe@ee.columbia.edu % $Header: /homes/dpwe/public_html/resources/matlab/dtw/../RCS/pvsample.m,v 1.3 2003/04/09 03:17:10 dpwe Exp $ if nargin < 3 hop = 0; end [rows,cols] = size(b); N = 2*(rows-1); if hop == 0 % default value hop = N/2; end % Empty output array c = zeros(rows, length(t)); % Expected phase advance in each bin dphi = zeros(1,N/2+1); dphi(2:(1 + N/2)) = (2*pi*hop)./(N./(1:(N/2))); % Phase accumulator % Preset to phase of first frame for perfect reconstruction % in case of 1:1 time scaling ph = angle(b(:,1)); % Append a 'safety' column on to the end of b to avoid problems % taking *exactly* the last frame (i.e. 1*b(:,cols)+0*b(:,cols+1)) b = [b,zeros(rows,1)]; ocol = 1; for tt = t % Grab the two columns of b bcols = b(:,floor(tt)+[1 2]); tf = tt - floor(tt); bmag = (1-tf)*abs(bcols(:,1)) + tf*(abs(bcols(:,2))); % calculate phase advance dp = angle(bcols(:,2)) - angle(bcols(:,1)) - dphi'; % Reduce to -pi:pi range dp = dp - 2 * pi * round(dp/(2*pi)); % Save the column c(:,ocol) = bmag .* exp(j*ph); % Cumulate phase, ready for next frame ph = ph + dphi' + dp; ocol = ocol+1; end %********************************************************************************** function d = stft(x, f, w, h) % D = stft(X, F, W, H) Short-time Fourier transform. % Returns some frames of short-term Fourier transform of x. Each % column of the result is one F-point fft; each successive frame is % offset by H points until X is exhausted. Data is hamm-windowed % at W pts.. % See also 'istft.m'. % dpwe 1994may05. Uses built-in 'fft' % $Header: /homes/dpwe/public_html/resources/matlab/RCS/stft.m,v 1.1 2002/02/13 16:15:55 dpwe Exp $ s = length(x); if rem(w, 2) == 0 % force window to be odd-len w = w + 1; end halflen = (w-1)/2; halff = f/2; % midpoint of win acthalflen = min(halff, halflen); halfwin = 0.5 * ( 1 + cos( pi * (0:halflen)/halflen)); win = zeros(1, f); win((halff+1):(halff+acthalflen)) = halfwin(1:acthalflen); win((halff+1):-1:(halff-acthalflen+2)) = halfwin(1:acthalflen); c = 1; % pre-allocate output array d = zeros((1+f/2),1+fix((s-f)/h)); for b = 0:h:(s-f) u = win.*x((b+1):(b+f)); t = fft(u); d(:,c) = t(1:(1+f/2))'; c = c+1; end; %********************************************************************************** function x = istft(d, ftsize, w, h) % X = istft(D, F, W, H) Inverse short-time Fourier ========== REMAINDER OF ARTICLE TRUNCATED ==========