## Copyright (C) 2020 Jens
##
## 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 {} {@var{retval} =} mc_pd_eval (@var{input1}, @var{input2})
##
## @seealso{}
## @end deftypefn
## Author: Jens
## Created: 2020-08-07
#
# pll_burst_eval(0.5, 0.0, 10, 0)
#
# Usage:
# x = siggen(2000, 48000, 8, 0.1);
# pll_burst_eval(48000,0, x)
#
function retval = pll_burst_eval(varargin)
params_default = struct("fs", 48000, "f", 0, "ref", [], "klead", 0.004, "klag", 0.00002, 'domega_max', 2000);
params = parse_myparams(params_default, varargin);
# Create variable from params
fs = params.fs;
f = params.f;
ref = params.ref;
klead = params.klead;
klag = params.klag;
domega_max = params.domega_max;
domega_lo_max = +domega_max/fs;
domega_lo_min = -domega_max/fs;
N = length(ref);
omega = f/fs;
# Start processing
lag = 0;
phi_lo = 0;
omega_err = 0;
agc_state = 0;
for n=1:N,
# Derotator LO
lo = exp(j*2*pi*phi_lo);
# AGC
[y, agc_state] = agc(agc_state, ref(n));
# Pahse detector
[perr, pd] = phase_det(lo, y);
# Process loop filter output kv
lag = lag + klag*perr;
kv = (lag + klead*perr);
# Calculate delta omega for LO
domega_lo = min(domega_lo_max, max(domega_lo_min, kv));
omega_lo = omega + domega_lo;
omega_err = omega_lo - omega;
# advance phase accumulator for LO
phi_lo = phi_lo + omega_lo;
_perr(n) = perr;
_omega_err(n) = omega_err;
_lo(n) = lo;
_ref_derote(n) = pd;
_agc_state(n) = agc_state;
end
f_err = fs*omega_err
function [perr, pd] = phase_det(lo, ref)
pd = ref*conj(lo);
perr = imag(pd);
endfunction
function [y, state_out] = agc(state_in, x)
alpha = 0.1;
refi = 1.0;
eps = 1e-3;
state_out = (1-alpha)*state_in + alpha*abs(x);
c = refi/(eps + state_out);
y = x*c;
endfunction
close all;
subplot(3, 1, 1)
plot(1:N, imag(_lo), 1:N, imag(ref), 1:N, _agc_state); legend('Lo', 'ref', 'agc'); grid
subplot(3, 1, 2)
plot(1:N, real(_ref_derote), 1:N, imag(_ref_derote)); legend('Re_{Derot}', 'Im_{Derot}'); grid
subplot(3, 1, 3)
plot(1:N, _perr, 1:N, _omega_err); legend('p_{err}', 'f_{err}'); grid
endfunction