import torch def hilbert(h): window = 2 * torch.heaviside(torch.linspace(-1, 1, steps=h.size(-1)), values=torch.ones(1)).to(h.device) window = torch.flip(window, dims=(-1,)) windowed_fft = window * torch.fft.fft(h) return torch.fft.ifft(windowed_fft) def minimum_phase_version(h): """ h is the time-domain RIR. We ensure that the RIR has minimum-phase-lag, which helps with stability, as its inverse is then causal and stable. """ T_orig = h.size(-1) h = torch.nn.functional.pad(h, (0, T_orig)) H = torch.fft.fft(h) log_H_abs = torch.log(torch.abs(H) + 1e-8) minimum_phase = - torch.imag( hilbert(log_H_abs) ) exp_minimum_phase = torch.exp(1j*minimum_phase) minimum_phase_h = torch.real(torch.fft.ifft( torch.abs(H).type(exp_minimum_phase.dtype) * exp_minimum_phase )) # |H(w)|*e^(jPhi(w)) minimum_phase_h = minimum_phase_h[: -T_orig] return minimum_phase_h