///|
pub fn moving_average(
signal : ArrayView[Double],
width : Int,
) -> Array[Double] raise SpectrumError {
if signal.length() == 0 {
raise EmptySignal
}
if width <= 0 {
raise InvalidArgument(message="width must be positive")
}
let out : Array[Double] = []
for i in 0.. Array[Double] raise SpectrumError {
convolve(signal, taps)
}
///|
pub fn lowpass_taps(
length~ : Int,
cutoff_hz~ : Double,
sample_rate~ : Double,
) -> Array[Double] raise SpectrumError {
validate_filter_args(length, cutoff_hz, sample_rate)
let fc = cutoff_hz / sample_rate
let mid = (length - 1) / 2
let win = window(Hamming, length)
let taps : Array[Double] = []
for n in 0.. Array[Double] raise SpectrumError {
let low = lowpass_taps(length~, cutoff_hz~, sample_rate~)
let mid = (length - 1) / 2
let out : Array[Double] = []
for i in 0.. Unit raise SpectrumError {
if length <= 0 {
raise EmptySignal
}
if length % 2 == 0 {
raise InvalidArgument(message="tap length must be odd")
}
if cutoff_hz <= 0.0 || sample_rate <= 0.0 || cutoff_hz >= sample_rate / 2.0 {
raise InvalidArgument(message="cutoff must be between 0 and Nyquist")
}
}
///|
fn normalize_taps(taps : Array[Double]) -> Array[Double] raise SpectrumError {
let sum = taps.fold(init=0.0, (acc, item) => acc + item)
if sum == 0.0 {
raise InvalidArgument(message="tap sum is zero")
}
taps.map(item => item / sum)
}
///|
pub fn bandpass_fir_taps(
length~ : Int,
low_cutoff_hz~ : Double,
high_cutoff_hz~ : Double,
sample_rate~ : Double,
) -> Array[Double] raise SpectrumError {
if low_cutoff_hz >= high_cutoff_hz {
raise InvalidArgument(message="low_cutoff must be less than high_cutoff")
}
let low1 = lowpass_taps(length~, cutoff_hz=low_cutoff_hz, sample_rate~)
let low2 = lowpass_taps(length~, cutoff_hz=high_cutoff_hz, sample_rate~)
let out : Array[Double] = []
for i in 0.. Array[Double] raise SpectrumError {
if low_cutoff_hz >= high_cutoff_hz {
raise InvalidArgument(message="low_cutoff must be less than high_cutoff")
}
let low1 = lowpass_taps(length~, cutoff_hz=low_cutoff_hz, sample_rate~)
let low2 = lowpass_taps(length~, cutoff_hz=high_cutoff_hz, sample_rate~)
let mid = (length - 1) / 2
let out : Array[Double] = []
for i in 0..