% Prueba del algoritmo de fingerprints.
% En esta prueba vamos variando el numero de muestras por frame (N), es
% decir, el tamano de la ventana de Hamming.

% OBJETIVO: ver hasta que valor del tamaño de la ventana de Hamming podemos
% aumentar obteniendo un funcionamiento correcto del algoritmo. Al tener un
% mayor tamaño de la ventana, el numero de sub-fingerprints por cada 3
% segundos de anuncio detectado sera menor, y, por tanto, el tiempo de
% computacion disminuira

% Fecha de creacion: 8 de Enero de 2007
% Ultima modificacion: 15 de Marzo de 2007

% Caracteristicas de la prueba

% N=parametro variable

over_lap=31/32;
num_band=33;
finf=300;
fsup=2000;
alpha=0.18;                  % umbral para considerar deteccion correcta. Calculado en la fase de analisis

time_detect=24000;           % numero de muestras correspondientes al tiempo del trozo de audio que se coge. 24000 se corresponden a 3segundos*8000muestras/segundo

fi=fopen('p_N_2960_1000_23960','w');     %abrimos un fichero para almacenar los resultados

% Indices necesarios:
p=1;

for N=2960:1000:23960

    % Calculo de los fingerprints de los anuncios empleados en la prueba

    f_22_23_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\22_23_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_22_23_02_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\22_23_02_8000_8'),N,over_lap,num_band,finf,fsup);
    f_22_23_03_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\22_23_03_8000_8'),N,over_lap,num_band,finf,fsup);
    f_22_23_04_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\22_23_04_8000_8'),N,over_lap,num_band,finf,fsup);
    f_01_07_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\01_07_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_08_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\08_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_09_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\09_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_10_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\10_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_11_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\11_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_12_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\12_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_13_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\13_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_14_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\14_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_17_19_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\17_19_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_18_23_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\18_23_01_8000_8'),N,over_lap,num_band,finf,fsup);
    f_20_23_01_8000_8=fingerprint_actualizable(wavread('Anuncios\Procesado\20_23_01_8000_8'),N,over_lap,num_band,finf,fsup);

    %simulamos como si se cogiera un intervalo de tiempo de una emision de
    %radio y se analizara si se corresponde con algun anuncio de la base de datos

    anuncio_detectado=wavread('Anuncios\Procesado\22_23_01_8000_8');

    t=1;
    s=1;
    key=1;
    for repeticion=1:1000                                             % repeticion para cada valor de N
        l=round((length(anuncio_detectado)-time_detect)*rand(1));     %valor escogido al azar para tomar un trozo al azar del anuncio leido

        t1=cputime;

        finger_detectado=fingerprint_actualizable(anuncio_detectado(l:l+time_detect-1,1),N,over_lap,num_band,finf,fsup);
        
        aux_times(repeticion)=cputime-t1;
    
    % La primera vez que entramos en el bucle, preparamos una variable,
    % 'probab', para almacenar las probabilidades de cada anuncio de ser
    % considerado como detectado
       
        if key==1
            key=0;
            [m,n]=size(finger_detectado);
            num_bits=m*n;                          %numero de bits que se comparan en la busqueda
            probab_alarm=zeros(1,m*n);
            probab_no_alarm=zeros(1,m*n);
        end
    
        j=1;
        distancia(j)=min(busqueda(finger_detectado,f_22_23_01_8000_8));
        if distancia(j)~=0
            probab_alarm(1,distancia(j))=probab_alarm(1,distancia(j))+1;
        end
        dist_alarm(p,t)=distancia(j);                % almacena distancia en deteccion correcta para calculo de probabilidad de alarma
        t=t+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_22_23_02_8000_8));
        if distancia(j)~=0
            probab_alarm(1,distancia(j))=probab_alarm(1,distancia(j))+1;
        end
        dist_alarm(p,t)=distancia(j);
        t=t+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_22_23_03_8000_8));
        if distancia(j)~=0
            probab_alarm(1,distancia(j))=probab_alarm(1,distancia(j))+1;
        end
        dist_alarm(p,t)=distancia(j);
        t=t+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_22_23_04_8000_8));
        if distancia(j)~=0
            probab_alarm(1,distancia(j))=probab_alarm(1,distancia(j))+1;
        end
        dist_alarm(p,t)=distancia(j);
        t=t+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_01_07_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);          % almacena distancia en deteccion correcta para calculo de probabilidad de falsa alarma
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_08_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_09_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_10_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_11_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_12_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_13_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_14_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_17_19_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_18_23_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;
        j=j+1;
        distancia(j)=min(busqueda(finger_detectado,f_20_23_01_8000_8));
        probab_no_alarm(1,distancia(j))=probab_no_alarm(1,distancia(j))+1;
        dist_no_alarm(p,s)=distancia(j);
        s=s+1;

        [h,q]=min(distancia);

    if (h/num_bits<alpha)                  %si el porcentaje de bits incorrectos es superior al alpha se considera que el trozo de audio que se esta 
                                           %estudiando no se corresponde con ningun anuncio de nuestra base de anuncios
        fprintf(fi,'Anuncio detectado: ANUNCIO NUMERO %1.0f con una probabilidad de deteccion correcta del %2.2f\n',q,(1-h/num_bits)*100);
    else
        fprintf(fi,'NO SE HA DETECTADO NINGUN ANUNCIO. La probabilidad de deteccion mas alta ha sido de %2.2f\n',(1-h/num_bits)*100');
    end


    fprintf(fi,'Tamaño de la ventana de Hamming: %1.0f muestras\n',N);
    fprintf(fi,'Tiempo en calcular el fingerprint: %2.4f   Numero de anuncios: %1.0f\n\n',t2-t1,j);
   
    end
    
times(p)=mean(aux_times);     % Guardamos el tiempo empleado en calcular el finprint para cada valor de N

figure;
plot((1:m*n)/m/n,probab_alarm/sum(probab_alarm),'rx')
hold on;
plot((1:m*n)/m/n,probab_no_alarm/sum(probab_no_alarm),'yx')
plot((1:m*n)/m/n,zeros(1,m*n),'kx')
title(['N = ',num2str(N)]);
xlabel('Tasa de error de bit entre fingerprints');
ylabel('pdf');

%Añade una linea vertical que simula el umbral
plot([alpha alpha],[0 max(probab_no_alarm/sum(probab_no_alarm))]) 
hold off;

% Calculo de los parametros de la distribucion que mas se aproxima a cada
% uno de los dos casos:

% Para evitar problemas con 'wblfit'
if(min(dist_alarm(p,:))==0)      
    dist_alarm(p,:)=dist_alarm(p,:)+10^(-6);
end


[a,b]=wblfit(dist_alarm(p,:));
[c,d]=normfit(dist_no_alarm(p,:));

% Probabilidad de producirse una deteccion incorrecta

prob1(p)=1-wblcdf(alpha,a(1,1)/(m*n),a(1,2));
prob2(p)=normcdf(alpha,c/(m*n),d/(m*n));


fprintf(fi,'Tamaño de la ventana de Hamming: %1.0f muestras\n',N);
fprintf(fi,'Numero de bits por fingerprint detectado: %4.0fx%4.0f\n',m,n);
fprintf(fi,'Tiempo en calcular el fingerprint: %2.4f\n',times(p));
fprintf(fi,'Pn: %2.4e   Pf: %2.4e\n\n\n',prob1(p),prob2(p));

p=p+1;

end


% Dibujamos la relacion del tiempo de calculo del fingerprint con respecto
% al parametro analizado

plot(2960:1000:24000,times);

fi=fopen('p_N_2960_1000_23960','r');
type p_N_2960_1000_23960  % Abre el fichero creado