ivan@138: function [ReconstSignal1 ReconstSignal2] = inpaintSignal_IndependentProcessingOfFrames(problemData,param) 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: % ======================================================== ivan@138: % Perform Audio De-clipping with overlapping blocks ivan@138: % Synthesis Approach, union of overcomplete DCT dictionary ivan@138: % Date: 14 Apr. 2010 ivan@138: % Inputs: ivan@138: % - x: Clipped signal ivan@138: % - ClipMask: Indices of clipped samples ivan@138: % - Optional parameters [and default values]: ivan@138: % - param.N: frame length [256] ivan@138: % - param.frameOverlapFactor: overlap factor between frames [2] ivan@138: % - param.wa: weighting analysis window [@sineWin] ivan@138: % - param.ws: weighting synthesis window [@sineWin] ivan@138: % - param.OMPerr: error threshold to stop OMP iterations [0.001] ivan@138: % - param.sparsityDegree: max number of non-zero components to ivan@138: % stop OMP iterations [param.N/4]; ivan@138: % - other fields: see the documentation of UDCT_Dictionary ivan@138: % ivan@138: % Outputs: ivan@138: % ReconstSignal1 - reconstructed signal (all samples generated ivan@138: % from the synthesis model) ivan@138: % ReconstSignal2 - reconstructed signal (only clipped samples are generated ivan@138: % from the synthesis model) ivan@138: % ivan@138: % By Valentin Emiya - SMALL Project, 2010 ivan@138: % ivan@138: % ======================================================== ivan@138: ivan@138: % Check parameters ivan@138: defaultParam.N = 256; ivan@138: defaultParam.OLA_frameOverlapFactor = 4; ivan@138: defaultParam.wa = @wSine; ivan@138: defaultParam.OLA_ws = @wSine; ivan@138: defaultParam.OLA_par_waitingTime_mainProcess = 0.2; ivan@138: defaultParam.OLA_par_waitingTime_thread = 0.2; ivan@138: defaultParam.OLA_par_frameBlockSize = 1; ivan@138: defaultParam.TCPIP_port = 3000; ivan@138: defaultParam.COM_DISP = false; ivan@138: defaultParam.STATE_DISP = false; ivan@138: ivan@138: if nargin<2 ivan@138: param = defaultParam; ivan@138: else ivan@138: names = fieldnames(defaultParam); ivan@138: for k=1:length(names) ivan@138: if ~isfield(param,names{k}) || isempty(param.(names{k})) ivan@138: param.(names{k}) = defaultParam.(names{k}); ivan@138: end ivan@138: end ivan@138: end ivan@138: ivan@138: x = problemData.x; ivan@138: ClipMask = find(problemData.IMiss); ivan@138: ivan@138: % According to this flag, switch between a parallel multithread processing ivan@138: % and a singlethread processing. This can fasten the computations but does ivan@138: % not affect the results. ivan@138: if param.MULTITHREAD_FRAME_PROCESSING ivan@138: [ReconstSignal1 ReconstSignal2] = multithreadProcessing(x,ClipMask,param); ivan@138: else ivan@138: [ReconstSignal1 ReconstSignal2] = singlethreadProcessing(x,ClipMask,param); ivan@138: end ivan@138: ivan@138: return; ivan@138: ivan@138: function [ReconstSignal1 ReconstSignal2] = singlethreadProcessing(x,ClipMask,param) ivan@138: % ======================================================== ivan@138: % Overlap-and-add processing of a signal with missing samples. ivan@138: % Decomposition into overlapping frames, processing of each ivan@138: % frame independently and OLA reconstruction. ivan@138: % Date: 01 Jun. 2010 ivan@138: % Inputs: ivan@138: % - x: Clipped signal ivan@138: % - ClipMask: Indices of clipped samples ivan@138: % - Optional parameters [and default values]: ivan@138: % - param.N: frame length [256] ivan@138: % - param.inpaintFrame: function handle for inpainting a frame ivan@138: % [@inpaintFrame_OMP] ivan@138: % - param.OLA_frameOverlapFactor: overlap factor between frames [2] ivan@138: % - param.wa: weighting analysis window [@sineWin] ivan@138: % - param.OLA_ws: weighting synthesis window [@sineWin] ivan@138: % - param.SKIP_CLEAN_FRAMES: flag to skip frames with no ivan@138: % missing samples [true] ivan@138: % - other fields: see the documentation the inpainting method ivan@138: % ivan@138: % Outputs: ivan@138: % ReconstSignal1 - reconstructed signal (all samples generated ivan@138: % from the synthesis model) ivan@138: % ReconstSignal2 - reconstructed signal (only clipped samples are generated ivan@138: % from the synthesis model) ivan@138: % ivan@138: % By Amir Adler, Maria Jafari, Valentin Emiya - SMALL Project, 2010 ivan@138: % ivan@138: % ======================================================== ivan@138: ivan@138: % Check parameters ivan@138: defaultParam.N = 256; ivan@138: defaultParam.inpaintFrame = @inpaintFrame_OMP; ivan@138: defaultParam.OLA_frameOverlapFactor = 2; ivan@138: defaultParam.wa = @wSine; ivan@138: defaultParam.ws = @wSine; ivan@138: defaultParam.SKIP_CLEAN_FRAMES = true; ivan@138: ivan@138: if nargin<3 ivan@138: param = defaultParam; ivan@138: else ivan@138: names = fieldnames(defaultParam); ivan@138: for k=1:length(names) ivan@138: if ~isfield(param,names{k}) || isempty(param.(names{k})) ivan@138: param.(names{k}) = defaultParam.(names{k}); ivan@138: end ivan@138: end ivan@138: end ivan@138: % if ~isfield(param,'D') ivan@138: % param.D = param.D_fun(param); ivan@138: % end ivan@138: ivan@138: bb=param.N; % block size ivan@138: ivan@138: % modify signal length to accommodate integer number of blocks ivan@138: L=floor(length(x)/bb)*bb; ivan@138: x=x(1:L); ivan@138: ClipMask(ClipMask>L) = []; ivan@138: ivan@138: % Extracting the signal blocks with 50% overlap ivan@138: Ibegin = (1:bb/param.OLA_frameOverlapFactor:length(x)-bb); ivan@138: if Ibegin(end)~=L-bb+1 ivan@138: Ibegin(end+1) = L-bb+1; ivan@138: end ivan@138: Iblk = ones(bb,1)*Ibegin+(0:bb-1).'*ones(size(Ibegin)); ivan@138: wa = param.wa(bb); % analysis window ivan@138: xFrames=diag(wa)*x(Iblk); ivan@138: ivan@138: % Generating the block mask ivan@138: Mask=ones(size(x)); ivan@138: Mask(ClipMask)=0; ivan@138: blkMask=Mask(Iblk); ivan@138: ivan@138: % Declipping the Patches ivan@138: [n,P]=size(xFrames); ivan@138: ivan@138: if ~isdeployed ivan@138: h=waitbar(0,'Processing each frame...'); ivan@138: end ivan@138: Reconst = zeros(n,P); ivan@138: co = zeros(512,P); ivan@138: for k=1:1:P, ivan@138: if ~isdeployed ivan@138: waitbar(k/P); ivan@138: end ivan@138: if param.SKIP_CLEAN_FRAMES && all(blkMask(:,k)) ivan@138: continue ivan@138: end ivan@138: frameProblemData.x = xFrames(:,k); ivan@138: frameProblemData.IMiss = ~blkMask(:,k); ivan@138: ivan@138: [Reconst(:,k)]= ... ivan@138: param.inpaintFrame(frameProblemData,param); ivan@138: ivan@138: end; ivan@138: if ~isdeployed ivan@138: close(h); ivan@138: end ivan@138: ivan@138: % Overlap and add ivan@138: ivan@138: % The completly reconstructed signal ivan@138: ReconstSignal1 = zeros(size(x)); ivan@138: ws = param.OLA_ws(bb); % synthesis window ivan@138: wNorm = zeros(size(ReconstSignal1)); ivan@138: for k=1:size(Iblk,2) ivan@138: ReconstSignal1(Iblk(:,k)) = ReconstSignal1(Iblk(:,k)) + Reconst(:,k).*ws(:); ivan@138: wNorm(Iblk(:,k)) = wNorm(Iblk(:,k)) + ws(:).*wa(:); ivan@138: end ivan@138: ReconstSignal1 = ReconstSignal1./wNorm; ivan@138: ivan@138: % Only replace the clipped samples with the reconstructed ones ivan@138: ReconstSignal2=x; ivan@138: ReconstSignal2(ClipMask)=ReconstSignal1(ClipMask); ivan@138: ivan@138: return; ivan@138: ivan@138: function [ReconstSignal1 ReconstSignal2] = multithreadProcessing(x,ClipMask,param) ivan@138: % Send parameters to the threads ivan@138: % initParamFilename = [param.OLA_par_threadDir 'par_param.mat']; ivan@138: % save(initParamFilename,'param'); ivan@138: ivan@138: bb=param.N; % block size ivan@138: ivan@138: % modify signal length to accommodate integer number of blocks ivan@138: L=floor(length(x)/bb)*bb; ivan@138: x=x(1:L); ivan@138: ClipMask(ClipMask>L) = []; ivan@138: ivan@138: % Extracting the signal blocks with 50% overlap ivan@138: Ibegin = (1:round(bb/param.OLA_frameOverlapFactor):length(x)-bb); ivan@138: if Ibegin(end)~=L-bb+1 ivan@138: Ibegin(end+1) = L-bb+1; ivan@138: end ivan@138: Iblk = ones(bb,1)*Ibegin+(0:bb-1).'*ones(size(Ibegin)); ivan@138: wa = param.wa(bb); % analysis window ivan@138: xFrames=diag(wa)*x(Iblk); ivan@138: ivan@138: % Generating the block mask ivan@138: Mask=ones(size(x)); ivan@138: Mask(ClipMask)=0; ivan@138: blkMask=Mask(Iblk); ivan@138: ivan@138: % Declipping the Patches ivan@138: if ~isdeployed && false ivan@138: h=waitbar(0,'Processing each frame...'); ivan@138: end ivan@138: [n,P]=size(xFrames); ivan@138: Reconst = NaN(n,P); ivan@138: % initializedThreads = []; ivan@138: ivan@138: % find the block of frames to process ivan@138: k_lists = {}; ivan@138: kTrame = 1; ivan@138: while kTrame<=P ivan@138: k_list = zeros(param.OLA_par_frameBlockSize,1); ivan@138: ind = 0; ivan@138: while ind