Array signal processing

SignalAnalysis.beamformMethod
beamform(s, f, n, sd; fs=framerate(s), method=Bartlett())
beamform(s, f, sd; fs=framerate(s), method=Bartlett())

Narrowband frequency-domain beamformer. Takes in passband signals s and produces beamformer output for all directions specified by the steering delays sd. The beamformer output is an energy estimate (or equivalent) for each steering direction. The beamforming only uses a narrowband signal cenetered at frequency f with a bandwidth of about fs/n.

If n is not specified, or is 1, then the input signal is assumed to be narrowband, and centered at frequency f.

The narrowband assumption requires that the bandwidth be no greater than about 5/T, where T is the maximum time taken for a signal to propagate through the array.

Several beamforming methods are available:

Custom beamformers can be implemented by creating a subtype of SignalAnalysis.Beamformer and implementing the SignalAnalysis.beamformer() method dispatched on that type.

Example:

julia> x = cw(100.0, 1.0, 44100.0);
julia> sd = steering(0.0:1.0:3.0, 1500.0, range(0.0, π; length=181));
julia> bfo = beamform([x x x x], 100.0, 4096, sd; method=Capon(0.1))
181-element Array{Float64,1}:
 0.12406290296318974
 0.1240975045516605
 ⋮
 0.12406290296318974
source
SignalAnalysis.beamformMethod
beamform(s, sd; fs=framerate(s))

Broadband time-domain delay-and-sum beamformer. Takes in passband or baseband signals s and produces beamformer output for all directions specified by the steering delays sd. The beamformer output is a timeseries signal for each steering direction.

Example:

julia> x = cw(100.0, 1.0, 44100.0);
julia> sd = steering(0.0:1.0:3.0, 1500.0, range(0.0, π; length=181));
julia> bfo = beamform([x x x x], sd)
SampledSignal @ 44100.0 Hz, 44100×181 Array{Complex{Float64},2}:
  ⋮
source
SignalAnalysis.steeringMethod
steering(rxpos, c, θ)

Computes steering delays for specified receiver positions rxpos, signal propagation speed c, and angles θ. Array θ can be a 1D array of angles or 2D array with (azimuth, elevation) pair in each row. The delays are computed with a far-field assumption, i.e., for plane incoming waves.

Examples:

julia> steering(0.0:1.0:5.0, 1500.0, range(0.0, π; length=181))
6×181 Array{Float64,2}:
  0.00166667    0.00166641   …  -0.00166641   -0.00166667
  0.001         0.000999848     -0.000999848  -0.001
  0.000333333   0.000333283     -0.000333283  -0.000333333
 -0.000333333  -0.000333283      0.000333283   0.000333333
 -0.001        -0.000999848      0.000999848   0.001
 -0.00166667   -0.00166641   …   0.00166641    0.00166667

julia> rxpos = [  # can be 2D or 3D coordinates
  0.0  1.0  2.0  3.0  4.0  5.0
  0.0  0.0  0.0  0.0  0.0  0.0
];
julia> steering(rxpos, 1500.0, range(0.0, π; length=181))
6×181 Array{Float64,2}:
  0.00166667    0.00166641   …  -0.00166641   -0.00166667
  0.001         0.000999848     -0.000999848  -0.001
  0.000333333   0.000333283     -0.000333283  -0.000333333
 -0.000333333  -0.000333283      0.000333283   0.000333333
 -0.001        -0.000999848      0.000999848   0.001
 -0.00166667   -0.00166641   …   0.00166641    0.00166667

julia> rxpos = [
  0.0  0.0  0.5  0.5
  0.0  0.5  0.0  0.5
  0.0  0.0  0.0  0.0
];
julia> θ = deg2rad.(reduce(vcat, hcat.(LinRange(-20,20,41)', LinRange(-10,10,21)))) # 2D array with (azimuth, elevation) in each row
julia> steering(rxpos, 1500.0, θ)
4×861 Array{Float64,2}:
  9.80987e-5    9.83857e-5    9.86427e-5  …   0.00021154   0.000210989   0.000210373
  0.000210373   0.000210989   0.00021154      9.86427e-5   9.83857e-5    9.80987e-5
 -0.000210373  -0.000210989  -0.00021154     -9.86427e-5  -9.83857e-5   -9.80987e-5
 -9.80987e-5   -9.83857e-5   -9.86427e-5     -0.00021154  -0.000210989  -0.000210373
source