clear
close all

[in, fs] = audioread('Sounds/master.mp3');
% Master of puppets
in =  sum( in(235*fs:235.5*fs,:) , 2 );
in = in.*tukeywin(length(in),0.175);
N = length(in);
%%
Pz = [1];
h = [ 1; -Pz ];

zplane(1,h)
% Feedforward prediction
encoded_out_ff = filter(h,1,in);

% Feedback prediction
encoded_out_fb = zeros(size(in));
p = zeros(size(in));
Na = length(h)-1;
q = 4;
Q = 5;


wb = waitbar(0,'Please wait');
for n = Na+1 : N - 1
    
  waitbar((n-Na-1)/(N-1-Na-1),wb);
  p(n) = flipud(Pz)'*( p(n-length(Pz):n-1) +   encoded_out_fb(n-length(Pz):n-1)  );
  encoded_out_fb(n) = 1/Q*round( Q*(in(n) - p(n) )*(2^q-1)  ) / (2^q-1) ;
  
end
close(wb);

decoded_out_ff =  filter(1,h, 1/Q*round( Q*encoded_out_ff *(2^q-1) ) / (2^q-1) );
decoded_out_fb =  filter(1,h, 1/Q*round( Q*encoded_out_fb *(2^q-1) ) / (2^q-1) );
%%

figure('units','normalized','outerposition',[0 0 1 1])

subplot(1,2,1)
plot(  (1:N)/fs, running_rms ( decoded_out_ff - in  , fs, 0.1 ) ,'LineWidth',1.5);
hold on
plot(  (1:N)/fs, running_rms ( decoded_out_fb - in  , fs, 0.1 ) ,'LineWidth',1.5);
plot(  (1:N)/fs, running_rms ( round(in *(2^q-1) ) / (2^q-1) - in  , fs, 0.1 ) ,'LineWidth',1.5);
xlim([0,N/fs])
title('Quantization noise after decoding','FontSize',13);
xlabel('t -> [s]','FontSize',13);
ylabel('E_{RMS}(t) -> [V]','FontSize',13);
l = legend('Feedforward structure','Feedback structure','original quantized signal');
set(l,'FontSize',13)
grid on


subplot(1,2,2)
plot(  (1:N)/fs, running_rms ( decoded_out_ff - in  , fs, 0.1 ) ,'LineWidth',1.5);
hold on
plot(  (1:N)/fs, running_rms ( decoded_out_fb - in  , fs, 0.1 ) ,'LineWidth',1.5);
plot(  (1:N)/fs, running_rms ( round(in *(2^q-1) ) / (2^q-1) - in  , fs, 0.1 ) ,'LineWidth',1.5);

title('Quantization noise after decoding','FontSize',13);
xlabel('t -> [s]','FontSize',13);
ylabel('E_{RMS}(t) -> [V]','FontSize',13);
l = legend('Feedforward structure','Feedback structure','original quantized signal');
set(l,'FontSize',13)
ylim([0,max( running_rms ( decoded_out_fb - in  , fs, 0.1 ))*8])
grid on
xlim([0,N/fs]);