Files
imdd_silas/Classes/04_DSP/Coding/Duobinary.m
Silas Labor Zizou cf4e0f2b12 measurement state
2024-10-29 14:38:22 +01:00

264 lines
7.0 KiB
Matlab

classdef Duobinary
%Duobinary Coding
% should work
properties(Access=public)
end
methods (Access=public)
function obj = Duobinary()
%NAME Construct an instance of this class
end
function signal = precode(~,signal)
if isa(signal,'Signal')
data = signal.signal;
else
data = signal;
end
u = unique(data);
M = numel(u);
%make unipolar
if M == 4
data = data .* sqrt(5);
elseif M == 6
data = data .* sqrt(10);
elseif M == 8
data = data .* sqrt(21);
elseif M == 16
data = data .* sqrt(85);
warning('Check if PAM16 implementation, mapping and scaling is correct!')
end
data = round(data);
b = min(data);
data = data - b;
data = data ./ 2;
assert(isequal((0:M-1)',unique(data)),'Check Duobinary Precoding'); %seems the signal is not unipolar
% Pre coding
bk = zeros(numel(data),1);
% for k = 1:numel(data)-1
% bk(k+1) =mod(data(k)-bk(k),M);
% end
for k = 2:numel(data)
bk(k) =mod(data(k)-bk(k-1),M);
end
%make bipolar
bk = bk .* 2;
bk = bk + b;
if M == 4
bk = bk ./ sqrt(5);
elseif M == 6
bk = bk ./ sqrt(10);
elseif M == 8
bk = bk ./ sqrt(21);
end
assert(isequal(unique(bk),u),'Check Duobinary Precoding'); %seems the signal is not the same as before
if isa(signal,'Signal')
signal.signal = bk;
else
signal = bk;
end
end
function signal = encode(~,signal)
if isa(signal,'Signal')
data = signal.signal;
else
data = signal;
end
data = data./rms(data);
u = unique(data);
M = numel(u);
%make unipolar
if M == 4
data = data .* sqrt(5);
elseif M == 6
data = data .* sqrt(10);
elseif M == 8
data = data .* sqrt(21);
elseif M == 16
data = data .* sqrt(85);
warning('Check if PAM16 implementation, mapping and scaling is correct!')
end
data = round(data);
b = min(data);
data = data - b;
data = data ./ 2;
% assert(isequal((0:M-1)',unique(data)),'Check Duobinary Precoding'); %seems the signal is not unipolar
% duobinary coding (1+D)
% coeff = [1,1];
%
% data = conv(data,coeff,"same");
coeff = [1,1];
data = filter(coeff, 1, data);
%data = data ./ rms(data);
% data = ifft(fft(real(data)).*fft(fliplr(coeff'),length(data))) + 1i*ifft(fft(imag(data)).*fft(fliplr(coeff'),length(data)));
%make bipolar
data = (data-round(mean(data),1));
if M == 4
data = data ./ sqrt(2.5); % 7-level constellation weighted with probability after DB code i.e. mean([-3 3 -2 -2 2 2 -1 -1 -1 1 1 1 0 0 0 0].^2) = 2.5 --> sqrt(2.5) == rms(constellation)
elseif M == 6
data = data ./ sqrt(5.8);
elseif M == 8
data = data ./ sqrt(10.5); % 15-level constellation weighted with probability after DB code i.e.
end
if isa(signal,'Signal')
signal.signal = data;
else
signal = data;
end
% Code to evaluate the s in sqrt(s):
% M=6;
% c = (0:(2*M)-2) - ((2*M)-2)/2;
% s = 0;
% for i = 0:(2*M)-2
% p(i+1) = M-abs(i-(M-1));
% s = s+p(i+1)*c(i+1).^2;
% end
% s = s/M^2;
end
function signalclass = decode(~,signalclass)
data = signalclass.signal;
u = unique(data);
I = numel(u); %number of duobinary coded const. points
M = (I+1)/2; %PAM-M order
%make unipolar
if I == 7
data = data .* sqrt(2.5);
elseif I == 11
%todo
data = data .* sqrt(5.8);
warning('Check db decode implementation, mapping and scaling is correct!')
elseif I == 15
data = data .* sqrt(10.5);
elseif I == 16
warning('Check db decode implementation, mapping and scaling is correct!')
end
data = round(data);
b = min(data);
data = data - b;
data = round(data);
data = mod(data,M);
%make bipolar
data = data .* 2;
data = data - round(mean(data));
if M == 4
data = data ./ sqrt(5);
elseif M == 6
data = data ./ sqrt(10);
elseif M == 8
data = data ./ sqrt(21);
end
signalclass.signal = data;
end
function signalclass = feedbackdetector(~,signalclass)
data = signalclass.signal;
u = unique(data);
I = numel(u); %number of duobinary coded const. points
M = (I+1)/2; %PAM-M order
%make unipolar
if I == 7
data = data .* sqrt(2.5);
elseif I == 11
%todo
data = data .* sqrt(5.8);
warning('Check if PAM16 implementation, mapping and scaling is correct!')
elseif I == 15
data = data .* sqrt(10.5);
elseif I == 16
warning('Check if PAM16 implementation, mapping and scaling is correct!')
end
data = round(data);
b = min(data);
data = data - b;
data = round(data);
data_out = zeros(length(data),1);
const = 0:M-1;
%%FALSCH!
for k = 1:length(data)-1
d_ = data(k+1) - data_out(k);
[~,b] = min(abs(d_-[0:M-1]));
data_out(k+1) = const(b);
end
%make bipolar
data_out = data_out .* 2;
data_out = data_out - round(mean(data_out));
if M == 4
data_out = data_out ./ sqrt(5);
elseif M == 6
data_out = data_out ./ sqrt(10);
elseif M == 8
data_out = data_out ./ sqrt(21);
end
signalclass.signal = data_out;
end
end
methods (Access=private)
% Cant be seen from outside! So put all your functions here that can/
% shall not be called from outside
end
end