-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtestEMagLsFromAtfs.m
85 lines (69 loc) · 2.93 KB
/
testEMagLsFromAtfs.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
% This script demonstrates how eMagLS can be used with arbitrary arrays
% based on measured array transfer functions (ATFs).
% This example renders signals from a pair of smartglasses.
%
% For more information, please refer to
% Thomas Deppisch, Nils Meyer-Kahlen, Sebastia Amengual Gari,
% "Blind Identification of Binaural Room Impulse Responses from Smart Glasses",
% IEEE/ACM Transactions on Audio, Speech, and Language Processing, vol. 32, pp. 4052-4065, 2024,
% doi: 10.1109/TASLP.2024.3454964.
%
% This software is licensed under a Non-Commercial Software License
% (see https://github.com/thomasdeppisch/eMagLS/blob/main/LICENSE for full details).
%
% Thomas Deppisch, 2025
clear; clc; close all;
addpath(genpath('dependencies/'));
addpath(genpath('lib/'));
%% load
% load HRIRs
[hrirFile, hrirUrl] = deal('./resources/HRIR_L2702.mat', ...
'https://zenodo.org/record/3928297/files/HRIR_L2702.mat');
% load a speech signal
[sig,sigFs] = audioread('./resources/decemberTour.wav');
% load a RIR
rirStruct = load('./resources/meetingRoom_leftLsp.mat');
rirFs = rirStruct.fs;
% load ATFs
atfStructFullSphere = load('./resources/glasses_on_HATS_ATFs_sphere.mat');
atfIrGridFullSphere = atfStructFullSphere.atfIrs;
atfAziGridRadFS = atfStructFullSphere.atfGridAziEleDeg(:,1) * pi/180;
atfZenGridRadFS = (90-atfStructFullSphere.atfGridAziEleDeg(:,2)) * pi/180;
atfFs = atfStructFullSphere.fs;
fprintf('Downloading HRIR dataset ... \n');
if isfile(hrirFile)
fprintf('already exists ... skipped.\n');
else
downloadAndExtractFile(hrirFile, hrirUrl);
end
% load HRIR
load(hrirFile);
if isa(HRIR_L2702, 'uint32') || isempty(HRIR_L2702)
% MIRO class does not exist on the system and will be downloaded
fprintf('Downloading MIRO class ... \n');
downloadAndExtractFile('dependencies/miro.m', 'https://zenodo.org/record/3928297/files/miro.m');
% Retry loading file
fprintf('Loading file "%s" ... \n', hrirFile);
load(hrirFile);
end
hL = double(HRIR_L2702.irChOne);
hR = double(HRIR_L2702.irChTwo);
hrirGridAziRad = double(HRIR_L2702.azimuth.');
hrirGridZenRad = double(HRIR_L2702.elevation.'); % the elevation angles actually contain zenith data between 0..pi
hrirFs = double(HRIR_L2702.fs);
clear HRIR_L2702;
assert(hrirFs == sigFs && hrirFs == atfFs && hrirFs == rirFs, 'Sample Rate Mismatch!')
%% create array signal
arraySig = fftfilt(rirStruct.roomIRs, sig);
%% calculate eMagLS rendering filters
eMagLsFilterLen = 256;
eMagLsCutOnFreq = 2000;
[wMlsL, wMlsR] = getEMagLsFiltersFromAtf(hL, hR, [hrirGridAziRad, hrirGridZenRad], atfIrGridFullSphere, ...
[atfAziGridRadFS atfZenGridRadFS], sigFs, eMagLsFilterLen, eMagLsCutOnFreq);
%% render to binaural
fprintf('Rendering \n');
binEMls = binauralDecode(arraySig, hrirFs, wMlsL, wMlsR, sigFs);
% normalize
binEMls = binEMls ./ max(abs(binEMls(:))) * 0.5;
fprintf('Playing back eMagLS binaural rendering ... \n');
playblocking(audioplayer(binEMls, sigFs));