classdef Transpozice < handle

    properties
        File
        PathName
        baseFs
        baseY
        yT
        player
        nsemitones
        yTAxes
        Fs
    end

    methods
        function obj = Transpozice(file, pathName)
                    obj.File = file;
                    obj.PathName = pathName;
                   [obj.baseY, obj.baseFs] = audioread(fullfile(pathName, file)); % Získání vstupních hodnot načteného signálu

                   %Převod signálu na mono
                   obj.baseY = mean(obj.baseY, 2);    

                   disp(['User selected', fullfile(pathName, file)]); % Vypsaní názvu souboru
        end
        
        function r = getFileName(obj)
                    [~, name, ext] = fileparts(fullfile(obj.PathName, obj.File));
                    r = strjoin({name, ext});
        end

        function obj = setNSemitones(obj, nsemitones)   
            obj.nsemitones = nsemitones;
            obj.modulateYT();
        end

        function obj = setFs(obj, Fs)
            obj.Fs = Fs;
        end

        
        % TRANSPOZICE
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        function obj = modulateYT(obj)
            if (obj.nsemitones ~= 0) % Pokud bude změněna hodnota půltónů, provede se následující operace

                % Zaokrouhlení počtu půltónů na celé číslo
                semitones = round(obj.nsemitones); 
    
                % Výpočet transpozičního koeficientu přes počtu půltónů
                transpozicniKoeficient = 2^(semitones/12);
                
                % Získání délky audio signálu
                signalLength = length(obj.baseY);
        
                % Vytvoření frekvenčního vektoru
                frequencies = (0:signalLength-1) * obj.baseFs / signalLength;
        
                % Výpočet změněných frekvencí pro každý bod v kmitočtovém spektru
                transposedFrequencies = frequencies * transpozicniKoeficient;
        
                % Interpolace vzorků audio signálu pro nové frekvence
               interpolatedSignal = interp1(frequencies', obj.baseY, transposedFrequencies', 'linear');
        
                obj.setYT(interpolatedSignal); % Hodnota, kterou funkce vrací jako výsledek               
            else % Pokud se hodnota nezmění
                obj.setFs(obj.baseFs);
                obj.setYT(obj.baseY);
            end
        end

       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       
        function obj = setYT(obj, yT)   
            obj.yT = yT;
            obj.plotYT();
            obj.player = audioplayer(obj.yT, obj.Fs);
        end

        % Vykreslení grafu
        function obj = plotYT(obj)
         
           % Vypočítání kmitočtového spektra signálu
                signal = obj.yT;
                N = length(signal); % délka signálu
                f = (0:N-1)*(obj.Fs/N); % vypočtení kmitočtů pro každý vzorek signálu
                signal(isnan(signal))=0;
                Y = fft(signal)/N; % Diskrétní Fourierova transformace
                
                % Výpočet amplitud a frekvencí
                amplitude = 2*abs(Y(1:N/2+1));
                frequency = f(1:N/2+1);
                
                % Zobrazení signálu v grafu
                plot(obj.yTAxes,frequency, amplitude);
                obj.yTAxes.XScale = 'log'; % Osa x bude logaritmická
                obj.yTAxes.XTick = [500 1000 2000 4000 8000]; % Nastavení hodnot na ose x
                obj.yTAxes.XLim = [400 8000]; % Nastavení rozsahu osy x, pro lepší zobrazení
        end
       %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

        function obj = setYTAxes(obj, yTAxes)
            obj.yTAxes = yTAxes;
        end

        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
        %%%%%%%%%%%%PŘEHRÁVAČ%%%%%%%%%%%%
        function obj = playAudio(obj)                       
            play(obj.player);
            disp(['Player,running ', obj.player.Running]);
        end
        
        function obj = pauseAudio(obj)
            pause(obj.player);
            disp(['Player,running ', obj.player.TimerPeriod]);
        end
        
        function obj = stopAudio(obj)
            stop(obj.player);
            disp(['Player,running ', obj.player.Running]);
        end  
     end
end