%==========================================================================
%   Nápověda Vám pomůže v případě, pokud nevíte, jak ovládat program.
%==========================================================================
%   Program run_dec slouží pro vyjmutí vodoznaku z audia typu *.wav. 
%   -----------------------------------------------------------------------
%   Program Vás nejprve vyzve pomocí dialogového okna k načtení audio 
%   souboru typu *.wav. Do Command Window se načtou základní informace
%   o audiu. Po určité době se Vám vepíše do Command Window dekódovaný
%   VODOZNAK spolu s bitovou chybovostí a dobou potřebnou pro extrakci.
%==========================================================================
%   Pro spuštění programu zadejte do Command Window: run_dec
%==========================================================================

clear all
close all
home;
warning off all
disp('===================================================================');
disp('Pro načtení vodoznačeného audio souboru zmačkněte libovolnou klávesu');
disp('===================================================================');
pause;
clc

[filename,pathname] = uigetfile( ...
{'*.wav', 'Zvukové soubory (*.wav)';
'*.wav', 'Wave (*.wav)';...
'*.*', 'Vsechny soubory (*.*)'},...
'Vyberte vodoznačený audio soubor');
if isequal(filename,0)
   disp('Uživatel zvolil Storno')
   return
else
[x_waterm,fvz,nbits]=wavread(fullfile(pathname,filename));
      
[Wversn,Wname,Wext] = fileparts(filename);
disp(['Uživatel vybral audio soubor: ',Wname,Wext])
     
[N,channels] = size( x_waterm);
if channels==1
    kanal='mono';
else
    kanal='stereo';
end

t_hh=fix((N/fvz)/3600);
t_h=(N/fvz)/3600;
t_m=fix((t_h-fix(t_h))*60);
t_mm=(t_h-fix(t_h))*60;
t_s=(t_mm-fix(t_mm))*60;

disp('------------------------------------------------------------');
disp(['Celková délka audia: ', num2str(t_hh, '%02.0f'),':', num2str(t_m, '%02.0f'),':',num2str( t_s, '%06.3f'), ' s']);
disp(['       Počet kanalů: ' ,num2str( channels),' (',kanal,')']);
disp(['Vzorkovací kmitočet: ' ,num2str( fvz), ' Hz',' (CD kvalita)']);
disp(['     Bitová hloubka: ', num2str( nbits), ' bitů',' (CD kvalita)']);
disp('------------------------------------------------------------');

%Nacteni pomocných proměnných
matf=exist(['PNS_',[Wname],'.mat']);
matf1=exist(['PNR_',[Wname],'.mat']);
matf2=exist(['alfa_',[Wname],'.mat']);
matf3=exist(['cfs_',[Wname],'.mat']);
matf4=exist(['Th_',[Wname],'.mat']);
matf5=exist(['bipseq_',[Wname],'.mat']);

while (matf~= 2 & matf1~=2 & matf2~=2 & matf3~=2 & matf4~=2 & matf5~=2) || fvz~=44100
       if fvz~=44100
            button=questdlg({'Vámi zvolený audio soubor není v CD kvalitě';' ';'Potvrďte tlačítko ANO pro nové vložení'},'Pokračovat v ...','ANO','ANO');
            [filename,pathname] = uigetfile( ...
            {'*.wav', 'Zvukové soubory (*.wav)';
            '*.wav', 'Wave (*.wav)';...
            '*.*', 'Vsechny soubory (*.*)'},...
            'Vyber originální audio soubor');
            if isequal(filename,0)
                    disp('Uživatel zvolil Storno')
                return
            else
            [x_waterm,fvz,nbits]=wavread(fullfile(pathname,filename));
                
                    [Wversn,Wname,Wext] = fileparts(filename);
                    clc
                    disp(['Uživatel vybral audio soubor: ',Wname,Wext])
                    [N,channels] = size( x_waterm);
                        if channels==1
                            kanal='mono';
                        else
                            kanal='stereo';
                        end
                    t_hh=fix((N/fvz)/3600);
                    t_h=(N/fvz)/3600;
                    t_m=fix((t_h-fix(t_h))*60);
                    t_mm=(t_h-fix(t_h))*60;
                    t_s=(t_mm-fix(t_mm))*60;

                    disp('------------------------------------------------------------');
                    disp(['Celková délka audia: ', num2str(t_hh, '%02.0f'),':', num2str(t_m, '%02.0f'),':',num2str( t_s, '%05.3f'), ' s']);
                    disp(['       Počet kanalů: ' ,num2str( channels),' (',kanal,')']);
                    disp(['Vzorkovací kmitočet: ' ,num2str( fvz), ' Hz',' (CD kvalita)']);
                    disp(['     Bitová hloubka: ', num2str( nbits), ' bitů',' (CD kvalita)']);
                    disp('------------------------------------------------------------');
                
                    matf=exist(['PNS_',[Wname],'.mat']);
                    matf1=exist(['PNR_',[Wname],'.mat']);
                    matf2=exist(['alfa_',[Wname],'.mat']);
                    matf3=exist(['cfs_',[Wname],'.mat']);
                    matf4=exist(['Th_',[Wname],'.mat']);
                    matf5=exist(['bipseq_',[Wname],'.mat']);
                
                end
    
       else 
            button=questdlg({'Vodoznak nebyl ve zvoleném audiu nalezen';' ';'Pravděpodobně jste nevybral vodoznačené audio';' ';...
            'Chcete načíst nový audio soubor?'},'Pokračovat v ...','ANO','NE','ANO');
            if strcmp(button,'ANO');
                    clear all
                    [filename,pathname] = uigetfile( ...
                    {'*.wav', 'Zvukové soubory (*.wav)';
                    '*.wav', 'Wave (*.wav)';...
                    '*.*', 'Vsechny soubory (*.*)'},...
                    'Vyberte vodoznačený audio soubor');
                    if isequal(filename,0)
                            disp('Uživatel zvolil Storno')
                            return
                    else
                    [x_waterm,fvz,nbits]=wavread(fullfile(pathname,filename));
                    
                    [Wversn,Wname,Wext] = fileparts(filename);
                    clc
                    disp(['Uživatel vybral audio soubor: ',Wname,Wext])
                    [N,channels] = size( x_waterm);
                        if channels==1
                            kanal='mono';
                        else
                            kanal='stereo';
                        end
                    t_hh=fix((N/fvz)/3600);
                    t_h=(N/fvz)/3600;
                    t_m=fix((t_h-fix(t_h))*60);
                    t_mm=(t_h-fix(t_h))*60;
                    t_s=(t_mm-fix(t_mm))*60;

                    disp('------------------------------------------------------------');
                    disp(['Celková délka audia: ', num2str(t_hh, '%02.0f'),':', num2str(t_m, '%02.0f'),':',num2str( t_s, '%05.3f'), ' s']);
                    disp(['       Počet kanalů: ' ,num2str( channels),' (',kanal,')']);
                    disp(['Vzorkovací kmitočet: ' ,num2str( fvz), ' Hz',' (CD kvalita)']);
                    disp(['     Bitová hloubka: ', num2str( nbits), ' bitů',' (CD kvalita)']);
                    disp('------------------------------------------------------------');
                
                    matf=exist(['PNS_',[Wname],'.mat']);
                    matf1=exist(['PNR_',[Wname],'.mat']);
                    matf2=exist(['alfa_',[Wname],'.mat']);
                    matf3=exist(['cfs_',[Wname],'.mat']);
                    matf4=exist(['Th_',[Wname],'.mat']);
                    matf5=exist(['bipseq_',[Wname],'.mat']);
                
                        
                    end
            else strcmp(button,'NE');
                clear all
            return
            end    
        end
end
        PN_SeqW=dlmread(['PNS_',[Wname],'.mat']);
        PN_SeqR=dlmread(['PNR_',[Wname],'.mat']);
        alfa=dlmread(['alfa_',[Wname],'.mat']);
        cfs=dlmread(['cfs_',[Wname],'.mat']);
        bipwat=dlmread(['bipseq_',[Wname],'.mat']);
        Th1=dlmread(['Th_',[Wname],'.mat']);

tic;   



%funkce pro segmentaci vstupního audio signálu
wind = 2048;
prekryv = 50;
[Y,R,S]=segmentaced(x_waterm,wind,prekryv);

clc
disp(' ')
disp('Proces extrahování vodoznaku')
disp('Čekejte prosím...') 

%rozklad vstupních S segmentů pomoci DWPT a uložení jednotlivých
%koeficientů do matice cfs
for i=1:S
    T=wpdec(Y(:,i),8,'db8');
    T=wpjoin(T,[5;6;10;18;20;36;37;39;40;66;68;69;70;71;72;128;130;132;135;136]);
    cfse(:,i)=read(T,'allcfs');
end

%do vektoru sAll se uloží velikost koncových uzlů rozkladového stromu
sAll=read(T,'sizes',[255;256;128;259;260;130;263;264;132;66;...
        135;136;68;69;70;71;72;36;18;39;40;20;10;5;6]);
               
        
%Dekódování vodoznaku w
[nn,mm]=size(cfse);
www=0;
ww=1;
for jj=1:mm
    for ii=1:nn
        if alfa==0
            if cfs(ii,jj)^2 <= Th1(ii,jj)
                while www<ww
                    if cfse(ii,jj) > 0
                        bin(ww,1)=1;
                        www=www+1;
                    else
                        bin(ww,1)=-1;
                        www=www+1;
                    end
                end
                ww=ww+1;
            else
            end
        else    
            if cfs(ii,jj)^2 <= Th1(ii,jj)
                while www<ww
                    if cfse(ii,jj) > 0
                        bin(ww,1)=1;
                        www=www+1;
                    else
                        bin(ww,1)=-1;
                        www=www+1;
                    end
                end
                ww=ww+1;
            else
                while www<ww
                    if cfse(ii,jj)-cfs(ii,jj) >0
                        bin(ww,1)=1;
                        www=www+1;
                    else 
                        bin(ww,1)=-1;
                        www=www+1;
                    end
                end
                ww=ww+1;
            end
        end
    end
end
        
         
N=5;
PN_SeqW=PN_SeqW';
%oblast hledání synchronizační pn sekvence
obl=xcorr(bin(1:(2*(length(PN_SeqW))+(length(bipwat)*N)-1)),PN_SeqW);
oblm=find(obl==max(obl));
oblmb=oblm -((2*(length(PN_SeqW)))+((length(bipwat)*N)-1)-1);

%počet dekódovaných vodoznaků
num_W=floor((length(bin)-oblmb)/(length(PN_SeqW)+length(bipwat)*N));

for gg=1:num_W
    w((gg-1)*(length(bipwat)*N)+1:gg*(length(bipwat)*N),1)=bin(gg*(length(PN_SeqW))+oblmb+((gg-1)*(length(bipwat)*N)):gg*(length(PN_SeqW))+(gg*(length(bipwat)*N))+oblmb-1);
end

%De-spreading
PNRo=repmat(PN_SeqR,1,num_W);
w1=w.*PNRo';

%De-interleaving
M=length(bipwat);
radky_i=M;    
sloupce_i=N;

for di=1:num_W
   for ii=1:sloupce_i
        w2(1+M*(di-1):radky_i*di,ii)=w1(radky_i*(ii-1)+1+M*N*(di-1):radky_i*ii+M*N*(di-1));
    end 
end

for di=1:num_W
    for ii=1:radky_i
        w3(sloupce_i*(ii-1)+1+M*N*(di-1):sloupce_i*ii+M*N*(di-1),1)=w2(ii+M*(di-1),1:sloupce_i);
    end
end

%dekodované vodoznaky Wk
for ggg=1:num_W
    for q=1:length(bipwat)
        if sum(w3(((ggg-1)*length(bipwat)*N)+((q-1)*N)+1:((ggg-1)*length(bipwat)*N)+(q*N),1))>0
            w4(q,ggg)=1;
        else
            w4(q,ggg)=-1;
        end
    end
end

%Výsledný dekódovaný vodoznak Wk
    for qq=1:length(bipwat)
        if sign(sum(w4(qq,:)))>0
            w5(qq,1)=1;
        else
            w5(qq,1)=-1;
        end
    end


%Převod vodoznaku Wk na znaky

for L=1:length(w5),
        waterm(floor((L-1)/8)+1,L-floor((L-1)/8)*8)=(w5(L,1)+1)/2;
end
Watermark = char(bin2dec(num2str(waterm)))';

t_d=toc;
%BER
bipwat=bipwat';
[bit num_W]=size(w4);
poc=0;
for ii=1:num_W
    for jj=1:bit;
        if  (w4(jj,ii) == bipwat(jj,1))
        else
            poc=poc+1;
        end;
    end;
end
BER=(100/(num_W*bit))*poc;

t_hhd=fix((t_d)/3600);
t_hd=(t_d)/3600;
t_md=fix((t_hd-fix(t_hd))*60);
t_mmd=(t_hd-fix(t_hd))*60;
t_sd=(t_mmd-fix(t_mmd))*60;

clc
disp(' ')
disp(['Byl extrahován vodoznak: ', Watermark])
disp(' ')
disp(['Doba potřebná pro extrakci vodoznaku: ', num2str(t_hhd, '%02.0f'),':', num2str(t_md, '%02.0f'),':',num2str( t_sd, '%06.3f'), ' s'])
disp(['Bitová chybovost (BER): ',num2str(BER,'%02.2f'),' %'])


end
