function data = generateAudioDenoiseProblem(soundfile, sigma, windowSize,...
    overlap, wa, ws, trainnum, redundancyFactor, initdict)
%%  Audio Denoising Problem
%
%   generateAudioDenoiseProblem is part of the SMALLbox and generate a
%   problem for comaprison of Dictionary Learning/Sparse Representation
%   techniques in audio denoising scenario.
%
%   The function takes as an optional input 
%       soundfile   - name of the file
%       sigma       - noise level (dB)
%       windowSize  - 1D frame size (eg 512)
%       overlap     - ammount of overlaping frames between 0 and 1
%       wa,ws       - analisys and synthesis window functions
%       
%       trainnum    - number of frames for training 
%       redundancyFactor - overcompletness of dictionary (default 2)
%       initdict    - initial dictionary
%   
%   The function outputs the structure with following fields:
%       Original    - original signal
%       Noisy       - signal with added noise
%       fs          - sample rate of the original signal in Hertz
%       nbits       - the number of bits per sample
%       sigma       - added noise level
%       b           - matrix of training samples for dictionary learning
%       b1          - matrix containing all frames for reconstruction step
%       m           - size od dictionary atom 
%       n           - number of frames for training
%       p           - number of atoms in dictionary
%       windowSize  - 1D frame size (eg 512)
%       overlap     - ammount of overlaping frames between 0 and 1
%       wa,ws       - analisys and synthesis window functions
%       initdict	- initial dictionary

%   Centre for Digital Music, Queen Mary, University of London.
%   This file copyright 2011 Ivan Damnjanovic.
%
%   This program is free software; you can redistribute it and/or
%   modify it under the terms of the GNU General Public License as
%   published by the Free Software Foundation; either version 2 of the
%   License, or (at your option) any later version.  See the file
%   COPYING included with this distribution for more information.
%%  
disp(' ');
disp('  **********  Denoising Problem  **********');
disp(' ');
disp('  This function reads an audio, adds random Gaussian noise,');
disp('  that can be later denoised by using dictionary learning techniques.');
disp(' ');

FS=filesep;

%% prompt user for wav file %%
%ask for file name

TMPpath=pwd;
if ~ exist( 'soundfile', 'var' ) || isempty(soundfile)
    %ask for file name 
    [pathstr1, name, ext, versn] = fileparts(which('SMALLboxSetup.m'));
    cd([pathstr1,FS,'data',FS,'audio']);
    [filename,pathname] = uigetfile({'*.mat; *.mid; *.wav'},'Select a file to transcribe');
    [pathstr, name, ext, versn] = fileparts(filename);
    data.name=name;

    if strcmp(ext,'.mid')
        midi=readmidi(filename);
%         data.notesOriginal=midiInfo(midi);
        y=midi2audio(midi);
        wavwrite(y, 44100, 16, 'temp.wav');
        [x.signal, x.fs, x.nbits]=wavread('temp.wav');
        delete('temp.wav');
    elseif strcmp(ext,'.wav')
%         cd([pathstr1,FS, 'data', FS, 'audio', FS, 'midi']);
%         filename1=[name, '.mid'];
%         if exist(filename1, 'file')
%             midi=readmidi(filename1);
%             data.notesOriginal=midiInfo(midi);
%         end
        cd([pathstr1,FS, 'data', FS, 'audio', FS, 'wav']);
        [x.signal, x.fs, x.nbits]=wavread(filename);
    else
%         cd([pathstr1,FS, 'data', FS, 'audio', FS, 'midi']);
%         filename1=[name, '.mid'];
%         if exist(filename1, 'file')
%             midi=readmidi(filename1);
%             data.notesOriginal=midiInfo(midi);
%         end
        cd([pathstr1,FS, 'data', FS, 'audio', FS, 'mat']);
        x=load([pathname,filename]);
    end
else
    [x.signal, x.fs, x.nbits]=wavread(soundfile);
    [pathstr, name, ext, versn] = fileparts(soundfile);
    data.name=name;
end

%% set parameters %%
if ~ exist( 'sigma', 'var' ) || isempty(sigma), sigma = 0.2; end

if ~ exist( 'windowSize', 'var' ) || isempty(windowSize), windowSize = 256;end
if ~ exist( 'overlap', 'var' ) || isempty(overlap), overlap = 0.5; end
if ~ exist( 'wa', 'var' ) || isempty(wa), wa = @wSine; end % Analysis window
if ~ exist( 'ws', 'var' ) || isempty(ws), ws = @wSine; end % Synthesis window


if ~ exist( 'redundancyFactor', 'var' ) || isempty(windowSize),...
        redundancyFactor = 2;end
if ~ exist( 'initdict', 'var' ) || isempty(initdict),...
        initdict = 'odct'; end
if ~ exist( 'trainnum', 'var' ) || isempty(trainnum), ...
        trainnum = 16*redundancyFactor*windowSize;end

if (strcmpi(initdict,'odct'))
    initdict = odctndict(windowSize, redundancyFactor*windowSize, 1);
elseif (strcmpi(initdict,'data'))
    clear initdict;    % causes initialization using random examples
else
    error('Invalid initial dictionary specified.');
end

if exist( 'initdict', 'var' ) 
  initdict = initdict(:,1:redundancyFactor*windowSize);
end


%%%% create training data %%%

%% generate noisy audio %%

disp(' ');
disp('Generating noisy audio...');
x.signal = x.signal/max(abs(x.signal(:)))*0.99999;
n = randn(size(x.signal)) .* sigma;

xnoise = x.signal + n;%  here we can load noise audio if available 
                 %  for example: wavread('icassp06_x.wav');%

                 


X = im2colstep(xnoise,[windowSize 1],[overlap*windowSize 1]);
X = diag(wa(windowSize)) * X;





% remove dc in blocks to conserve memory %
% bsize = 2000;
% for i = 1:bsize:size(X,2)
%   blockids = i : min(i+bsize-1,size(X,2));
%   X(:,blockids) = remove_dc(X(:,blockids),'columns');
% end
data.Original = x.signal;
data.Noisy = xnoise;
data.fs = x.fs;
data.nbits = x.nbits;

data.sigma = sigma;


if (trainnum<size(X,2))
    p = randperm(size(X,2));
    p=sort(p(1:trainnum));
    data.b = X(:,p);
else
    data.b = X;
end

data.b1 = X;
[data.m, data.n] = size(data.b);
data.p = redundancyFactor*windowSize;

data.windowSize = windowSize;
data.overlap = overlap;
data.ws = ws;
data.wa = wa;

data.initdict= initdict;

cd(TMPpath);

