%% Multirate: Resampling kiisseli.wav % % This demo shows how upsampling (ylösnäytteitys) by % factor L and downsampling (alasnäytteistys) by factor M % are applied when changing the sampling rate (frequency). % % x2 x3 % ----- -------- ----- % x[n] --> | L | -----> | H_LP | -----> | M | --> y[n] % ----- -------- ----- % % % The demo gives you four figures. Each figure % contains a time-domain waveform in seconds and a frequency-domain % spectrum from 0 .. fs/2 Hz. % % Fig 1 -- original signal x % Fig 2 -- upsampled signal x2 % Fig 3 -- upsampled signal after lowpass filtering x3 % Fig 4 -- downsampled signal y <==> result % % Anti-imaging (interpolation) filter and anti-aliasing % filter are combined to a single LP filter with cut-off % frequency of min(w_M, w_L). % % Jukka Parviainen, 28.4.2009 / 25.4.2008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Variables to be edited % % YOU CAN EDIT THESE VARIABLES HERE. % DO NOT CHANGE ANYTHING ELSE. % Audiofile to be downloaded and analysed audiofile = 'kiisseli.wav'; % Upsampling (L) and downsampling (M) factors L = 3; M = 5; % Is the lowpass filter in Step 3 in use? % filterInUse = 0; filterInUse = 1; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Shut down figures and remove some variables % % NOTE! It is probably useful to say % clear all % clear all variables % close all % shut down all windows % before starting this demo! close all; clear x x2 x3 y %% Download the audio file [x, fs] = wavread(audiofile); %soundsc(x, fs) disp(['Audiofile ' audiofile]); disp(['#samples = ' num2str(length(x))]); disp(['Original sampling frequency fs = ' num2str(fs) ' Hz']); disp(['Original sampling period Ts = ' num2str(1/fs) ' s']); disp(['Length in seconds = ' num2str(length(x)/fs) ' s']); %% Set the upsampling and downsampling factors fsL = L*fs; fsLM = L*fs/M; disp(' '); disp(['Resampling by factor L/M = ' num2str(L) '/' num2str(M)]); disp(['Sampling freq. after upsampling fsL = ' num2str(fsL) ' Hz']); disp(['Resampled sampling frequency fsLM = ' num2str(fsLM) ' Hz']); disp(['Sampling per. after resampling TsLM = ' num2str(1/fsLM) ' s']); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Fig 1 -- Original signal P1 = length(x); t = [0 : P1-1]/fs; xF = fft(x); w = fs*[0 : P1-1]/P1; figure(1); clf; subplot(211); plot(t, x); grid on; xlabel('time'); title(['Original signal ' audiofile ' [#samples = ' num2str(P1) ']']); subplot(212); plot(w, 20*log10(abs(xF))); set(gca,'XLim',[0 fs/2]); grid on; xlabel(['frequency (fs = ' num2str(fs) ' Hz)']); % some lines and text: dummyY = get(gca,'YLim'); pO = line([fs/2 fs/2], dummyY); pF = line([fsLM/2 fsLM/2], dummyY); set(pO, 'Color', [1 0 0], 'LineWidth', 3); set(pF, 'Color', [0 1 0], 'LineWidth', 3); dummyF = dummyY(2) - 0.07*(dummyY(2)-dummyY(1)); tF = text(0.99*(fs/2), dummyF, '\omega = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); dummyF = dummyY(2) - 0.14*(dummyY(2)-dummyY(1)); tF = text(0.99*(fsLM/2), dummyF, '\omega_L_M = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); %% BREAKPOINT % % - What is sampling frequency? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Fig 2 -- Upsampling by L P2 = L*(P1-1)+1; t2 = [0 : P2-1]/fsL; x2(1:L:P2) = x; x2F = fft(x2); w2 = fsL*[0 : P2-1]/P2; figure(2); clf; subplot(211); plot(t2, x2); grid on; xlabel('time'); title(['Upsampled by L = ' num2str(L) ' [#samples = ' num2str(P2) ']']); subplot(212); plot(w2, 20*log10(abs(x2F))); set(gca,'XLim',[0 fsL/2]); grid on; xlabel(['frequency (fs = ' num2str(fsL) ' Hz)']); % some lines and text: dummyY = get(gca,'YLim'); pO = line([fs/2 fs/2], dummyY); pF = line([fsLM/2 fsLM/2], dummyY); pT = line([fsL/2 fsL/2], dummyY); set(pO, 'Color', [1 0 0], 'LineWidth', 3); set(pF, 'Color', [0 1 0], 'LineWidth', 3); set(pT, 'Color', [1 1 0], 'LineWidth', 3); dummyF = dummyY(2) - 0.07*(dummyY(2)-dummyY(1)); tF = text(0.99*(fs/2), dummyF, '\omega = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); dummyF = dummyY(2) - 0.14*(dummyY(2)-dummyY(1)); tF = text(0.99*(fsLM/2), dummyF, '\omega_L_M = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); dummyF = dummyY(2) - 0.21*(dummyY(2)-dummyY(1)); tF = text(0.99*(fsL/2), dummyF, '\omega_L = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); %% BREAKPOINT % % - What is the new sampling frequency f_L? % - Confirm that there are L-1 zeros between % each original sample of x in waveform %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if filterInUse % Fig 3 -- Lowpass filtering % Removing "images" and anti-aliasing w_cut = 2*min([fsL/(2*L) fsL/(2*M)])/fsL; % ???? does it work???? f_cut = w_cut*fsL/2; Rp = 1; Rs = 50; [N, Wn] = ellipord(0.92*w_cut, 0.98*w_cut, Rp, Rs); [B, A] = ellip(N, Rp, Rs, Wn); x3 = filter(B, A, x2); x3F = fft(x3); figure(3); clf; subplot(211); plot(t2, x3); grid on; xlabel('time'); title(['Up by L = ' num2str(L) ' and FILTERED with f_c \approx ' num2str(f_cut) ' Hz']); subplot(212); plot(w2, 20*log10(abs(x3F))); set(gca,'XLim',[0 fsL/2]); grid on; xlabel(['frequency (fs = ' num2str(fsL) ' Hz)']); % some lines and text: dummyY = get(gca,'YLim'); pO = line([fs/2 fs/2], dummyY); pF = line([fsLM/2 fsLM/2], dummyY); pT = line([fsL/2 fsL/2], dummyY); set(pO, 'Color', [1 0 0], 'LineWidth', 3); set(pF, 'Color', [0 1 0], 'LineWidth', 3); set(pT, 'Color', [1 1 0], 'LineWidth', 3); dummyF = dummyY(2) - 0.07*(dummyY(2)-dummyY(1)); tF = text(0.99*(fs/2), dummyF, '\omega = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); dummyF = dummyY(2) - 0.14*(dummyY(2)-dummyY(1)); tF = text(0.99*(fsLM/2), dummyF, '\omega_L_M = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); dummyF = dummyY(2) - 0.21*(dummyY(2)-dummyY(1)); tF = text(0.99*(fsL/2), dummyF, '\omega_L = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); else % Not filtering the signal at all! % For (aliasing) demo purposes only. warning('No anti-aliasing / anti-imaging filter used!'); x3 = x2; end; %% BREAKPOINT % % - What does lowpass filtering affect? % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Fig 4 -- Downsampling by M y = x3(1:M:end); P4 = length(y); t4 = [0 : P4-1]/fsLM; yF = fft(y); w4 = fsLM*[0 : P4-1]/P4; figure(4); clf; subplot(211); plot(t4, y); grid on; xlabel('time'); if filterInUse title(['Up L = ' num2str(L) ' AND filtered AND downsampled by M = ' num2str(M)]); else title(['Up L = ' num2str(L) ' (NOT filtered) AND downsampled by M = ' num2str(M)]); end; subplot(212); plot(w4, 20*log10(abs(yF))); set(gca,'XLim',[0 fsLM/2]); grid on; xlabel(['frequency (fs = ' num2str(fsLM) ' Hz)']); % some lines and text: dummyY = get(gca,'YLim'); pO = line([fs/2 fs/2], dummyY); pF = line([fsLM/2 fsLM/2], dummyY); pT = line([fsL/2 fsL/2], dummyY); set(pO, 'Color', [1 0 0], 'LineWidth', 3); set(pF, 'Color', [0 1 0], 'LineWidth', 3); set(pT, 'Color', [1 1 0], 'LineWidth', 3); dummyF = dummyY(2) - 0.07*(dummyY(2)-dummyY(1)); tF = text(0.99*(fs/2), dummyF, '\omega = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); dummyF = dummyY(2) - 0.14*(dummyY(2)-dummyY(1)); tF = text(0.99*(fsLM/2), dummyF, '\omega_L_M = \pi \rightarrow'); set(tF,'HorizontalAlignment','right'); %% BREAKPOINT % % - Listen to the resampled signal y (if possible) %% %soundsc(x, fs); % original %% %soundsc(y, L/M*fs); % resampled by L/M %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Summary % % In order to change sampling rate % (1) upsample % (2) apply lowpass filtering % (3) downsample % % _All_ this can be done in Matlab with a single command % % y = resample(x, L, M); %