diff toolboxes/AudioInpaintingToolbox/Solvers/inpaintSignal_IndependentProcessingOfFrames.m @ 138:56d719a5fd31 ivand_dev

Audio Inpaintin Toolbox
author Ivan Damnjanovic lnx <ivan.damnjanovic@eecs.qmul.ac.uk>
date Thu, 21 Jul 2011 14:27:47 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolboxes/AudioInpaintingToolbox/Solvers/inpaintSignal_IndependentProcessingOfFrames.m	Thu Jul 21 14:27:47 2011 +0100
@@ -0,0 +1,372 @@
+function [ReconstSignal1 ReconstSignal2] = inpaintSignal_IndependentProcessingOfFrames(problemData,param)
+%
+%
+% Usage:
+%
+%
+% Inputs:
+%          - 
+%          - 
+%          - 
+%          - 
+%          - 
+%          - 
+%          - 
+%          - 
+%
+% Outputs:
+%          - 
+%          - 
+%          - 
+%          - 
+%
+% Note that the CVX library is needed.
+%
+% -------------------
+%
+% Audio Inpainting toolbox
+% Date: June 28, 2011
+% By Valentin Emiya, Amir Adler, Maria Jafari
+% This code is distributed under the terms of the GNU Public License version 3 (http://www.gnu.org/licenses/gpl.txt).
+% ========================================================
+% Perform Audio De-clipping with overlapping blocks
+% Synthesis Approach, union of overcomplete DCT dictionary
+% Date: 14 Apr. 2010
+% Inputs:
+%          - x: Clipped signal
+%          - ClipMask: Indices of clipped samples
+%          - Optional parameters [and default values]:
+%             - param.N: frame length [256]
+%             - param.frameOverlapFactor: overlap factor between frames [2]
+%             - param.wa: weighting analysis window [@sineWin]
+%             - param.ws: weighting synthesis window [@sineWin]
+%             - param.OMPerr: error threshold to stop OMP iterations [0.001]
+%             - param.sparsityDegree: max number of non-zero components to
+%             stop OMP iterations [param.N/4];
+%             - other fields: see the documentation of UDCT_Dictionary
+%
+% Outputs:
+%          ReconstSignal1 - reconstructed signal (all samples generated
+%          from the synthesis model)
+%          ReconstSignal2 - reconstructed signal (only clipped samples are generated
+%          from the synthesis model)
+%
+% By Valentin Emiya - SMALL Project, 2010
+% 
+% ========================================================
+
+% Check parameters
+defaultParam.N = 256;
+defaultParam.OLA_frameOverlapFactor = 4;
+defaultParam.wa = @wSine;
+defaultParam.OLA_ws = @wSine;
+defaultParam.OLA_par_waitingTime_mainProcess = 0.2;
+defaultParam.OLA_par_waitingTime_thread = 0.2;
+defaultParam.OLA_par_frameBlockSize = 1;
+defaultParam.TCPIP_port = 3000;
+defaultParam.COM_DISP = false;
+defaultParam.STATE_DISP = false;
+
+if nargin<2
+    param = defaultParam;
+else
+    names = fieldnames(defaultParam);
+    for k=1:length(names)
+        if ~isfield(param,names{k}) || isempty(param.(names{k}))
+            param.(names{k}) = defaultParam.(names{k});
+        end
+    end
+end
+
+x = problemData.x;
+ClipMask = find(problemData.IMiss);
+
+% According to this flag, switch between a parallel multithread processing
+% and a singlethread processing. This can fasten the computations but does
+% not affect the results.
+if param.MULTITHREAD_FRAME_PROCESSING
+   [ReconstSignal1 ReconstSignal2] = multithreadProcessing(x,ClipMask,param);
+else
+   [ReconstSignal1 ReconstSignal2] = singlethreadProcessing(x,ClipMask,param);
+end
+
+return;
+
+function [ReconstSignal1 ReconstSignal2] = singlethreadProcessing(x,ClipMask,param)
+% ========================================================
+% Overlap-and-add processing of a signal with missing samples.
+% Decomposition into overlapping frames, processing of each
+% frame independently and OLA reconstruction.
+% Date: 01 Jun. 2010
+% Inputs:
+%          - x: Clipped signal
+%          - ClipMask: Indices of clipped samples
+%          - Optional parameters [and default values]:
+%             - param.N: frame length [256]
+%             - param.inpaintFrame: function handle for inpainting a frame
+%             [@inpaintFrame_OMP]
+%             - param.OLA_frameOverlapFactor: overlap factor between frames [2]
+%             - param.wa: weighting analysis window [@sineWin]
+%             - param.OLA_ws: weighting synthesis window [@sineWin]
+%             - param.SKIP_CLEAN_FRAMES: flag to skip frames with no
+%             missing samples [true]
+%             - other fields: see the documentation the inpainting method
+%
+% Outputs:
+%          ReconstSignal1 - reconstructed signal (all samples generated
+%          from the synthesis model)
+%          ReconstSignal2 - reconstructed signal (only clipped samples are generated
+%          from the synthesis model)
+%
+% By Amir Adler, Maria Jafari, Valentin Emiya - SMALL Project, 2010
+% 
+% ========================================================
+
+% Check parameters
+defaultParam.N = 256;
+defaultParam.inpaintFrame = @inpaintFrame_OMP;
+defaultParam.OLA_frameOverlapFactor = 2;
+defaultParam.wa = @wSine;
+defaultParam.ws = @wSine;
+defaultParam.SKIP_CLEAN_FRAMES = true;
+
+if nargin<3
+    param = defaultParam;
+else
+    names = fieldnames(defaultParam);
+    for k=1:length(names)
+        if ~isfield(param,names{k}) || isempty(param.(names{k}))
+            param.(names{k}) = defaultParam.(names{k});
+        end
+    end
+end
+% if ~isfield(param,'D')
+%    param.D = param.D_fun(param);
+% end
+
+bb=param.N; % block size
+
+% modify signal length to accommodate integer number of blocks
+L=floor(length(x)/bb)*bb;
+x=x(1:L);
+ClipMask(ClipMask>L) = [];
+
+% Extracting the signal blocks with 50% overlap
+Ibegin = (1:bb/param.OLA_frameOverlapFactor:length(x)-bb);
+if Ibegin(end)~=L-bb+1
+    Ibegin(end+1) = L-bb+1;
+end
+Iblk = ones(bb,1)*Ibegin+(0:bb-1).'*ones(size(Ibegin));
+wa = param.wa(bb); % analysis window
+xFrames=diag(wa)*x(Iblk);
+
+% Generating the block mask
+Mask=ones(size(x));
+Mask(ClipMask)=0;
+blkMask=Mask(Iblk);
+
+% Declipping the Patches
+[n,P]=size(xFrames);
+
+if ~isdeployed
+    h=waitbar(0,'Processing each frame...');
+end
+Reconst = zeros(n,P);
+co = zeros(512,P);
+for k=1:1:P,
+    if ~isdeployed
+        waitbar(k/P);
+    end
+    if param.SKIP_CLEAN_FRAMES && all(blkMask(:,k))
+        continue
+    end
+    frameProblemData.x = xFrames(:,k);
+    frameProblemData.IMiss = ~blkMask(:,k);
+    
+    [Reconst(:,k)]= ...
+        param.inpaintFrame(frameProblemData,param);
+   
+end;
+if ~isdeployed
+    close(h);
+end
+
+% Overlap and add
+
+% The completly reconstructed signal
+ReconstSignal1 = zeros(size(x));
+ws = param.OLA_ws(bb); % synthesis window
+wNorm = zeros(size(ReconstSignal1));
+for k=1:size(Iblk,2)
+    ReconstSignal1(Iblk(:,k)) = ReconstSignal1(Iblk(:,k)) + Reconst(:,k).*ws(:);
+    wNorm(Iblk(:,k)) = wNorm(Iblk(:,k)) + ws(:).*wa(:);
+end
+ReconstSignal1 = ReconstSignal1./wNorm;
+
+% Only replace the clipped samples with the reconstructed ones
+ReconstSignal2=x;
+ReconstSignal2(ClipMask)=ReconstSignal1(ClipMask);
+
+return;
+
+function [ReconstSignal1 ReconstSignal2] = multithreadProcessing(x,ClipMask,param)
+% Send parameters to the threads
+% initParamFilename = [param.OLA_par_threadDir 'par_param.mat'];
+% save(initParamFilename,'param');
+
+bb=param.N; % block size
+
+% modify signal length to accommodate integer number of blocks
+L=floor(length(x)/bb)*bb;
+x=x(1:L);
+ClipMask(ClipMask>L) = [];
+
+% Extracting the signal blocks with 50% overlap
+Ibegin = (1:round(bb/param.OLA_frameOverlapFactor):length(x)-bb);
+if Ibegin(end)~=L-bb+1
+    Ibegin(end+1) = L-bb+1;
+end
+Iblk = ones(bb,1)*Ibegin+(0:bb-1).'*ones(size(Ibegin));
+wa = param.wa(bb); % analysis window
+xFrames=diag(wa)*x(Iblk);
+
+% Generating the block mask
+Mask=ones(size(x));
+Mask(ClipMask)=0;
+blkMask=Mask(Iblk);
+
+% Declipping the Patches
+if ~isdeployed && false
+    h=waitbar(0,'Processing each frame...');
+end
+[n,P]=size(xFrames);
+Reconst = NaN(n,P);
+% initializedThreads = [];
+
+% find the block of frames to process
+k_lists = {};
+kTrame = 1;
+while kTrame<=P
+    k_list = zeros(param.OLA_par_frameBlockSize,1);
+    ind = 0;
+    while ind<param.OLA_par_frameBlockSize && kTrame<=P
+        if param.SKIP_CLEAN_FRAMES && all(blkMask(:,kTrame))
+            kTrame=kTrame+1;
+            continue
+        end
+        ind = ind+1;
+        k_list(ind) = kTrame;
+        kTrame=kTrame+1;
+    end
+    if ind==0
+        break;
+    end
+    k_lists{end+1} = k_list(1:ind);
+end
+k_list_all = cell2mat(k_lists');
+
+% Create a server
+serverSocket = createServer(param);
+% Definition of the client states
+stateDef;
+
+param.COM_DISP = false;
+
+kBlock=1;
+initializedClientIDs = [];
+while any(isnan(Reconst(1,k_list_all)))
+        if ~isdeployed && false
+            waitbar(sum(~isnan(Reconst(1,k_list_all)))/length(k_list_all));
+        end
+    
+    % Wait for a new client
+    currentClient = waitClient(serverSocket);
+    
+    % Receive client state
+    clientIDState = readData(currentClient,param.COM_DISP);
+    clientID = clientIDState(1);
+    clientState = clientIDState(2);
+    switch clientState
+        case INIT
+            if param.STATE_DISP
+                fprintf('INIT %d\n',clientID);
+            end
+            if 0
+               sendData(currentClient,initParamFilename,param.COM_DISP);
+            else
+               sendData(currentClient,param,param.COM_DISP);
+            end
+            initializedClientIDs(end+1) = clientID;
+        case FREE
+            if ~ismember(clientID,initializedClientIDs)
+                sendData(currentClient,INIT_ORDER,param.COM_DISP); % INIT
+            elseif kBlock<=length(k_lists)
+                k_list = k_lists{kBlock};
+                if param.STATE_DISP
+                    fprintf('TO PROCESS %d:',clientID);
+                    arrayfun(@(x)fprintf(' %d',x),k_list);
+                    fprintf('\n');
+                end
+                sendData(currentClient,k_list,param.COM_DISP);
+                sendData(currentClient,xFrames(:,k_list),param.COM_DISP);
+                sendData(currentClient,find(blkMask(:,k_list)),param.COM_DISP);
+                kBlock = kBlock+1;
+            else
+                if param.STATE_DISP
+                    fprintf('WAIT %d\n',clientID);
+                end
+                sendData(currentClient,WAIT_ORDER,param.COM_DISP); % no data to process
+            end
+        case PROCESSED
+            processed_k_list = readData(currentClient,param.COM_DISP);
+            y = readData(currentClient,param.COM_DISP);
+            y = reshape(y,[],length(processed_k_list));
+            if param.STATE_DISP
+                fprintf('PROCESSED %d:',clientID);
+                arrayfun(@(x)fprintf(' %d',x),processed_k_list);
+                fprintf('\n');
+            end
+            if ~isempty(processed_k_list)
+                Reconst(:,processed_k_list) = y;
+            end
+        otherwise
+            error('switch:UndefinedClientState','Undefined client state');
+    end
+    
+    closeClientConnection(currentClient);
+end;
+
+% Close the server
+closeServer(serverSocket);
+
+if ~isdeployed && false
+    close(h);
+end
+
+% Overlap and add
+
+% The completly reconstructed signal
+ReconstSignal1 = zeros(size(x));
+ws = param.OLA_ws(bb); % synthesis window
+wNorm = zeros(size(ReconstSignal1));
+for k=1:size(Iblk,2)
+    ReconstSignal1(Iblk(:,k)) = ReconstSignal1(Iblk(:,k)) + Reconst(:,k).*ws(:);
+    wNorm(Iblk(:,k)) = wNorm(Iblk(:,k)) + ws(:).*wa(:);
+end
+ReconstSignal1 = ReconstSignal1./wNorm;
+
+% Only replace the clipped samples with the reconstructed ones
+ReconstSignal2=x;
+ReconstSignal2(ClipMask)=ReconstSignal1(ClipMask);
+
+killClients(param);
+
+return;
+
+% ========================================================
+% ========================================================
+
+
+
+% ========================================================
+% ========================================================