git-svn-id: http://moon:8086/svn/matlab/trunk@100 801c6759-fa7c-4059-a304-17956f83a07c
157 lines
3.1 KiB
Matlab
Executable File
157 lines
3.1 KiB
Matlab
Executable File
## 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 <http://www.gnu.org/licenses/>.
|
|
|
|
## -*- texinfo -*-
|
|
## @deftypefn {Function File} {@var{retval} =} garage (@var{input1}, @var{input2})
|
|
##
|
|
## @seealso{}
|
|
## @end deftypefn
|
|
|
|
## Author: Jens Ahrensfeld <ahrensfeld@w2ess001vm>
|
|
## 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
|