ivan@138: function [xClipped, IClipped, xClean, clipSizes] = makeClippedSignal(x,clippingLevel,GR) ivan@138: % Normalize and clip a signal. ivan@138: % ivan@138: % Usage: ivan@138: % [xClipped, IClipped, xClean, clipSizes] = makeClippedSignal(x,clippingLevel,GR) ivan@138: % ivan@138: % Inputs: ivan@138: % - x: input signal (may be multichannel) ivan@138: % - clippingLevel: clipping level, between 0 and 1 ivan@138: % - GR (default: false): flag to generate an optional graphical display ivan@138: % ivan@138: % Outputs: ivan@138: % - xClipped: clipped signal ivan@138: % - IClipped: boolean vector (same size as xClipped) that indexes clipped ivan@138: % samples ivan@138: % - xClean: clean signal ivan@138: % - clipSizes: size of the clipped segments ivan@138: % ivan@138: % Note that the input signal is normalized to 0.9999 (-1 is not allowed in ivan@138: % wav files) to provide xClipped and xClean. ivan@138: % ivan@138: % ------------------- ivan@138: % ivan@138: % Audio Inpainting toolbox ivan@138: % Date: June 28, 2011 ivan@138: % By Valentin Emiya, Amir Adler, Maria Jafari ivan@138: % This code is distributed under the terms of the GNU Public License version 3 (http://www.gnu.org/licenses/gpl.txt). ivan@138: ivan@138: if nargin<3 || isempty(GR) ivan@138: GR = false; ivan@138: end ivan@138: ivan@138: %% Normalization ivan@138: xMax = 0.9999; ivan@138: xClean = x/max(abs(x(:)))*xMax; ivan@138: clippingLevel = clippingLevel*xMax; ivan@138: ivan@138: %% DISABLED - Ramp to produce a clipping level that linearly increases ivan@138: if 0 ivan@138: xClean = xClean.*(1:length(xClean))'/length(xClean); ivan@138: end ivan@138: ivan@138: %% Clipping (hard threshold) ivan@138: xClipped = min(max(xClean,-clippingLevel),clippingLevel); ivan@138: IClipped = abs(xClipped)>=clippingLevel; % related indices ivan@138: ivan@138: %% Size of the clipped segments ivan@138: if nargout>3 || GR ivan@138: % clipSizes = diff(find(diff(~IClipped))); ivan@138: % clipSizes = clipSizes(2-(IClipped(1)==0):2:end); ivan@138: clipSizes = diff(IClipped); ivan@138: if clipSizes(find(clipSizes,1,'first'))==-1,clipSizes = [1;clipSizes]; end ivan@138: if clipSizes(find(clipSizes,1,'last'))==1,clipSizes = [clipSizes;-1]; end ivan@138: clipSizes = diff(find(clipSizes)); ivan@138: clipSizes = clipSizes(1:2:end); ivan@138: end ivan@138: ivan@138: %% Optional graphical display ivan@138: if GR ivan@138: ivan@138: % Plot histogram of the sizes of the clipped segments ivan@138: if ~isempty(clipSizes) ivan@138: figure ivan@138: hist(clipSizes,1:max(clipSizes)) ivan@138: title('Size of missing segments') ivan@138: xlabel('Size'),ylabel('# of segments') ivan@138: end ivan@138: ivan@138: t = (0:length(xClean)-1); % time scale in samples ivan@138: ivan@138: % Plot original and clipped signals ivan@138: figure ivan@138: plot(t,xClean,'',t,xClipped,'') ivan@138: legend('original','clipped') ivan@138: ivan@138: % Scatter plot between original and clipped signals ivan@138: figure ivan@138: plot(xClean,xClipped,'.') ivan@138: xlabel('Original signal'),ylabel('Clipped signal') ivan@138: ivan@138: % Spectrograms ivan@138: N = 512; ivan@138: w = hann(N); ivan@138: fs = 1; ivan@138: NOverlap = round(.8*N); ivan@138: nfft = 2^nextpow2(N)*2*2; ivan@138: figure ivan@138: subplot(3,3,[1,4]) ivan@138: spectrogram(xClean,w,NOverlap,nfft,fs,'yaxis') ivan@138: title('Original') ivan@138: xlim(t([1,end])) ivan@138: cl = get(gca,'clim'); ivan@138: set(gca,'clim',cl); ivan@138: subplot(3,3,[1,4]+1) ivan@138: spectrogram(xClipped,w,NOverlap,nfft,fs,'yaxis') ivan@138: title('Clipped') ivan@138: set(gca,'clim',cl); ivan@138: subplot(3,3,[1,4]+2) ivan@138: spectrogram(xClean-xClipped,w,NOverlap,nfft,fs,'yaxis') ivan@138: title('Error (=original-clipped)') ivan@138: set(gca,'clim',cl); ivan@138: subplot(3,3,7) ivan@138: plot(t,xClean,'');xlim(t([1,end])) ivan@138: subplot(3,3,8) ivan@138: plot(t,xClean,'',t,xClipped,'');xlim(t([1,end])) ivan@138: subplot(3,3,9) ivan@138: plot(t,xClean-xClipped,'');xlim(t([1,end])) ivan@138: end ivan@138: ivan@138: return