1 stable release
Uses old Rust 2015
1.0.0 | Feb 27, 2017 |
---|
#13 in #fm
6KB
54 lines
demod_fm.rs -- FM signal demodulator
This crates provides a simple FM signal demodulator for use with software radio.
Usage
This crate can be used through cargo by adding it as
a dependency in Cargo.toml
:
[dependencies]
demod_fm = "1.0.0"
and importing it in the crate root:
extern crate demod_fm;
lib.rs
:
This crates provides a simple FM signal demodulator for use with software radio. It demodulates using phase difference approximation as described below.
Theory
Consider the classical equation [1] for an FM signal:
s(t) = a(t) cos(ωct + φ(t))
with
φ(t) = ω∆∫x(τ)dτ
where the integral is evaluated from 0 to t and x(t) is the modulating signal to be recovered.
Differentiating this gives
dφ(t) / dt = ω∆x(t)
so
x(t) = ω∆-1 dφ(t) / dt
Differentiation in continuous time is approximated by finite backward difference in discrete time, so
x(t) ≈ ω∆-1 (φ[t] - φ[t-1]) / T
Assuming a "normalized" period of T = 1, this becomes
x(t) ≈ w∆-1 (φ[t] - φ[t-1])
This requires the change in phase between the current and previous sampling instants, which can be computed from the corresponding I/Q samples. Given an FM signal s(t), the received I/Q sequence will have components
i(t) = a(t) cos φ(t)
q(t) = a(t) sin φ(t)
with each sample represented as
p(t) = i(t) + j q(t)
Evaluating the complex argument of this gives
arg(p(t)) = arctan[q(t) / i(t)] = arctan tan φ(t) = φ(t)
so
arg(p(t)) - arg(p(t-1)) = φ(t) - φ(t-1)
Applying the complex identities arg(uv) ≡ arg(u) + arg(v) (mod (-π, π]) and arg(u*) = -arg(u),
arg(p(t)p(t-1)*) = arg(p(t)) - arg(p(t-1)) = φ(t) - φ(t-1)
Combining all these results leads to the equation calculated at each sample:
x[t] = ω∆-1 arg(p[t]p[t - 1]*)
using angular frequency deviation ω∆ = 2π f∆ and the current and previous complex samples.
References
- "FM demodulation using a digital radio and digital signal processing", J.M. Shima,
Dependencies
~240KB