M Project.toml => Project.toml +2 -1
@@ 1,9 1,10 @@
name = "RoomAcoustics"
uuid = "9b22aa7e-b0d0-4fe8-9c3b-2b8bf774f735"
authors = ["zymon"]
-version = "0.1.0"
+version = "0.2.0"
[deps]
+DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
M src/RoomAcoustics.jl => src/RoomAcoustics.jl +2 -0
@@ 3,6 3,7 @@ module RoomAcoustics
using LinearAlgebra
using StaticArrays
using Statistics
+using DSP
using Random
using Random: GLOBAL_RNG
@@ 10,5 11,6 @@ include("types.jl")
include("utils.jl")
include("directivity.jl")
include("ISM.jl")
+include("moving_sources.jl")
end # module
A src/moving_sources.jl => src/moving_sources.jl +48 -0
@@ 0,0 1,48 @@
+export synth_movement
+
+"""
+Experimental
+"""
+function synth_movement(
+ rx_path::AbstractVector{SVector{3, T}},
+ signal::AbstractVector{T},
+ tx::TxRx{T},
+ room::Room,
+ config::RIRConfig,
+ W_max::Integer = 2^11,
+) where {T<:Real}
+ P, N = length(rx_path), length(signal)
+
+ # Synthesise room impulse responses for given path
+ rirs = [ISM(tx, TxRx(p), room, config) for p in rx_path]
+
+ # Find synthesis parameters
+ best = typemax(Int);
+ W, L = 0, 0
+ for WW = 1:W_max, LL = 1:W_max-1
+ score = P*WW - LL*(P-1) - N;
+ if abs(score) <= best
+ best = abs(score);
+ W, L = WW, LL
+ best == 0 && break
+ end
+ end
+
+ # Compute synthesis window
+ w = sin.((1:W)*π/(W+1))
+
+ # Allocate memory for auxiliary signals
+ out = zeros(P*(W-L)+L)
+ dout = zeros(P*(W-L)+L)
+
+ # Synthesise
+ for (i, h) = enumerate(rirs)
+ sh = conv(h, signal)
+ f_s = (i-1)*(W-L) + 1
+ f_e = f_s + W - 1
+ out[f_s:f_e] += w .* sh[f_s:f_e]
+ dout[f_s:f_e] += w
+ end
+ out ./ dout
+end
+