another dev commit

This commit is contained in:
zymon 2023-05-16 11:55:55 +02:00
parent 9aad4f303b
commit 937fce822f
5 changed files with 51 additions and 47 deletions

View file

@ -1,37 +1,38 @@
export ISM export ISM
function ISM( function ISM(
tx::TxRx,
array::TxRxArray, array::TxRxArray,
tx::TxRx,
room::AbstractRoom, room::AbstractRoom,
config::ISMConfig; config::ISMConfig;
) )
Pn, o, B = array.p, array.origin, array.B rxs, origin, B = array.txrx, array.origin, array.B
[ISM(TxRx(B*p.position+o, B*p.B, p.directivity), tx, room, config) for p in Pn] l2g = rx -> TxRx(B * rx.position + origin, B * rx.B, rx.directivity)
[ISM(tx, rx |> l2g, room, config) for rx in rxs]
end end
""" """
""" """
function ISM( function ISM(
tx::TxRx,
rxs::AbstractVector{<:TxRx}, rxs::AbstractVector{<:TxRx},
tx::TxRx,
room::AbstractRoom, room::AbstractRoom,
config::ISMConfig; config::ISMConfig;
) )
[ISM(rx, tx, room, config) for rx in rxs] [ISM(rx, tx, room, config) for rx in rxs]
end end
""" """
""" """
function ISM( function ISM(
rx::TxRx,
tx::TxRx, tx::TxRx,
rx::TxRx,
room::RectangularRoom, room::RectangularRoom,
config::ISMConfig; config::ISMConfig;
) )
@ -53,9 +54,9 @@ function ISM(
if config.hp if config.hp
return AllenBerkley_highpass100(h, config.fs) return AllenBerkley_highpass100(h, config.fs)
# Zmień to na funkcie operującą na zaalokowanym już h # TODO: Zmień to na funkcie operującą na zaalokowanym już h
# AllenBerkley_highpass100!(h, config.fs) # AllenBerkley_highpass100!(h, config.fs)
#return h # return h
else else
return h return h
end end
@ -67,15 +68,15 @@ end
""" """
function ISM_RectangularRoom_core( function ISM_RectangularRoom_core(
tx::SVector{3, T}, # transmitter position tx::SVector{3,T}, # transmitter position
rx::SVector{3, T}, # reveiver position rx::SVector{3,T}, # reveiver position
B::SMatrix{3, 3, T}, # receiver orientation B::SMatrix{3,3,T}, # receiver orientation
dp::AbstractDirectivityPattern, # Receiver directivity pattern dp::AbstractDirectivityPattern, # Receiver directivity pattern
L::Tuple{T, T, T}, # room size (Lx, Ly, Lz) L::Tuple{T,T,T}, # room size (Lx, Ly, Lz)
β::Tuple{T, T, T, T, T, T}, # Reflection coefficients (βx1, βx2, βy1, βy2, βz1, βz2) β::Tuple{T,T,T,T,T,T}, # Reflection coefficients (βx1, βx2, βy1, βy2, βz1, βz2)
c::T, # velocity of the wave c::T, # velocity of the wave
fs::T, # sampling frequeyncy fs::T, # sampling frequeyncy
order::Tuple{<:Int, <:Int}, # order of reflections; min max order::Tuple{<:Int,<:Int}, # order of reflections; min max
Nh::Integer, # h lenght in samples Nh::Integer, # h lenght in samples
Wd::T, # Window width Wd::T, # Window width
ISD::T, # Random displacement of image source ISD::T, # Random displacement of image source
@ -110,15 +111,15 @@ end
""" """
function ISM_RectangularRoom_core!( function ISM_RectangularRoom_core!(
h::AbstractVector{<:T}, h::AbstractVector{<:T},
tx::SVector{3, T}, # transmitter position tx::SVector{3,T}, # transmitter position
rx::SVector{3, T}, # reveiver position rx::SVector{3,T}, # reveiver position
B::SMatrix{3, 3, T}, # receiver orientation B::SMatrix{3,3,T}, # receiver orientation
dp::AbstractDirectivityPattern, # Receiver directivity pattern dp::AbstractDirectivityPattern, # Receiver directivity pattern
L::Tuple{T, T, T}, # room size (Lx, Ly, Lz) L::Tuple{T,T,T}, # room size (Lx, Ly, Lz)
β::Tuple{T, T, T, T, T, T}, # Reflection coefficients (βx1, βx2, βy1, βy2, βz1, βz2) β::Tuple{T,T,T,T,T,T}, # Reflection coefficients (βx1, βx2, βy1, βy2, βz1, βz2)
c::T, # velocity of the wave c::T, # velocity of the wave
fs::T, # sampling frequeyncy fs::T, # sampling frequeyncy
order::Tuple{<:Int, <:Int}, # order of reflections; min max order::Tuple{<:Int,<:Int}, # order of reflections; min max
Wd::T, # Window width Wd::T, # Window width
ISD::T, # Random displacement of image source ISD::T, # Random displacement of image source
lrng::AbstractRNG # random number generator lrng::AbstractRNG # random number generator
@ -128,7 +129,7 @@ function ISM_RectangularRoom_core!(
Nh = length(h) Nh = length(h)
# Samples to distance coefficient [m] # Samples to distance coefficient [m]
Γ = c/fs Γ = c / fs
# Transform size of the room from meters to samples # Transform size of the room from meters to samples
Lₛ = L ./ Γ Lₛ = L ./ Γ
@ -158,7 +159,7 @@ function ISM_RectangularRoom_core!(
if o_min <= o && (o <= o_max || o_max == -1) if o_min <= o && (o <= o_max || o_max == -1)
# Compute Rp part # Compute Rp part
for i = 1:3 for i = 1:3
Rp[i] = (1 .- 2 * p[i]) * tx[i] - rx[i] Rp[i] = (1 .- 2 * p[i]) * tx[i] - rx[i]
end end
# Position of [randomized] image source for given permutation # Position of [randomized] image source for given permutation
@ -174,30 +175,30 @@ function ISM_RectangularRoom_core!(
dist = norm(tx_isp) dist = norm(tx_isp)
# Propagation time between receiver and image source # Propagation time between receiver and image source
τ = dist/c τ = dist / c
if τ <= Nh/fs # Check if it still in transfer function range if τ <= Nh / fs # Check if it still in transfer function range
# Compute value of reflection coefficients # Compute value of reflection coefficients
b .= β .^ abs.((n-q, n, l-j, l, m-k, m)) b .= β .^ abs.((n - q, n, l - j, l, m - k, m))
# Direction of Arrival of ray # Direction of Arrival of ray
DoA .= tx_isp./dist DoA .= tx_isp ./ dist
# Compute receiver directivity gain # Compute receiver directivity gain
DG = directivity_pattern(SVector{3}(DoA), B, dp) DG = directivity_pattern(SVector{3}(DoA), B, dp)
# Compute attenuation coefficient # Compute attenuation coefficient
A = DG * prod(b)/(4π * dist) A = DG * prod(b) / (4π * dist)
# Compute range of samples in transfer function # Compute range of samples in transfer function
i_s = max(ceil(Int, (τ-Wd/2)*fs)+1, 1) # start i_s = max(ceil(Int, (τ - Wd / 2) * fs) + 1, 1) # start
i_e = min(floor(Int, (τ+Wd/2)*fs)+1, Nh) # end i_e = min(floor(Int, (τ + Wd / 2) * fs) + 1, Nh) # end
# Insert yet another impulse into transfer function # Insert yet another impulse into transfer function
for i i_s:i_e for i i_s:i_e
t = (i-1)/fs - τ # time signature t = (i - 1) / fs - τ # time signature
w = 0.5 * (1.0 + cos(2π*t/Wd)) # Hann window w = 0.5 * (1.0 + cos(2π * t / Wd)) # Hann window
h[i] += w * A * sinc(fs * t) # sinc h[i] += w * A * sinc(fs * t) # sinc
end end
end end

View file

@ -15,6 +15,7 @@ include("utils.jl")
include("ISM.jl") include("ISM.jl")
include("moving_sources.jl") include("moving_sources.jl")
export WASN
include("WASN.jl") include("WASN.jl")
end # module end # module

View file

@ -16,11 +16,7 @@ struct Node
δ::Real δ::Real
end end
function Node(rx, δ=0.0) struct Event # NOTE: TxNode może będzie lepszą nazwa?
Node(rx, δ)
end
struct Event
tx::TxRx tx::TxRx
emission::Real emission::Real
fs::Real fs::Real
@ -33,8 +29,12 @@ function synth_events(
room::AbstractRoom, room::AbstractRoom,
rir_config::AbstractRIRConfig, rir_config::AbstractRIRConfig,
) )
hs = [ISM(nodes[i].rx, events[j].tx, room, rir_config) for i in eachindex(nodes), j in eachindex(events)] hs = Matrix{Vector{Vector{Float64}}}(undef, nodes |> length, events |> length)
s = [[conv(h, events[j].signal) for h in hs[i, j]] for i in eachindex(nodes), j in eachindex(events)] iter = Iterators.product(nodes |> eachindex, events |> eachindex) |> collect
Threads.@threads for (i,j) iter
hs[i,j] = ISM(events[j].tx, nodes[i].rx, room, rir_config)
end
s = [[conv(h, events[j].signal) for h in hs[i, j]] for i eachindex(nodes), j eachindex(events)]
(signals=s, hs=hs) (signals=s, hs=hs)
end end
@ -54,9 +54,10 @@ function synthesise(
# Find length of the output signal # Find length of the output signal
δ_max = [node.δ for node nodes] |> maximum; δ_max = [node.δ for node nodes] |> maximum;
N = [ceil(Int, (events[j].emission + δ_max)*fs) + length(e_signal[1, j][1]) for j eachindex(events)] |> maximum N = [ceil(Int, (events[j].emission + δ_max)*fs) + length(e_signal[1, j][1]) for j eachindex(events)] |> maximum
N += floor(Int, fs)
# Allocate memory for output signals # Allocate memory for output signals
output = [zeros(N, node.rx.p |> length) for node nodes] output = [zeros(N, node.rx.txrx |> length) for node nodes]
for i eachindex(nodes), j eachindex(events) for i eachindex(nodes), j eachindex(events)
shift_n = floor(Int, (events[j].emission + nodes[i].δ)*fs) shift_n = floor(Int, (events[j].emission + nodes[i].δ)*fs)

View file

@ -8,8 +8,8 @@ abstract type AbstractRoom end
struct RectangularRoom{T<:Real} <: AbstractRoom struct RectangularRoom{T<:Real} <: AbstractRoom
c::T c::T
L::Tuple{T, T, T} L::Tuple{T,T,T}
β::Tuple{T, T, T, T, T, T} β::Tuple{T,T,T,T,T,T}
end end
@ -19,8 +19,8 @@ abstract type AbstractRIRConfig end
""" """
""" """
struct ISMConfig{T<:Real, I<:Integer, R<:AbstractRNG} <: AbstractRIRConfig struct ISMConfig{T<:Real,I<:Integer,R<:AbstractRNG} <: AbstractRIRConfig
order::Tuple{I, I} # Order of reflection [low, high] order::Tuple{I,I} # Order of reflection [low, high]
fs::T # Sampling frequency fs::T # Sampling frequency
N::I # Number of samples in impulse response N::I # Number of samples in impulse response
Wd::T # Single impulse width Wd::T # Single impulse width

View file

@ -5,11 +5,12 @@ export h2RT60, Sabine_RT60
""" """
function h2RT60(h::AbstractVector{<:Number}, Fs::Real) function h2RT60(h::AbstractVector{<:Number}, Fs::Real)
cs = cumsum(reverse(h.^2)) dB(x) = 10log10(x)
edc = 10*log10.(reverse(cs./cs[end])) # energy decay curve normalize(x) = x ./ x[begin]
edc = h .|> abs2 |> reverse |> cumsum |> reverse |> normalize .|> dB
ind = findfirst(edc .<= -60. ) ind = findfirst(edc .<= -60. )
if ind == nothing if ind === nothing
rt = length(h)/Fs rt = length(h)/Fs
else else
rt = ind/Fs rt = ind/Fs