Skip to content

Commit b81bdef

Browse files
authored
Add files via upload
1 parent 436b76b commit b81bdef

File tree

5 files changed

+888
-0
lines changed

5 files changed

+888
-0
lines changed

+librosa/istft.m

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
function varargout = istft(Y,varargin)
2+
% librosa.istft Inverse Short-time Fourier transform.
3+
%
4+
% This function matches the istft function from Librosa (tested for
5+
% version 0.9.2). Parameter defaults are identical to the Librosa
6+
% function.
7+
%
8+
% X = librosa.istft(Y) returns the inverse short-time Fourier transform
9+
% (istft) of Y.
10+
%
11+
% X = librosa.istft(S, FFTLength=NFFT) specifies the FFT length used to
12+
% calculate the stft.
13+
%
14+
% X = librosa.istft(S, Window=win) specifies the window used to compute
15+
% the stft.
16+
%
17+
% X = librosa.istft(S, HopLength=H) specifies the hop length.
18+
%
19+
% X = librosa.istft(S, Center=center) specifies if the signal was
20+
% centered.
21+
%
22+
% S = librosa.istft(X, GenerateMATLABCode=true) generates and opens an
23+
% untitled file containing code that implements the code of librosa.istft
24+
% using the MATLAB function istft.
25+
%
26+
% % EXAMPLE:
27+
% % Compute the istft of a real signal using the overlap-add method.
28+
% fs = 10240;
29+
% t = 0:1/fs:0.5-1/fs;
30+
% x = 5*sin(2*pi*t*10);
31+
% win = hamming(512,'periodic');
32+
% S = librosa.stft(x,'Window',win,'HopLength',numel(win)-384,...
33+
% 'FFTLength',1024);
34+
% X = librosa.istft(S,'Window',win,'HopLength',numel(win)-384,...
35+
% 'FFTLength',1024);
36+
%
37+
% % Plot original and resynthesized signals.
38+
% plot(1:numel(x),x,1:size(X,1),X,'-.')
39+
% axis tight
40+
% xlabel('Time bins')
41+
% ylabel('Amplitude (V)')
42+
% title('Original and Reconstructed Signal')
43+
% legend('Original','Reconstructed')
44+
45+
% Copyright 2022 The MathWorks, Inc.
46+
47+
%% Validate input signal
48+
validateattributes(Y,{'single','double'},...
49+
{'nonempty','3d'}, ...
50+
'librosa.istft','Y')
51+
52+
%% Parse function parameters
53+
p = inputParser;
54+
addRequired(p,'Y');
55+
56+
validFFTLength = @(x) isnumeric(x) && isscalar(x) && (x > 0) && floor(x)==x;
57+
addParameter(p,'FFTLength',2048,validFFTLength);
58+
59+
validHopLength = @(x) isnumeric(x) && isscalar(x) && (x > 0) && floor(x)==x;
60+
addParameter(p,'HopLength',2048,validHopLength);
61+
62+
validWindowLength = @(x) isnumeric(x) && isscalar(x) && (x > 0) && floor(x)==x;
63+
addParameter(p,'WindowLength',2048,validWindowLength);
64+
65+
validWindow = @(x) ischar(x) || isstring(x) || isvector(x) && isreal(x) &&isfloat(x);
66+
addParameter(p,'Window',hann(2048,'periodic'),validWindow);
67+
68+
validCenter = @(x)isscalar(x) && (isnumeric(x)||islogical(x));
69+
addParameter(p,'Center',true,validCenter);
70+
71+
validLength = @(x) isnumeric(x) && isscalar(x) && (x > 0) && floor(x)==x;
72+
addParameter(p,'Length',true,validLength);
73+
74+
validCodegen = @(x)isscalar(x) && (isnumeric(x)||islogical(x));
75+
addParameter(p,'GenerateMATLABCode',false,validCodegen);
76+
77+
parse(p,Y,varargin{:});
78+
79+
FFTLength = p.Results.FFTLength;
80+
center = p.Results.Center;
81+
82+
% Reconcile Window and WindowLength specifications, similar to Librosa
83+
% function
84+
if ismember('WindowLength',p.UsingDefaults)
85+
if ismember('Window',p.UsingDefaults)
86+
winlen = FFTLength;
87+
else
88+
win = p.Results.Window;
89+
if ischar(win) || isstring(win)
90+
winlen = FFTLength;
91+
else
92+
winlen = numel(win);
93+
end
94+
end
95+
else
96+
winlen = p.Results.WindowLength;
97+
end
98+
99+
if ismember('Window',p.UsingDefaults)
100+
win = hann(winlen,'periodic');
101+
else
102+
win = p.Results.Window;
103+
if ischar(win) || isstring(win)
104+
win = sprintf('%s(%d)',win,winlen);
105+
win = eval(win);
106+
end
107+
end
108+
109+
if (numel(win) ~= winlen)
110+
error('Window size mismatch')
111+
end
112+
113+
if ismember('HopLength',p.UsingDefaults)
114+
hopLength = floor(numel(win)/4);
115+
else
116+
hopLength = p.Results.HopLength;
117+
end
118+
119+
lengthSpecified = ~ismember('Length',p.UsingDefaults);
120+
len = p.Results.Length;
121+
122+
if numel(win)<FFTLength
123+
L = FFTLength-numel(win);
124+
L2 = floor(L/2);
125+
win = win(:);
126+
win = [zeros(L2,1); win; zeros(FFTLength-L2-numel(win),1)];
127+
end
128+
129+
if p.Results.GenerateMATLABCode
130+
strWriter = StringWriter;
131+
else
132+
strWriter = librosa.utils.StringWriter;
133+
end
134+
135+
if lengthSpecified
136+
strWriter.addcr('%s\n%% Adjust length.','%%');
137+
if center
138+
padded_length = len + FFTLength;
139+
strWriter.addcr('padLength = %d+%d;',len,FFTLength);
140+
else
141+
padded_length = len;
142+
strWriter.addcr('padLength = %d;',len);
143+
end
144+
n_frames = min(size(Y,2),ceil(padded_length/hopLength));
145+
Y = Y(:,1:n_frames,:);
146+
strWriter.addcr('numFrames = min(size(Y,2),ceil(padLength/%d));',hopLength);
147+
strWriter.addcr('Y = Y(:,1:numFrames,:)');
148+
end
149+
150+
y = istft(Y,Window=win,...
151+
OverlapLength=numel(win)-hopLength,...
152+
FFTLength=FFTLength,...
153+
FrequencyRange="onesided");
154+
155+
strWriter.addcr('%s\n%% Compute ISTFT.','%%');
156+
strWriter.addcr('y = istft(Y, Window=%s,...',mat2str(win(:),32));
157+
strWriter.addcr('OverlapLength=%d,...',numel(win)-hopLength);
158+
strWriter.addcr('FFTLength=%d,...',FFTLength);
159+
strWriter.addcr('FrequencyRange="onesided");');
160+
161+
if ~lengthSpecified
162+
if center
163+
strWriter.addcr('%s\n%% STFT was centered.','%%');
164+
L = floor(FFTLength/2);
165+
y = y(L+1:size(y,1)-L,:);
166+
strWriter.addcr('L = floor(%d/2);',FFTLength);
167+
strWriter.addcr('y = y(L+1:size(y,1)-L,:);',FFTLength);
168+
end
169+
else
170+
if center
171+
strWriter.addcr('%s\n%% STFT was centered.','%%');
172+
L = floor(FFTLength/2);
173+
strWriter.addcr('L = floor(%d/2);',FFTLength);
174+
y = y(L+1:L+len,:);
175+
strWriter.addcr('y = y(L+1:L+%d,:);',len);
176+
else
177+
y = y(1:len,:);
178+
strWriter.addcr('y = y(1:%d,:);',len);
179+
end
180+
end
181+
182+
varargout{1} = y;
183+
varargout{2} = strWriter.char;
184+
185+
generateMATLABCode = p.Results.GenerateMATLABCode;
186+
if generateMATLABCode
187+
footer = sprintf('%% _Generated by MATLAB (R) and Audio Toolbox on %s_', string(datetime("now")));
188+
strWriter.addcr('\n%s\n%s','%%',footer);
189+
matlab.internal.liveeditor.openAsLiveCode(strWriter.char)
190+
end

+librosa/mel.m

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
function varargout = mel(varargin)
2+
% librosa.stft Design Mel filter bank
3+
%
4+
% This function matches the mel function from Librosa (tested for
5+
% version 0.9.2). Parameter defaults are identical to the Librosa
6+
% function.
7+
%
8+
% FB = librosa.mel(SampleRate=fs) returns a frequency-domain
9+
% Mel filter bank, filterBank. fs is the input sample rate, in Hz.
10+
%
11+
% FB = librosa.mel(FFTLength=NFFT) specifies the FFT length.
12+
%
13+
% FB = librosa.mel(NumBands=NUMBANDS) specifies the number of bands in
14+
% the filter bank.
15+
%
16+
% FB = librosa.mel(Fmin=FMIN) specifies the lowest frequency (in Hz).
17+
%
18+
% FB = librosa.mel(Fmax=FMAX) specifies the highest frequency (in Hz).
19+
%
20+
% FB = librosa.mel(Normalization=NORM) specifies the type of filter bank
21+
% normalization.
22+
%
23+
% FB = librosa.mel(HTK=FLAG) specifies what type of Mel scaling is used.
24+
% If FLAG is true, HTK scaling is used. If FLAG is false, Slaney scaling
25+
% is used. This function only supports HTK scaling, which is the
26+
% non-default of the Librosa function. Set HTK=true in the function call.
27+
%
28+
% FB = librosa.mel(GenerateMATLABCode=true) generates and opens an
29+
% untitled file containing code that implements the code of librosa.mel
30+
% using the MATLAB function designAuditoryFilterBank.
31+
%
32+
% % Example:
33+
% % Design an auditory filter bank and use it to compute a mel
34+
% % spectrogram.
35+
%
36+
% [audioIn,fs] = audioread("Counting-16-44p1-mono-15secs.wav");
37+
%
38+
% % Compute spectrogram
39+
% win = hann(1024,"periodic");
40+
% [~,F,T,S] = spectrogram(audioIn,win,512,1024,fs,"onesided");
41+
%
42+
% % Design auditory filter bank
43+
% filterBank = librosa.mel(SampleRate=fs,FFTLength=1024, ...
44+
% NumBands=16,Normalization="None", HTK=true);
45+
%
46+
% % Visualize filter bank
47+
% plot(F,filterBank.')
48+
% grid on
49+
% title("Mel Filter Bank")
50+
% xlabel("Frequency (Hz)")
51+
%
52+
% % Compute mel spectrogram
53+
% SMel = filterBank*S;
54+
55+
% Copyright 2022 The MathWorks, Inc.
56+
57+
%% Parse function parameters
58+
p = inputParser;
59+
60+
validFFTLength = @(x) isnumeric(x) && isscalar(x) && (x > 0) && floor(x)==x;
61+
addParameter(p,'FFTLength',2048,validFFTLength);
62+
validSampleRate = @(x) isnumeric(x) && isscalar(x) && (x>0);
63+
addParameter(p,'SampleRate',22050,validSampleRate);
64+
validNumBands = @(x) isnumeric(x) && isscalar(x) && (x > 0) && floor(x)==x;
65+
addParameter(p,'NumBands',128,validNumBands);
66+
validFmin = @(x) isnumeric(x) && isscalar(x) && (x>0);
67+
addParameter(p,'Fmin',0,validFmin);
68+
validFmax = @(x) isnumeric(x) && isscalar(x) && (x>0);
69+
addParameter(p,'Fmax',8000,validFmax);
70+
validHTK = @(x)isscalar(x) && (isnumeric(x)||islogical(x));
71+
addParameter(p,'HTK',false,validHTK);
72+
validNorm = @(x) (isnumeric(x) && isscalar(x)) || (ismember(char(x),{'Slaney','None'}));
73+
addParameter(p,'Normalization','Slaney',validNorm);
74+
validCodegen = @(x)isscalar(x) && (isnumeric(x)||islogical(x));
75+
addParameter(p,'GenerateMATLABCode',false,validCodegen);
76+
77+
parse(p,varargin{:});
78+
79+
if ismember('Fmax',p.UsingDefaults)
80+
fmax = p.Results.SampleRate/2;
81+
else
82+
fmax = min(p.Results.SampleRate/2,p.Results.Fmax);
83+
end
84+
85+
if ~p.Results.HTK
86+
error('Slaney scaling is not supported. Set HTK to true.');
87+
end
88+
89+
norm = p.Results.Normalization;
90+
customNorm = false;
91+
switch norm
92+
case 'None'
93+
norm = 'none';
94+
case 'Slaney'
95+
norm = 'bandwidth';
96+
otherwise
97+
norm = 'none';
98+
customNorm = true;
99+
end
100+
101+
if p.Results.GenerateMATLABCode
102+
strWriter = StringWriter;
103+
else
104+
strWriter = librosa.utils.StringWriter;
105+
end
106+
strWriter.addcr('%s\n%% Construct filter bank.','%%');
107+
108+
filterBank = designAuditoryFilterBank(p.Results.SampleRate,...
109+
"FrequencyScale","mel",...
110+
"FFTLength",p.Results.FFTLength,...
111+
"NumBands",p.Results.NumBands,...
112+
"FrequencyRange",[p.Results.Fmin fmax],...
113+
"Normalization",norm,...
114+
"OneSided",true,...
115+
"FilterBankDesignDomain","linear");
116+
117+
strWriter.addcr('filterBank = designAuditoryFilterBank(%f,...',p.Results.SampleRate);
118+
strWriter.addcr('FrequencyScale="mel",...');
119+
strWriter.addcr('FFTLength=%d,...',p.Results.FFTLength);
120+
strWriter.addcr('NumBands=%d,...',p.Results.NumBands);
121+
strWriter.addcr('FrequencyRange=[%f %f],...',p.Results.Fmin,fmax);
122+
strWriter.addcr('Normalization=''%s'',...',norm);
123+
strWriter.addcr('OneSided=true,...');
124+
strWriter.addcr('FilterBankDesignDomain="linear");');
125+
126+
if customNorm
127+
n = p.Results.Normalization;
128+
strWriter.addcr('%s\n%% Normalize filter bank.','%%');
129+
if ~isequal(n,-Inf)
130+
val = vecnorm(filterBank,n,2);
131+
strWriter.addcr('n = vecnorm(filterBank,%f,2);',p.Results.Normalization);
132+
filterBank = filterBank./val;
133+
strWriter.addcr('filterBank = filterBank./n;');
134+
end
135+
end
136+
137+
varargout{1} = filterBank;
138+
varargout{2} = strWriter.char;
139+
140+
if p.Results.GenerateMATLABCode
141+
footer = sprintf('%% _Generated by MATLAB (R) and Audio Toolbox on %s_', string(datetime("now")));
142+
strWriter.addcr('\n%s\n%s','%%',footer);
143+
matlab.internal.liveeditor.openAsLiveCode(strWriter.char)
144+
end
145+
end

0 commit comments

Comments
 (0)