function [X,A,P] = forwardSTFT(x, parameter) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Name: forwardSTFT % Date of Revision: 11 2014 % Programmer: Christian Dittmar % % Given a time signal as input, this computes the spectrogram by means of % the Short-time fourier transform % % Input: x the time signal oriented as numSamples x 1 % parameter. % blockSize the blocksize to use during analysis % hopSize the hopsize to use during analysis % winFunc the analysis window % reconstMirror this switch decides whether to discard the mirror % spectrum or not % appendFrame this switch decides if we use silence in the % beginning and the end % % Output: X the complex valued spectrogram in numBins x numFrames % A the magnitude spectrogram % P the phase spectrogram (wrapped in -pi ... +pi) % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % If you use the 'NMF toolbox' please refer to: % [1] Patricio López-Serrano, Christian Dittmar, Yiğitcan Özer, and Meinard % Müller % NMF Toolbox: Music Processing Applications of Nonnegative Matrix % Factorization % In Proceedings of the International Conference on Digital Audio Effects % (DAFx), 2019. % % License: % This file is part of 'NMF toolbox'. % https://www.audiolabs-erlangen.de/resources/MIR/NMFtoolbox/ % 'NMF toolbox' is free software: you can redistribute it and/or modify it % under the terms of the GNU General Public License as published by the % the Free Software Foundation, either version 3 of the License, or (at % your option) any later version. % % 'NMF toolbox' is distributed in the hope that it will be useful, but % WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General % Public License for more details. % % You should have received a copy of the GNU General Public License along % with 'NMF toolbox'. If not, see http://www.gnu.org/licenses/. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Check parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if nargin < 1 error('Please specify input time-domain signal x.'); end if nargin < 2 parameter = []; end if ~isfield(parameter,'blockSize') parameter.blockSize = 2048; end if ~isfield(parameter,'hopSize') parameter.hopSize = 512; end if ~isfield(parameter,'winFunc') parameter.winFunc = hann(parameter.blockSize); end if ~isfield(parameter,'reconstMirror') parameter.reconstMirror = true; end if ~isfield(parameter,'appendFrame') parameter.appendFrame = true; end % parse parameters to internal variables for better readability blockSize = parameter.blockSize; halfBlockSize = round(blockSize/2); hopSize = parameter.hopSize; winFunc = parameter.winFunc; reconstMirror = parameter.reconstMirror; appendFrame = parameter.appendFrame; % the number of bins needs to be corrected % if we want to discard the mirror spectrum if reconstMirror numBins = blockSize/2+1; else numBins = blockSize; end % append safety space in the beginning and end if appendFrame x = [zeros(halfBlockSize,1);x;zeros(halfBlockSize,1)]; end % pre-compute the number of frames numFrames = round((length(x)-blockSize)/hopSize); % initialize with correct size X = zeros(numBins, numFrames); counter = 0; for k = 1:hopSize:length(x)-blockSize % where to pick ind = k:k+blockSize-1; % pick signal frame snip = x(ind); % apply windowing snip = snip.*winFunc; % do fft f = fft(snip,blockSize); % if required, remove upper half of spectrum if reconstMirror f = f(1:blockSize/2+1); end % store into STFT matrix counter = counter+1; X(:,counter) = f; end % compute derived matrices A = abs(X); P = angle(X);