function demo_tfjigsawsep(demo) %RUNASSCRIPT
%DEMO_TFJIGSAWSEP - Decomposition of an audio signal into tonal, transient and residual layers
%
%   This demo shows how to use tfjigsawsep, where a signal is decomposed
%   into its tonal, transient and noisy residual layers. 
%   
%   The algorithm is based on [1]. It transforms a signal into a two-windowed
%   Gabor expansion such that one wide window shall lead to a high frequency
%   resolution (tonal layer is represented well) and a narrow one to a high
%   time resolution (transient layer is repr. well). The resulting Gabor
%   coefficients in the time-frequency plane are grided adaptively into rectangular
%   'supertiles', whithin one by one an entropy criterion decides, which
%   layer of the signal (tonal, transient) is represented better. This tile
%   will be kept if it is below a certain threshold, the other one is thrown
%   away. After running through the whole tf-plane, the respectively
%   leftover Gabor coefficients are transformed back and substracted 
%   from the original signal. By applying this procedure iteratively,
%   tonal and transient layers emerge.
%   A second version of the algorithm is available. Here the entropy
%   criterion chooses those tiles, where the tonal part of the signal is
%   represented better and is below a given threshold. The rest is set to
%   zero. The leftover Gabor coefficients are transformed back and
%   substracted from the original signal. Then the same is applied again to
%   choose those tiles, where the transient part is represented better.
%   After that, one gets the first approximation of the two layers. By
%   applying this procedure iteratively on the residual, tonal and
%   transient layers emerge.
%   
%   .. figure:: 
%
%      Separated layers
%      
%   See also: tfjigsawsep, plottfjigsawsep, dgtreal
%
%   References: jato07
%

% 
%   tfjigsawsep takes three very crucial parameters, t1,t2 and p. One has to
%   tweak and play with them to obtain good results:
%
%   t1 and t2 determine 'how likely' a part of the signal has been produced
%   by white noise. Good values are within (0.85,0.98), usually t2 > t1 works
%   well.
%
%   For speech signals lower values for t1 care for better noiseextraction
%   for musical signals, sometimes even t2 > 1 is necessary to extract all
%   the percussion elements
%
%   p determines the size of the supertiles and can be chosen within
%   (0,min(L/a1,M2/2)]. Values below 10 work best (tendencies):
%   higher for speech signals,lower for musical signals
%
%   Version 1 works particularly well for speech signals and detecting
%   percussive elements in musical signals, version 2 depicts the tonal layer
%   very nice, but is slower.
%
%   The default parameters are r1=r2=0.95, p=4 and the default settings for
%   the 3 Gabor systems are:
%   
%       "Tonal" system:     g1 = {'hann',4096}; a1 = 512; M1 = 4096;
%   
%       "Transient" system: g2 = {'hann',256};  a2 = 32;  M2 = 256;
%
%       "Residual" system:  g3 = {'hann',2048}; a3 = 512; M3 = 2048;
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Several scenarios are provided to give a demonstration, what effects the
% choice of the parameters have. Declare the corresp. string below.
%
% glockenspiel signal with added noise - version 2 of the algorithm:
%    'glo1': suitable parameters
%    'glo2': supertile size too large, tonal parts are in the transient layer
%    'glo3': t1 too large, t2 too small - transient parts are in the tonal
%            layer
%
% speech signal with added noise, a person says 'the cocktailpartyeffect' -
% version 1:
%    'spe1': suitable parameters
%    'spe2': supertile size too small, the algorithm cannot detect the
%            transients that are essential for speech signals properly
%    'spe3': t2 too large, tonal parts are in the transient layer
%
% synthetic test signal with dirac-like impulses and added noise -
% version 2:
%    'syn': the algorithm struggles with seperating high frequency impulses
%           and noise
%

%AUTHOR: Daniel Haider, 2017 

if nargin < 1, demo = 'syn'; end

switch demo
    case 'glo1'
        [f,fs] = gspi;
        f = f(1:2^16);
        f = f + 0.0001*randn(size(f));
        p = 2;
        r1 = 0.88;
        r2 = 0.87;
        tfjigsawsep(f,r1,r2,p,'plot','ver2','fs',fs);
    case 'glo2'
        [f,fs] = gspi;
        f = f(1:2^16);
        f = f + 0.001*randn(size(f));
        p = 10;
        r1 = 0.92;
        r2 = 0.93;        
        tfjigsawsep(f,r1,r2,p,'plot','ver2','fs',fs);
    case 'glo3'
        [f,fs] = gspi;
        f = f(1:2^16);
        f = f + 0.001*randn(size(f));
        p = 10;
        r1 = 0.98;
        r2 = 0.8;
        tfjigsawsep(f,r1,r2,p,'plot','ver2','fs',fs);
    case 'spe1'
        [f,fs] = cocktailparty;
        f = f(1:10^5);
        f = f + 0.001*rand(size(f));
        p = 10;
        r1 = 0.94;
        r2 = 0.87;
        tfjigsawsep(f,r1,r2,p,'plot','fs',fs);  
    case 'spe2'
        [f,fs] = cocktailparty;
        f = f(1:10^5);
        f = f + 0.001*rand(size(f));
        p = 2;
        r1 = 0.94;
        r2 = 0.87;
        tfjigsawsep(f,r1,r2,p,'plot','fs',fs);
    case 'spe3'
        [f,fs] = cocktailparty;
        f = f(1:10^5);
        f = f + 0.001*rand(size(f));
        p = 10;
        r1 = 0.94;
        r2 = 0.98;
        tfjigsawsep(f,r1,r2,p,'plot','fs',fs);
    case 'syn'
        [f,fs] = synthtest;
        f = f + 0.001*randn(size(f));
        p = 2;
        r1 = 0.85;
        r2 = 0.82;
        tfjigsawsep(f,r1,r2,p,'plot','ver2','fs',fs);   
    otherwise
        error('Please check the spelling of the string!')
end

function [s,fs] = synthtest()
amp=0.6; 
fs=44100;
dur1=1;
dur2=1.5;
freq1=440;
freq2=415.30;
freq3=392;
freq4=369.99;
val1=0:1/fs:dur1;
val2=0:1/fs:dur2;
a1 = amp*sin(2*pi* freq1*val1);
a2 = amp*sin(2*pi* freq2*val1);
a3 = amp*sin(2*pi* freq3*val1);
a4 = amp*sin(2*pi* freq4*val2);
b = zeros(1,length(a1)+length(a2)+length(a3)+length(a4));
b(1,1:1378:44096)=1;
b(1,44100:2756:88196)=1;
b(1,88200:5512:132296)=1;
b(1,132300:16538:198452)=1;
a = [a1,a2,a3,a4];
s = a+b;
s = normalize(s,'wav');


