%% Differential PCM Example
clear; close all; clc;
predictor = [0 0.85]; % y(k)=a*x(k-1)
pred_ord=2;     % optimum predictor order
partition = [-1:.1:.9];
codebook = [-1:.1:1];
t = [0:pi/50:2*pi];
x = sawtooth(3*t); % Original signal
% Quantize x using DPCM.
encodedx = dpcmenco(x,codebook,partition,predictor);
% Try to recover x from the modulated signal.
decodedx = dpcmdeco(encodedx,codebook,predictor);
figure()
h=plot(t,x,t,decodedx); grid on
set(h(1),'LineWidth',2)
set(h(2),'LineWidth',2)
xlabel('t');ylabel('x(t)');
legend('Original Signal','Decoded DPCM')
title('Non-optimized DPCM');
ylim([-1.25 1.5]);
distor = sum((x-decodedx).^2)/length(x); % Mean square error
%% Optimized DPCM
initcodebook = [-1:.1:1]; % Initial guess at codebook
% Optimize parameters, using initial codebook and order 1.
[opt_predictor,opt_codebook,opt_partition] = dpcmopt(x,pred_ord,initcodebook);
% Quantize x using DPCM.
encodedx = dpcmenco(x,opt_codebook,opt_partition,opt_predictor);
%% DPCM Encoded Signal
figure()
plot(t,encodedx,'LineWidth',2); grid on
title('Encoded DPCM')
% Try to recover x from the modulated signal.
decodedx = dpcmdeco(encodedx,opt_codebook,opt_predictor);
distoptr = sum((x-decodedx).^2)/length(x); % Mean square error
disp(['Non-optimized MS error = ',num2str(pow2db(distor)),' dB']);
disp(['Optimized MS error = ',num2str(pow2db(distoptr)),' dB']);
figure()
h=plot(t,x,t,decodedx);  grid on
set(h,'LineWidth',2)
xlabel('t');ylabel('x(t)');
legend('Original Signal','Decoded DPCM')
title('Optimized DPCM');
ylim([-1.25 1.5]);
figure()
x_val=[0:1/length(partition):1-1/length(partition)];
plot(x_val,partition,'LineWidth',2);hold on;
x_val=[0:1/length(opt_partition):1-1/length(opt_partition)];
plot(x_val,opt_partition,'LineWidth',2);grid;
legend('Non-optimum partition','Optimum partition','Location','NorthWest');grid on
disp(['Non-Optimized predictor = [',num2str(predictor),']']);
disp(['Optimized predictor = [',num2str(opt_predictor),']']);
