## Copyright (C) 2018 Jens Ahrensfeld
##
## This program is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see .
## -*- texinfo -*-
## @deftypefn {Function File} {@var{retval} =} garage (@var{input1}, @var{input2})
##
## @seealso{}
## @end deftypefn
## Author: Jens Ahrensfeld
## Created: 2018-12-06
function bits = garage (varargin)
params = struct ('numSamplesPerSym', 4, 'with_filter', 0, 'k_noise', 0.04);
units = struct ('numSamplesPerSym', 'sps', 'with_filter', '', 'k_noise', '');
% Parse parameters
names = fieldnames(params);
for k=1:nargin-1,
for n=1:length(names),
if strcmpi(varargin{k}, names{n})
params.(names{n}) = varargin{k+1};
end
end
end
print_parameters(params, units)
k_n = params.k_noise; % NOise
k_s = 1.0; % Sym
numSamplesPerSym = params.numSamplesPerSym;
baud = 9600;
fs = baud * numSamplesPerSym;
numSyms = 50;
numBursts = 3;
numSymsPauseBetweenBurst = 50;
syms = rand(numSyms, 1) > 0.5;
bit = 0;
syms_m = [];
% Line coding
for n=1:numSyms,
if syms(n) == 1
syms_m = [syms_m bit];
bit = not(bit);
syms_m = [syms_m bit];
bit = not(bit);
else
syms_m = [syms_m bit];
syms_m = [syms_m bit];
bit = not(bit);
end
end
% Upconvert
x = [];
for k=1:numBursts
for n=1:2*numSyms,
for m=1:numSamplesPerSym,
x = [x syms_m(n)];
end
end
x = [x zeros(1, numSymsPauseBetweenBurst*numSamplesPerSym)];
end
% Channel
[b,a] = butter(2, baud/fs);
if params.with_filter
x = filter(b, a, x);
end
y = k_s*x + k_n*randn(1, length(x));
y = wavread('seq.wav');
N = length(y);
n = 1:N;
bit = 0;
count = numSamplesPerSym;
smp = [];
smp_n = [];
bits = [];
% Receive
state = "Init";
peakFindCount = 10;
v_min = 0;
v_max = 0;
for n=1:N
state_next = state;
v_thr = (v_max - v_min) / 2;
if y(n) < v_min
v_min = y(n);
elseif y(n) > v_max
v_max = y(n);
end
v_min = v_min + 1e-5*(v_thr - v_min);
v_max = v_max - 1e-5*v_max;
if strcmp(state, "Init")
state_next = "Decode";
elseif strcmp(state, "Decode")
bit_curr = y(n) > v_thr;
if (bit ~= bit_curr)
count = fix(numSamplesPerSym/2);
bit = bit_curr;
end
if count > 0
count = count - 1;
else
count = numSamplesPerSym-1;
smp = [smp y(n)];
smp_n = [smp_n n];
bits = [bits bit_curr];
end;
_cnt(n) = count;
end
_v_tr(n) = v_thr;
if ~strcmp(state, state_next)
fprintf(stdout, "Change state: %s => %s\n", state, state_next);
state = state_next;
end
end
bits = bits';
n = 1:N;
% Plot
subplot(2, 1, 1)
plot(n, y, '-o', smp_n, smp, 'rx', n, _v_tr, 'y'); grid;
subplot(2, 1, 2)
plot(n, _cnt); grid;
endfunction