ivan@138: function [problemData, solutionData] = generateDeclippingProblem(x,clippingLevel,GR)
ivan@138: %
ivan@138: %
ivan@138: % Usage:
ivan@138: %
ivan@138: %
ivan@138: % Inputs:
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %
ivan@138: % Outputs:
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %          - 
ivan@138: %
ivan@138: % Note that the CVX library is needed.
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: % Generate a clipping problem: normalize and clip a signal.
ivan@138: %
ivan@138: % Usage:
ivan@138: %   [problemData, solutionData] = 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: %   - problemData.x: clipped signal
ivan@138: %   - problemData.IMiss: boolean vector (same size as problemData.x) that indexes clipped
ivan@138: %   samples
ivan@138: %   - problemData.clipSizes: size of the clipped segments (not necessary
ivan@138: %   for solving the problem)
ivan@138: %   - solutionData.xClean: clean signal (input signal after normalization
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 problemData.x and solutionData.xClean.
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: solutionData.xClean = x/max(abs(x(:)))*xMax;
ivan@138: clippingLevel = clippingLevel*xMax;
ivan@138: 
ivan@138: %% Clipping (hard threshold)
ivan@138: problemData.x = min(max(solutionData.xClean,-clippingLevel),clippingLevel);
ivan@138: problemData.IMiss = abs(problemData.x)>=clippingLevel; % related indices
ivan@138: 
ivan@138: %% Size of the clipped segments
ivan@138: problemData.clipSizes = diff(problemData.IMiss);
ivan@138: if problemData.clipSizes(find(problemData.clipSizes,1,'first'))==-1,problemData.clipSizes = [1;problemData.clipSizes]; end
ivan@138: if problemData.clipSizes(find(problemData.clipSizes,1,'last'))==1,problemData.clipSizes = [problemData.clipSizes;-1]; end
ivan@138: problemData.clipSizes = diff(find(problemData.clipSizes));
ivan@138: problemData.clipSizes = problemData.clipSizes(1:2: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(problemData.clipSizes)
ivan@138:         figure
ivan@138:         hist(problemData.clipSizes,1:max(problemData.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(solutionData.xClean)-1); % time scale in samples
ivan@138:     
ivan@138:     % Plot original and clipped signals
ivan@138:     figure
ivan@138:     plot(t,solutionData.xClean,'',t,problemData.x,'')
ivan@138:     legend('original','clipped')
ivan@138:     
ivan@138:     % Scatter plot between original and clipped signals
ivan@138:     figure
ivan@138:     plot(solutionData.xClean,problemData.x,'.')
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(solutionData.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(problemData.x,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(solutionData.xClean-problemData.x,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,solutionData.xClean,'');xlim(t([1,end]))
ivan@138:     subplot(3,3,8)
ivan@138:     plot(t,solutionData.xClean,'',t,problemData.x,'');xlim(t([1,end]))
ivan@138:     subplot(3,3,9)
ivan@138:     plot(t,solutionData.xClean-problemData.x,'');xlim(t([1,end]))
ivan@138: end
ivan@138: 
ivan@138: return