Skip to content

Commit

Permalink
Merge pull request #8 from dingraha/generic_pbs
Browse files Browse the repository at this point in the history
Add proportional bands and proportional band spectra, etc
  • Loading branch information
dingraha authored Jul 1, 2024
2 parents d0242b4 + 958b40c commit 4de7152
Show file tree
Hide file tree
Showing 13 changed files with 4,476 additions and 548 deletions.
12 changes: 5 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
name = "AcousticMetrics"
uuid = "046f749b-9c1e-43ca-86bc-6902340f753e"
authors = ["Ingraham, Daniel James (GRC-LTV0) <[email protected]>"]
version = "0.6.1"
authors = ["Ingraham, Daniel James (GRC-LTV0) <[email protected]> and contributors"]
version = "0.7.0"

[deps]
ConcreteStructs = "2569d6c7-a4a2-43d3-a901-331e8e4be471"
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
FLOWMath = "6cb5d3fb-0fe8-4cc2-bd89-9fe0b19a99d3"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"

[compat]
julia = "1.8.2"
ConcreteStructs = "0.2.2"
FFTW = "1.4.3"
FLOWMath = "0.3.3"
ForwardDiff = "0.10.19"
OffsetArrays = "1.10.4"
julia = "1.8.2"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Currently implemented metrics include:

* Approximate octave and third-octave spectra
* Exact proportional spectra of any octave fraction > 0.
* Lazy representations of proportional band spectra constructed from either other narrowband or proportional band spectra

* Integrated metrics

Expand Down
5 changes: 3 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module AMDocs
using Documenter, AcousticMetrics
using AcousticMetrics: AcousticMetrics

function main()
function doit()
IN_CI = get(ENV, "CI", nothing)=="true"

makedocs(sitename="AcousticMetrics.jl", modules=[AcousticMetrics], doctest=false,
Expand All @@ -17,7 +18,7 @@ function main()
end

if !isinteractive()
main()
doit()
end

end # module
89 changes: 86 additions & 3 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,92 @@
```@meta
CurrentModule = AMDocs
```

# API Reference

```@autodocs
Modules = [AcousticMetrics]
## Fourier Transforms
```@docs
AcousticMetrics.rfft!
AcousticMetrics.irfft!
```

## Pressure Time History
```@docs
AbstractPressureTimeHistory
PressureTimeHistory
AcousticMetrics.pressure
AcousticMetrics.inputlength
AcousticMetrics.timestep(pth::AbstractPressureTimeHistory)
AcousticMetrics.starttime(pth::AbstractPressureTimeHistory)
AcousticMetrics.time
```

## Narrowband Metrics
```@docs
AbstractNarrowbandSpectrum
AcousticMetrics.halfcomplex
AcousticMetrics.timestep(sm::AbstractNarrowbandSpectrum)
AcousticMetrics.starttime(sm::AbstractNarrowbandSpectrum)
AcousticMetrics.samplerate
AcousticMetrics.frequency
AcousticMetrics.frequencystep
AcousticMetrics.istonal
PressureSpectrumAmplitude
PressureSpectrumPhase
MSPSpectrumAmplitude
MSPSpectrumPhase
PowerSpectralDensityAmplitude
PowerSpectralDensityPhase
```

### Proportional Bands and Proportional Band Spectra
```@docs
AbstractProportionalBands
AcousticMetrics.octave_fraction
AcousticMetrics.lower_center_upper
AcousticMetrics.freq_scaler
AcousticMetrics.band_start
AcousticMetrics.band_end
AcousticMetrics.lower_bands
AcousticMetrics.upper_bands
AcousticMetrics.center_bands
AcousticMetrics.cband_number
ExactProportionalBands
ExactOctaveCenterBands
ExactOctaveLowerBands
ExactOctaveUpperBands
ExactThirdOctaveCenterBands
ExactThirdOctaveLowerBands
ExactThirdOctaveUpperBands
ApproximateThirdOctaveBands
ApproximateThirdOctaveCenterBands
ApproximateThirdOctaveLowerBands
ApproximateThirdOctaveUpperBands
ApproximateOctaveBands
ApproximateOctaveCenterBands
ApproximateOctaveLowerBands
ApproximateOctaveUpperBands
AbstractProportionalBandSpectrum
AcousticMetrics.has_observer_time
AcousticMetrics.observer_time
AcousticMetrics.timestep(pbs::AbstractProportionalBandSpectrum)
AcousticMetrics.amplitude
AcousticMetrics.time_period
AcousticMetrics.time_scaler
LazyNBProportionalBandSpectrum
AcousticMetrics.frequency_nb
AcousticMetrics.lazy_pbs
ProportionalBandSpectrum
LazyPBSProportionalBandSpectrum
ProportionalBandSpectrumWithTime
AcousticMetrics.combine
```

## Weighting
```@docs
W_A
```

## Integrated Metrics
```@docs
OASPL
```
3 changes: 2 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Currently implemented metrics include:
* Proportional band spectra

* Approximate octave and third-octave spectra
* Exact proportional spectra of any octave fraction > 0.
* Exact proportional spectra of any octave fraction integer > 0.
* Lazy representations of proportional band spectra constructed from either narrowband or proportional band spectra

* Integrated metrics

Expand Down
20 changes: 18 additions & 2 deletions src/AcousticMetrics.jl
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
module AcousticMetrics

using ConcreteStructs: @concrete
using Base.Iterators: Iterators
using Base.Order: ord, Forward
using FFTW: r2r!, R2HC, HC2R, rfftfreq
using FLOWMath: abs_cs_safe
using ForwardDiff: ForwardDiff
using OffsetArrays: OffsetArray

include("constants.jl")

include("fourier_transforms.jl")

include("narrowband.jl")
export AbstractPressureTimeHistory, PressureTimeHistory
export AbstractNarrowbandSpectrum
export PressureSpectrumAmplitude, PressureSpectrumPhase, MSPSpectrumAmplitude, MSPSpectrumPhase, PowerSpectralDensityAmplitude, PowerSpectralDensityPhase

include("integrated.jl")
export OASPL

include("proportional_bands.jl")
export AbstractProportionalBands
export ExactProportionalBands
export ExactOctaveCenterBands, ExactOctaveLowerBands, ExactOctaveUpperBands
export ExactThirdOctaveCenterBands, ExactThirdOctaveLowerBands, ExactThirdOctaveUpperBands
export ApproximateOctaveBands, ApproximateOctaveCenterBands, ApproximateOctaveLowerBands, ApproximateOctaveUpperBands
export ApproximateThirdOctaveBands, ApproximateThirdOctaveCenterBands, ApproximateThirdOctaveLowerBands, ApproximateThirdOctaveUpperBands
export AbstractProportionalBandSpectrum, LazyNBProportionalBandSpectrum, ProportionalBandSpectrum, ProportionalBandSpectrumWithTime, LazyPBSProportionalBandSpectrum

include("weighting.jl")
export W_A

end # module
123 changes: 3 additions & 120 deletions src/fourier_transforms.jl
Original file line number Diff line number Diff line change
@@ -1,123 +1,6 @@
"""
dft_r2hc(x::AbstractVector)
Calculate the real-input discrete Fourier transform, returning the result in the "half-complex" format.
See
http://www.fftw.org/fftw3_doc/The-1d-Real_002ddata-DFT.html#The-1d-Real_002ddata-DFT
and http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html for
details.
Only use this for checking the derivatives of the FFT routines (should work fine, just slow).
"""
function dft_r2hc(x::AbstractVector)
# http://www.fftw.org/fftw3_doc/The-1d-Real_002ddata-DFT.html#The-1d-Real_002ddata-DFT
# http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html
# So
#
# * we don't need the imaginary part of y_0 (which will be the first element in y, say, i=1)
# * if n is even, we don't need the imaginary part of y_{n/2} (which would be i = n/2+1)
#
# Now, the order is supposed to be like this (r for real, i for imaginary):
#
# * r_0, r_1, r_2, r_{n/2}, i_{(n+1)/2-1}, ..., i_2, i_1
#
# But the docs say that they're still using the same old formula, which is:
#
# Y_k = Σ_{j=0}^{n-1} X_j exp(-2*π*i*j*k/n)
#
# (where i is sqrt(-1)).
n = length(x)
xo = OffsetArray(x, 0:n-1)

y = similar(x)
yo = OffsetArray(y, 0:n-1)

# Let's do k = 0 first.
yo[0] = sum(xo)

# Now go from k = 1 to n/2 for the real parts.
T = eltype(x)
for k in 1:n÷2
yo[k] = zero(T)
for j in 0:n-1
# yo[k] += xo[j]*exp(-2*pi*sqrt(-1)*j*k/n)
yo[k] += xo[j]*cos(-2*pi*j*k/n)
end
end

# Now go from 1 to (n+1)/2-1 for the imaginary parts.
for k in 1:(n+1)÷2-1
yo[n-k] = zero(T)
for j in 0:n-1
yo[n-k] += xo[j]*sin(-2*pi*j*k/n)
end
end

return y
end

"""
dft_hc2r(x::AbstractVector)
Calculate the inverse discrete Fourier transform of a real-input DFT.
This is the inverse of `dft_r2hc`, except for a factor of `N`, where `N` is the length of the input (and output), since FFTW computes an "unnormalized" FFT.
See
http://www.fftw.org/fftw3_doc/The-1d-Real_002ddata-DFT.html#The-1d-Real_002ddata-DFT
and http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html for
details.
Only use this for checking the derivatives of the FFT routines (should work fine, just slow).
"""
function dft_hc2r(x::AbstractVector)
n = length(x)
xo = OffsetArray(x, 0:n-1)

y = zero(x)
yo = OffsetArray(y, 0:n-1)

j = 0
for k in 0:n-1
yo[k] += xo[j]
end

# So, I need this loop to get r_1 to r_{n÷2} and i_{(n+1)÷2-1} to i_1.
# Let's say n is even.
# Maybe 8.
# So then n÷2 == 4 and (n+1)÷2-1 == 3.
# So x0 looks like this:
#
# r_0, r_1, r_2, r_3, r_4, i_3, i_2, i_1
#
# If n is odd, say, 9, then n÷2 == 4 and (n+1)÷2-1 == 4, and x0 looks like this:
#
# r_0, r_1, r_2, r_3, r_4, i_4, i_3, i_2, i_1
#
for j in 1:(n-1)÷2
rj = xo[j]
ij = xo[n-j]
for k in 0:n-1
yo[k] += 2*rj*cos(2*pi*j*k/n) - 2*ij*sin(2*pi*j*k/n)
end
end

if iseven(n)
# Handle the Nyquist frequency.
j = n÷2
rj = xo[j]
for k in 0:n-1
yo[k] += rj*cos(2*pi*j*k/n)
end
end

return y
end

@concrete struct RFFTCache
val
jac
struct RFFTCache{TVal,TJac}
val::TVal
jac::TJac
end

function RFFTCache(::Type{V}, M, N) where {V}
Expand Down
23 changes: 23 additions & 0 deletions src/integrated.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
OASPL(ap::AbstractPressureTimeHistory)
Return the overall sound pressure level of a pressure time history.
"""
function OASPL(ap::AbstractPressureTimeHistory)
p = pressure(ap)
n = inputlength(ap)
p_mean = sum(p)/n
msp = sum((p .- p_mean).^2)/n
return 10*log10(msp/p_ref^2)
end

"""
OASPL(ap::AbstractNarrowbandSpectrum)
Return the overall sound pressure level of a narrowband spectrum.
"""
function OASPL(sp::AbstractNarrowbandSpectrum)
amp = MSPSpectrumAmplitude(sp)
msp = sum(@view amp[begin+1:end])
return 10*log10(msp/p_ref^2)
end
Loading

0 comments on commit 4de7152

Please sign in to comment.