├── .gitattributes
├── .gitignore
├── ADMA
├── ADMA.m
└── apply_ADMA.m
├── COLA_check.m
├── DMA
├── DMA.m
└── apply_DMA.m
├── DMA2
├── DMA2.m
└── apply_DMA2.m
├── DMA_SS
├── DMA1_SS.m
└── apply_DMA_SS.m
├── GUI
├── DMA1_b2b.m
├── DispAngle.fig
└── DispAngle.m
├── KaiserBesselDerived.m
├── README.md
├── WPE
├── config.m
├── fdndlp.m
├── stftanalysis.m
└── stftsynthesis.m
├── applyProcess_real.m
├── applyProcess_sim.m
├── beam
├── DMA2_beam.m
├── DMA_beam.m
├── beam.m
├── beam.mlx
├── beampolar.m
├── beampolar_M12.m
└── beampolar_SS.m
├── doc
├── DMA_SS.md
└── pic
│ ├── 57563270-4C95-4f4e-A43E-A811F6E1ECE2.png
│ ├── {194544CE-17C5-45DC-B044-270623C30619}_20191021152956.jpg
│ ├── {1D9ED7CA-80A0-42BE-A554-B9F6A638282F}_20191023164007.jpg
│ ├── {5FF73B88-7BB7-4AE4-9EC0-37BBDD2499F8}_20191023145635.jpg
│ ├── {73B28CF7-E00C-46C0-8393-FFED146AAD1D}_20191021203234.jpg
│ ├── {8CEB0A6C-7635-45BE-9668-B327E884334C}_20191023141623.jpg
│ ├── {97F38125-6E72-4774-B031-BF57999C8F17}_20191021153136.jpg
│ ├── {E5D9A13E-3F78-42D2-B864-DF4168E58AC6}_20191023164103.jpg
│ └── {EC4ED9E9-1EC2-4136-BB57-76AF5EE9E4F3}_20191023141233.jpg
├── lib
├── +file
│ └── find_pcm.m
├── +sim
│ ├── RIR_generator_URA.m
│ ├── generate_signal.m
│ ├── noise_gen_URA.m
│ └── signal_simulation.m
├── +util
│ ├── fig.m
│ ├── play.m
│ ├── plot.m
│ └── visual.m
├── GenNoiseMSC.m
├── GenNoiseMSC_shift.m
├── mycohere.m
├── patternURA.m
├── spectral_subtraction.m
├── stft_test.m
├── update_CSD.m
├── update_MSC.m
└── update_PSD.m
└── wav
├── 4mic_r0.005
├── target_2mic_ganrao_180
│ ├── 1.wav
│ ├── 2.wav
│ ├── 3.wav
│ └── 4.wav
└── target_2mic_ganrao_90
│ ├── 1.wav
│ ├── 2.wav
│ ├── 3.wav
│ └── 4.wav
├── STEREO_0024.pcm
├── STEREO_0111.pcm
└── xmos
├── rec
├── readme.txt
├── 音轨-2.wav
├── 音轨-3.wav
├── 音轨-4.wav
└── 音轨-5.wav
└── rec96
├── readme.txt
├── 音轨-2.wav
├── 音轨-3.wav
├── 音轨-4.wav
└── 音轨-5.wav
/.gitattributes:
--------------------------------------------------------------------------------
1 | # These files are text and should be normalized (convert between crlf and lf)
2 | *.txt text
3 | *.md text
4 | *.m text
5 | *.wrd text
6 | *.c text
7 | *.h text
8 | *.sh text
9 | *.tex text
10 |
11 | # These files should be treated as binary
12 | *.png binary
13 | *.jpg binary
14 | *.wav binary
15 | *.egg binary
16 | *.ttf binary
17 | *.pdf binary
18 | *.dot binary
19 | *.doc binary
20 | *.zip binary
21 | *.docx binary
22 | *.kmx binary
23 | *.exe binary
24 | *.aiff binary
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ##ignore this file##
2 |
3 | EventDetector/bin/EventDetector
4 |
5 | EventDetector/Makefile
6 |
7 | EventDetector/CMakeFiles/
8 |
9 | cmake_install.cmake
10 |
11 | CMakeCache.txt
12 |
13 | *.asv
14 |
15 | *.pk
16 |
17 | *.d
18 |
19 | # Object files
20 | *.o
21 | *.ko
22 | *.obj
23 | *.elf
24 |
25 | # Linker output
26 | *.ilk
27 | *.map
28 | *.exp
29 |
30 | # Precompiled Headers
31 | *.gch
32 | *.pch
33 |
34 | # Libraries
35 | *.lib
36 | *.a
37 | *.la
38 | *.lo
39 |
40 | # Shared objects (inc. Windows DLLs)
41 | *.dll
42 | *.so
43 | *.so.*
44 | *.dylib
45 |
46 | # Executables
47 | *.exe
48 | *.out
49 | *.app
50 | *.i*86
51 | *.x86_64
52 | *.hex
53 |
54 | # Debug files
55 | *.dSYM/
56 | *.su
57 | *.idb
58 | *.pdb
59 |
60 | # Kernel Module Compile Results
61 | *.mod*
62 | *.cmd
63 | .tmp_versions/
64 | modules.order
65 | Module.symvers
66 | Mkfile.old
67 | dkms.conf
68 |
69 | output/
70 | #*real*
71 | batchtest/
--------------------------------------------------------------------------------
/ADMA/ADMA.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/ADMA/ADMA.m
--------------------------------------------------------------------------------
/ADMA/apply_ADMA.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | %
3 | % endfire
4 | % refer to "A Dual-Microphone Speech Enhancement Algorithm
5 | % Based on the Coherence Function"
6 | %
7 | % broadside
8 | % refer to "A coherence-based noise reduction algorithm for binaural
9 | % hearing aids"
10 | %
11 | %
12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 | % close all
14 | % clear all;
15 | %addpath(genpath('lib'));
16 | c = 340; % speed of sound
17 |
18 | %%
19 | %% load recorded office noise audio
20 |
21 | fs = 16000;
22 |
23 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24 |
25 | %%
26 | frameLength = 256;
27 | overlap = 128;
28 | inc = frameLength - overlap;
29 | N_FFT = 256;
30 | % test xmos 4-mic circular array recordings
31 | x = loadwav('../wav/4mic_r0.005/target_2mic_ganrao_90/');
32 | d = 0.005*2;
33 |
34 | switch 2
35 | case 1
36 | x = x(:,[2,4]); % extract speaker-1
37 | disp('speaker-1 is in front of mic1')
38 | case 2
39 | x = x(:,[3,1]); % extract speaker-2
40 | disp('speaker-2 is in front of mic4')
41 | otherwise
42 | disp('other value')
43 | end
44 |
45 | %% process
46 | % x = pcmread('wav/STEREO_0024.pcm',2)';
47 | y = zeros(size(x,1),1);
48 | % WPE_out_2ch = fdndlp(x, cfgs);
49 | [ y] = ADMA( x,d);
50 |
51 | %% evaluate
52 | %speech = sig.speech;
53 | % [pesq_mos]= pesq_vec(speech, out,fs)
54 | %rmpath(genpath('lib'));
55 | visual( x(:,1),y*2 );
56 | % util.fig(out, fs);
57 |
58 |
59 |
--------------------------------------------------------------------------------
/COLA_check.m:
--------------------------------------------------------------------------------
1 | % # COLA check:
2 | % # from scipy import signal
3 | % # print(signal.check_COLA(signal.windows.hamming(400,sym=False),400,300))
4 | % #
5 | frameLength = 256;
6 | overlap = 128;
7 | inc = frameLength - overlap;
8 | N_FFT = 512;
9 |
10 | window = sqrt(hamming(frameLength+1));
11 | window = window(1:frameLength);
12 | % window = KaiserBesselDerived(1.5,256);
13 |
14 | win = zeros(1,inc*9+overlap)';
15 | frameNum = fix((length(win)-overlap)/inc);
16 | win_ind = zeros(frameNum,length(win));
17 | figure,
18 | for n = 1:frameNum
19 | win_ind(n,(n-1)*inc+1:(n-1)*inc+frameLength) = window.^2;
20 | hold on,plot(win_ind(n,:))
21 | end
22 | win_sum = sum(win_ind); % overlap-add window
23 | hold on,plot(win_sum);
24 |
--------------------------------------------------------------------------------
/DMA/DMA.m:
--------------------------------------------------------------------------------
1 | function [ y ] = DMA( x,spacing)
2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 | % first-order DMAs
4 | % refer to
5 | % [1]."differential microphone arrays"
6 | %
7 | % example Usage:
8 | % y = DMA( x,0.02)
9 | %
10 | % Inputs:
11 | % x dual-mic input data,[samples,channel]
12 | % spacing mic spacing
13 | %
14 | % Outputs:
15 | % y processed data
16 | %
17 | % Created by Wang wei
18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19 | X = stft(x);
20 | % output spectral
21 | Y = squeeze(X(:,1,:));
22 | fs = 16000;
23 |
24 | alpha_1_1 = cos(180*pi/180);
25 | theta_target = 0*pi/180;
26 | d = spacing;
27 | frameLength = 256;
28 | inc = frameLength/2;
29 |
30 | t = 27;
31 | c = (331.3+0.606*t);
32 | tao0 = d/c;
33 |
34 | N = frameLength;
35 | omega = zeros(N/2+1,1);
36 | HL = zeros(1,N/2+1);
37 | H = zeros(2,N/2+1);
38 |
39 | frameNum = size(X,1);
40 | half_bin = size(X,3);
41 |
42 | for k = 2:N/2+1
43 | omega(k) = 2*pi*(k-1)*fs/N;
44 | % HL(k) = 1/(1-exp(1j*omega(k)*tao0*(alpha_1_1-cos(theta_target))));
45 | HL(k) = 1j/(omega(k)*tao0*(alpha_1_1-cos(theta_target))); % approximating e^x with 1+x
46 | H(:,k) = HL(k)*[1;
47 | -exp(1j*omega(k)*tao0*alpha_1_1)];
48 | end
49 |
50 | for frameIndex = 1:frameNum
51 |
52 | d = squeeze(X(frameIndex,:,1:half_bin));
53 |
54 | Yout = sum(d.*(H));
55 | Y(frameIndex,:) = Yout;
56 | end
57 | y = istft(Y);
58 | y = real(y);
59 | end
60 |
61 |
62 |
--------------------------------------------------------------------------------
/DMA/apply_DMA.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | %
3 | % test first-order DMA
4 | %
5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 | % close all
7 | % clear all;
8 | %addpath(genpath('lib'));
9 | c = 340; % speed of sound
10 |
11 | %%
12 | %% load recorded office noise audio
13 |
14 | fs = 16000;
15 |
16 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17 |
18 | %%
19 | x = loadwav('../wav/4mic_r0.005/target_2mic_ganrao_90/');
20 | d = 0.005*2;
21 | % x = loadwav('wav/xmos/meetingroom_2/');
22 | % d = 0.064;
23 |
24 | cfgs = 'config.m';
25 | switch 1
26 | case 1
27 | x = x(:,[3,1]); % extract speaker-1
28 | disp('speaker-1 is in front of mic1')
29 | case 2
30 | x = x(:,[2,4]); % extract speaker-2
31 | disp('speaker-2 is in front of mic4')
32 | otherwise
33 | disp('other value')
34 | end
35 | %% process
36 | % x = pcmread('../wav/STEREO_0024.pcm',2)';
37 | % d = 0.025;
38 | y = DMA( x,d);
39 |
40 | %% evaluate
41 | %speech = sig.speech;
42 | % [pesq_mos]= pesq_vec(speech, out,fs)
43 | %rmpath(genpath('lib'));
44 | visual( x(:,1),y);
45 | % util.fig(out, fs);
46 |
47 |
48 |
--------------------------------------------------------------------------------
/DMA2/DMA2.m:
--------------------------------------------------------------------------------
1 | function [ y ] = DMA2( x,spacing)
2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 | % first-order DMAs
4 | % refer to
5 | % [1]."differential microphone arrays"
6 | %
7 | % example Usage:
8 | % y = DMA( x,0.02)
9 | %
10 | % Inputs:
11 | % x dual-mic input data,[samples,channel]
12 | % spacing mic spacing
13 | %
14 | % Outputs:
15 | % y processed data
16 | %
17 | % Created by Wang wei
18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19 | X = stft(x);
20 | % output spectral
21 | Y = squeeze(X(:,1,:));
22 | fs = 16000;
23 |
24 | alpha_1_1 = cos(180*pi/180);
25 | theta_target = 0*pi/180;
26 | d = spacing;
27 | frameLength = 256;
28 | inc = frameLength/2;
29 |
30 | % Cardioid
31 | alpha_21 = -1;
32 | alpha_22 = 0;
33 |
34 | % Hypercardioid
35 | alpha_21 = -0.89;
36 | alpha_22 = -0.28;
37 |
38 | % % Supercardioid
39 | % alpha_21 = -0.81;
40 | % alpha_22 = 0.31;
41 |
42 | % % Quadrupole
43 | % alpha_21 = -1/sqrt(2);
44 | % alpha_22 = 1/sqrt(2);
45 |
46 |
47 |
48 | t = 27;
49 | c = (331.3+0.606*t);
50 | tao0 = d/c;
51 |
52 | N = frameLength;
53 | omega = zeros(N/2+1,1);
54 | HL = zeros(1,N/2+1);
55 | H = zeros(3,N/2+1);
56 |
57 | frameNum = size(X,1);
58 | half_bin = size(X,3);
59 |
60 | for k = 2:N/2+1
61 | omega(k) = 2*pi*(k-1)*fs/N;
62 |
63 | H(:,k) = 1/(-1*tao0^2*omega(k)^2*(alpha_21-1)*(alpha_22-1))*[1;
64 | -exp(1j*omega(k)*tao0*alpha_21)-exp(1j*omega(k)*tao0*alpha_22);
65 | exp(1j*omega(k)*tao0*(alpha_21+alpha_22))];
66 | if(sqrt(H(:,k)'*H(:,k))>1)
67 | H(:,k) = H(:,k)/sqrt(H(:,k)'*H(:,k));
68 | end
69 | end
70 |
71 | for frameIndex = 1:frameNum
72 |
73 | d = squeeze(X(frameIndex,:,1:half_bin));
74 |
75 | Yout = sum(d.*(H));
76 | Y(frameIndex,:) = Yout;
77 | end
78 | y = istft(Y);
79 | y = real(y);
80 | end
81 |
82 |
83 |
--------------------------------------------------------------------------------
/DMA2/apply_DMA2.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | %
3 | % test first-order DMA
4 | %
5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 | % close all
7 | % clear all;
8 | %addpath(genpath('lib'));
9 | c = 340; % speed of sound
10 |
11 | %%
12 | %% load recorded office noise audio
13 |
14 | fs = 16000;
15 |
16 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17 |
18 | %%
19 | x = loadwav('../wav/4mic_r0.005/target_2mic_ganrao_90/');
20 | d = 0.005*2;
21 | % x = loadwav('wav/xmos/meetingroom_2/');
22 | % d = 0.064;
23 |
24 | x = loadpcm('E:\\work\\kws\\lanso\\录音\\录音1\\');
25 | x = x(:,[1,2,3]);
26 | d = 0.05;
27 |
28 | %% process
29 | % x = pcmread('../wav/STEREO_0024.pcm',2)';
30 | % d = 0.025;
31 | y = DMA2( x,d);
32 |
33 | %% evaluate
34 | %speech = sig.speech;
35 | % [pesq_mos]= pesq_vec(speech, out,fs)
36 | %rmpath(genpath('lib'));
37 | visual( x(:,1),y);
38 | % util.fig(out, fs);
39 |
40 |
41 |
--------------------------------------------------------------------------------
/DMA_SS/DMA1_SS.m:
--------------------------------------------------------------------------------
1 | function [ y,Y12] = DMA1_SS( x,spacing)
2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 | % DMAs for Sepctral-Subtraction
4 | % refer to
5 | % [1]."Sound Source Separation Using Null-Beamforming and Spectral Subtraction
6 | % for mobileDevice"
7 | % [2]."differential microphone arrays"
8 | %
9 | % example Usage:
10 | % y = DMA1_SS( x,0.02)
11 | %
12 | % Inputs:
13 | % x dual-mic input data,[samples,channel]
14 | % spacing mic spacing
15 | %
16 | % Outputs:
17 | % y processed data
18 | %
19 | % Created by Wang wei
20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21 | fs = 16000;
22 | N_FFT = 1024;
23 | frameLength = 512;
24 | inc = 256;
25 | c = 340;
26 | tao0 = spacing/c;
27 | win = sqrt(hann(frameLength+1));
28 | win = win(1:end-1);
29 | X = stft(x,N_FFT,frameLength,inc,win);
30 | % output spectral
31 | Y = squeeze(X(:,1,:));
32 | y = zeros(size(x,1),1);
33 | L = size(x,1);
34 | frameNum = fix((L - (frameLength-inc))/inc);
35 |
36 | half_bin = N_FFT/2+1;
37 |
38 |
39 | theta = linspace(0,2*pi,360); % scaning angle
40 |
41 | HL = zeros(1,half_bin);
42 |
43 | H_1st_f = zeros(2,half_bin);
44 | H_1st_b = zeros(2,half_bin);
45 | H_1st_n = zeros(2,half_bin);
46 | HL_f = zeros(1,half_bin);
47 | HL_b = zeros(1,half_bin);
48 | HL_n = zeros(1,half_bin);
49 |
50 | Cf = zeros(2,half_bin);
51 | Cb = zeros(2,half_bin);
52 | Cn = zeros(2,half_bin);
53 |
54 | B12 = zeros(length(theta),half_bin); % beamformer output
55 | B21 = zeros(length(theta),half_bin); % beamformer output
56 | N12 = zeros(length(theta),half_bin); % beamformer output
57 | M12 = zeros(length(theta),half_bin); % beamformer output
58 | Y12_2 = zeros(length(theta),half_bin); % beamformer output
59 | Y12 = zeros(length(theta),half_bin); % beamformer output
60 |
61 | eps = 1e-8;
62 | % calculate fixed beamformer weights
63 | for k = 2:half_bin
64 | omega_k = 2*pi*(k-1)*fs/N_FFT; % normalized digital angular frequency
65 |
66 | % forward
67 | theta_target = 0*pi/180;
68 | theta_null = 180*pi/180;
69 | HL_f(k) = 1/(1-exp(1j*omega_k*tao0*(cos(theta_null)-cos(theta_target))));
70 | % HL_f(k) = 1j/(omega_k*tao0*(cos(theta_null)-cos(theta_target))); % approximating e^x with 1+x
71 | H_1st_f(:,k) = [1;
72 | -exp(1j*omega_k*tao0*cos(theta_null))];
73 | Cf(:,k) = H_1st_f(:,k);%.*HL_f(k);
74 |
75 | % backward
76 | theta_target = 180*pi/180;
77 | theta_null = 0*pi/180;
78 | HL_b(k) = 1/(1-exp(1j*omega_k*tao0*(cos(theta_null)-cos(theta_target))));
79 | % HL_b(k) = 1j/(omega_k*tao0*(cos(theta_null)-cos(theta_target))); % approximating e^x with 1+x
80 | H_1st_b(:,k) = [1;
81 | -exp(1j*omega_k*tao0*cos(theta_null))];
82 | Cb(:,k) = H_1st_b(:,k);%.*HL_b(k);
83 |
84 | % reference noise
85 | theta_target = 0*pi/180;
86 | theta_null = 90*pi/180;
87 | HL_n(k) = 1/(1-exp(1j*omega_k*tao0*(cos(theta_null)-cos(theta_target))));
88 | % HL_n(k) = 1j/(omega_k*tao0*(cos(theta_null)-cos(theta_target))); % approximating e^x with 1+x
89 | H_1st_n(:,k) = [1;
90 | -exp(1j*omega_k*tao0*cos(theta_null))];
91 | Cn(:,k) = H_1st_n(:,k);%.*HL_n(k);
92 |
93 | % compensation filter for spectral-subtrctive output
94 | HL(k) = 1/(sqrt(2*(1-cos(omega_k*tao0)))+eps);
95 | end
96 |
97 | % calculate beampattern
98 | for ang = 1:length(theta)
99 | for k = 2:half_bin
100 | omega_k = 2*pi*(k-1)*fs/N_FFT; % normalized digital angular frequency
101 | a = [1,exp(-1j*omega_k*tao0*cos(theta(ang)))]; % signal model,steering vector
102 | B12(ang,k) = a*Cf(:,k);
103 | B21(ang,k) = a*Cb(:,k);
104 | N12(ang,k) = a*Cn(:,k);
105 | M12(ang,k) = min(abs(B12(ang,k)),abs(B21(ang,k)));
106 | Y12_2(ang,k) = max(abs(M12(ang,k))^2-abs(N12(ang,k))^2,0);
107 | Y12(ang,k) = sqrt(Y12_2(ang,k))*HL(k);
108 | end
109 |
110 | end
111 | % draw beampattern
112 | if(nargout==2)
113 | k = 96;
114 | figure,polarplot(linspace(0,2*pi,360),abs(B12(:,k)));%rlim([-1 1])
115 | hold on,polarplot(linspace(0,2*pi,360),abs(B21(:,k)));
116 | hold on,polarplot(linspace(0,2*pi,360),abs(N12(:,k)));
117 | hold on,polarplot(linspace(0,2*pi,360),abs(M12(:,k)));
118 | hold on,polarplot(linspace(0,2*pi,360),abs(Y12(:,k)));
119 | legend('B12','B21','N12','M12','Y12');
120 | end
121 |
122 | B12 = zeros(frameNum,half_bin); % beamformer output
123 | B21 = zeros(frameNum,half_bin); % beamformer output
124 | N12 = zeros(frameNum,half_bin); % beamformer output
125 | M12 = zeros(frameNum,half_bin); % beamformer output
126 | Y12_2 = zeros(frameNum,half_bin); % beamformer output
127 | Y12 = zeros(frameNum,half_bin); % beamformer output
128 |
129 | for frameIndex = 1:frameNum
130 | d = squeeze(X(frameIndex,:,1:half_bin));
131 |
132 | for k = 2:half_bin
133 | a = d(:,k); % [1,exp(-1j*omega(k)*sin0)],input signal broadside
134 |
135 | % fixed beamformer
136 | B12(frameIndex,k) = a.'*Cf(:,k);
137 | B21(frameIndex,k) = a.'*Cb(:,k);
138 | N12(frameIndex,k) = a.'*Cn(:,k);
139 | % spectral-subtraction
140 | M12(frameIndex,k) = min(abs(B12(frameIndex,k)),abs(B21(frameIndex,k)));
141 | alpha_ss = 1.5;
142 | beta_ss = 0.001;
143 | if(abs(M12(frameIndex,k))^2>(alpha_ss+beta_ss)*abs(N12(frameIndex,k))^2)
144 | Y12_2(frameIndex,k) = abs(M12(frameIndex,k))^2 - alpha_ss*abs(N12(frameIndex,k))^2;
145 | else
146 | Y12_2(frameIndex,k) = beta_ss*abs(N12(frameIndex,k))^2;
147 | end
148 | phase = angle(B12(frameIndex,k));
149 | Y(frameIndex,k) = sqrt(Y12_2(frameIndex,k))*HL(k)*(cos(phase)+1j*(sin(phase)));
150 | % Y(frameIndex,k) = abs(N12(frameIndex,k));
151 | % Y(frameIndex,k) = M12(frameIndex,k);
152 | % Y(frameIndex,k) = Y(frameIndex,k)*(cos(phase)+1j*(sin(phase)));
153 | end
154 | end
155 | y = istft(Y,N_FFT,frameLength,inc);
156 | y = real(y);
157 | end
158 |
159 |
160 |
--------------------------------------------------------------------------------
/DMA_SS/apply_DMA_SS.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | %
3 | % test DMA_SS
4 | %
5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 | % close all
7 | % clear all;
8 |
9 | c = 340; % speed of sound
10 |
11 | %%
12 | %% load recorded office noise audio
13 |
14 | fs = 16000;
15 |
16 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17 |
18 | %%
19 | frameLength = 256;
20 | overlap = 128;
21 | inc = frameLength - overlap;
22 | N_FFT = 256;
23 | % test xmos 4-mic circular array recordings
24 | x = loadwav('../wav/4mic_r0.005/target_2mic_ganrao_90/');
25 | d = 0.005*2;
26 | % x = loadwav('wav/xmos/meetingroom_2/');
27 | % d = 0.064;
28 |
29 | cfgs = 'config.m';
30 | switch 2
31 | case 1
32 | x = x(:,[1,3]); % extract speaker-1
33 | disp('speaker-1 is in front of mic1')
34 | case 2
35 | x = x(:,[2,4]); % extract speaker-2
36 | disp('speaker-2 is in front of mic4')
37 | otherwise
38 | disp('other value')
39 | end
40 | % x = pcmread('wav/631/32dB/STEREO_0107.pcm',2)'*10;
41 | % d = 0.025;
42 | % M = size(x,2);
43 | % x1 = x;
44 |
45 | % x = loadwav('wav/cmu/');
46 | % d = 0.03;
47 |
48 | frameLength = 256;
49 | overlap = frameLength - inc;
50 | t = 27;
51 | c = 340;%(331.3+0.606*t);
52 | null = 90*pi/180;
53 | tao0 = sin(null)*d/c;
54 | theta0 = 180;
55 | alpha = cos(theta0/180*pi);
56 | beta = 1;
57 | N_FFT = frameLength;
58 | omega = zeros(N_FFT/2+1,1);
59 | omega_c = pi/(2*tao0);
60 | Hf = zeros(2,N_FFT/2+1);
61 | Hb = zeros(2,N_FFT/2+1);
62 | HL = zeros(1,N_FFT/2+1);
63 |
64 | %% process
65 | % x = pcmread('wav/STEREO_0024.pcm',2)';
66 | y = zeros(size(x,1),1);
67 | % WPE_out_2ch = fdndlp(x, cfgs);
68 | [ y] = DMA1_SS( x,d);
69 |
70 | %% evaluate
71 | %speech = sig.speech;
72 | % [pesq_mos]= pesq_vec(speech, out,fs)
73 |
74 | visual( x(:,1),y*2 );
75 | % util.fig(out, fs);
76 |
77 |
78 |
--------------------------------------------------------------------------------
/GUI/DMA1_b2b.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/GUI/DMA1_b2b.m
--------------------------------------------------------------------------------
/GUI/DispAngle.fig:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/GUI/DispAngle.fig
--------------------------------------------------------------------------------
/GUI/DispAngle.m:
--------------------------------------------------------------------------------
1 | function varargout = DispAngle(varargin)
2 | % DISPANGLE MATLAB code for DispAngle.fig
3 | % DISPANGLE, by itself, creates a new DISPANGLE or raises the existing
4 | % singleton*.
5 | %
6 | % H = DISPANGLE returns the handle to a new DISPANGLE or the handle to
7 | % the existing singleton*.
8 | %
9 | % DISPANGLE('CALLBACK',hObject,eventData,handles,...) calls the local
10 | % function named CALLBACK in DISPANGLE.M with the given input arguments.
11 | %
12 | % DISPANGLE('Property','Value',...) creates a new DISPANGLE or raises the
13 | % existing singleton*. Starting from the left, property value pairs are
14 | % applied to the GUI before DispAngle_OpeningFcn gets called. An
15 | % unrecognized property name or invalid value makes property application
16 | % stop. All inputs are passed to DispAngle_OpeningFcn via varargin.
17 | %
18 | % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
19 | % instance to run (singleton)".
20 | %
21 | % See also: GUIDE, GUIDATA, GUIHANDLES
22 |
23 | % Edit the above text to modify the response to help DispAngle
24 |
25 | % Last Modified by GUIDE v2.5 21-Nov-2017 17:18:33
26 |
27 | % Begin initialization code - DO NOT EDIT
28 | gui_Singleton = 1;
29 | gui_State = struct('gui_Name', mfilename, ...
30 | 'gui_Singleton', gui_Singleton, ...
31 | 'gui_OpeningFcn', @DispAngle_OpeningFcn, ...
32 | 'gui_OutputFcn', @DispAngle_OutputFcn, ...
33 | 'gui_LayoutFcn', [] , ...
34 | 'gui_Callback', []);
35 | if nargin && ischar(varargin{1})
36 | gui_State.gui_Callback = str2func(varargin{1});
37 | end
38 |
39 | if nargout
40 | [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
41 | else
42 | gui_mainfcn(gui_State, varargin{:});
43 | end
44 | % End initialization code - DO NOT EDIT
45 |
46 | % --- Executes just before DispAngle is made visible.
47 | function DispAngle_OpeningFcn(hObject, eventdata, handles, varargin)
48 | % This function has no output args, see OutputFcn.
49 | % hObject handle to figure
50 | % eventdata reserved - to be defined in a future version of MATLAB
51 | % handles structure with handles and user data (see GUIDATA)
52 | % varargin command line arguments to DispAngle (see VARARGIN)
53 |
54 | % Choose default command line output for DispAngle
55 | handles.output = hObject;
56 |
57 | % Update handles structure
58 | guidata(hObject, handles);
59 |
60 | % This sets up the initial plot - only do when we are invisible
61 | % so window can get raised using DispAngle.
62 | if strcmp(get(hObject,'Visible'),'off')
63 | plot(rand(5));
64 | end
65 |
66 |
67 | global start;
68 | start = 0;
69 | global recObj;
70 | global dir;
71 | dir = 1;
72 | global fs;
73 | buffer_size = 1024;
74 | fs = 8000;
75 | global deviceReader;
76 | global channel;
77 | channel = 6;
78 | deviceReader = audioDeviceReader('NumChannels',channel,'SampleRate',fs,'SamplesPerFrame',buffer_size);
79 | devices = getAudioDevices(deviceReader)
80 | % SoundCardNum = input('please select XMOS sound card number:');
81 | SoundCardNum = 3;
82 | deviceReader = audioDeviceReader('NumChannels',channel,'SampleRate',fs,'SamplesPerFrame',buffer_size,'Device',devices{SoundCardNum});
83 |
84 | setup(deviceReader);
85 | global deviceWriter;
86 | deviceWriter = audioDeviceWriter('SampleRate',fs);
87 | setup(deviceWriter,zeros(buffer_size,1));
88 |
89 | % UIWAIT makes DispAngle wait for user response (see UIRESUME)
90 | % uiwait(handles.figure1);
91 |
92 |
93 | % --- Outputs from this function are returned to the command line.
94 | function varargout = DispAngle_OutputFcn(hObject, eventdata, handles)
95 | % varargout cell array for returning output args (see VARARGOUT);
96 | % hObject handle to figure
97 | % eventdata reserved - to be defined in a future version of MATLAB
98 | % handles structure with handles and user data (see GUIDATA)
99 |
100 | % Get default command line output from handles structure
101 | varargout{1} = handles.output;
102 |
103 | % --- Executes on button press in pushbutton1.
104 | function pushbutton1_Callback(hObject, eventdata, handles)
105 | % hObject handle to pushbutton1 (see GCBO)
106 | % eventdata reserved - to be defined in a future version of MATLAB
107 | % handles structure with handles and user data (see GUIDATA)
108 | % axes(handles.axes1);
109 | % cla;
110 |
111 | global deviceReader;
112 | global deviceWriter;
113 | global fs;
114 | global channel;
115 |
116 | global dir;
117 | global start;
118 |
119 | if start == 0
120 | start = 1;
121 | set(handles.pushbutton1,'string','recording....');
122 | set(handles.pushbutton1, 'BackgroundColor',[0 1 0]);
123 | else
124 | start = 0;
125 |
126 | set(handles.pushbutton1,'string','stop');
127 | set(handles.pushbutton1, 'BackgroundColor',[1 0 0]);
128 | end
129 |
130 | d = 0.045;
131 | inc = 128;
132 | chunk_size = 1024;
133 | frameLength = 256;
134 | overlap = frameLength - inc;
135 | t = 27;
136 | c = (331.3+0.606*t);
137 | tao0 = d/c;
138 | theta0 = 180;
139 | alpha = cos(theta0/180*pi);
140 | beta = 1;
141 | N = frameLength;
142 | omega = zeros(N/2+1,1);
143 | omega_c = pi/(2*tao0);
144 | Hf = zeros(2,N/2+1);
145 | Hb = zeros(2,N/2+1);
146 | HL = zeros(1,N/2+1);
147 | % H(:,1) = 1;
148 | last_acquiredAudio = zeros(overlap,channel);
149 | last_output = zeros(overlap,1);
150 | % playData = zeros(chunk_size,1);
151 |
152 | while start
153 |
154 | acquiredAudio = deviceReader();
155 | x = [last_acquiredAudio(:,[2,dir+2]);acquiredAudio(:,[2,dir+2])];
156 | % size(acquiredAudio)
157 | % y = DMA(x);
158 | % playData = [last_output;y(1:end-overlap)];
159 | % deviceWriter(real(playData));
160 |
161 | y = zeros(chunk_size+overlap,1);
162 | y(1:overlap) = last_output;
163 | y = DMA1_b2b( x,y,frameLength,inc,omega,Hb,Hf,HL,fs,N,tao0,alpha,beta);
164 |
165 |
166 | playData = [y(1:end-overlap)];
167 | deviceWriter(real(playData));
168 |
169 |
170 | last_output = y(end-overlap+1:end);
171 | last_acquiredAudio = acquiredAudio(end-overlap+1:end,:);
172 |
173 |
174 | theta = 0:0.01:pi/4;
175 | rho = sin(2*theta).*cos(2*theta);
176 | % polarplot(theta-22.5/180*pi+ang(1)/180*pi,rho)
177 | polarplot(theta-22.5/180*pi+(dir-1)*60/180*pi,rho)
178 | drawnow
179 |
180 |
181 | end
182 |
183 |
184 |
185 | % --------------------------------------------------------------------
186 | function FileMenu_Callback(hObject, eventdata, handles)
187 | % hObject handle to FileMenu (see GCBO)
188 | % eventdata reserved - to be defined in a future version of MATLAB
189 | % handles structure with handles and user data (see GUIDATA)
190 |
191 |
192 | % --------------------------------------------------------------------
193 | function OpenMenuItem_Callback(hObject, eventdata, handles)
194 | % hObject handle to OpenMenuItem (see GCBO)
195 | % eventdata reserved - to be defined in a future version of MATLAB
196 | % handles structure with handles and user data (see GUIDATA)
197 | file = uigetfile('*.fig');
198 | if ~isequal(file, 0)
199 | open(file);
200 | end
201 |
202 | % --------------------------------------------------------------------
203 | function PrintMenuItem_Callback(hObject, eventdata, handles)
204 | % hObject handle to PrintMenuItem (see GCBO)
205 | % eventdata reserved - to be defined in a future version of MATLAB
206 | % handles structure with handles and user data (see GUIDATA)
207 | printdlg(handles.figure1)
208 |
209 | % --------------------------------------------------------------------
210 | function CloseMenuItem_Callback(hObject, eventdata, handles)
211 | % hObject handle to CloseMenuItem (see GCBO)
212 | % eventdata reserved - to be defined in a future version of MATLAB
213 | % handles structure with handles and user data (see GUIDATA)
214 | selection = questdlg(['Close ' get(handles.figure1,'Name') '?'],...
215 | ['Close ' get(handles.figure1,'Name') '...'],...
216 | 'Yes','No','Yes');
217 | if strcmp(selection,'No')
218 | return;
219 | end
220 |
221 | delete(handles.figure1)
222 |
223 |
224 | % --- Executes on selection change in popupmenu1.
225 | function popupmenu1_Callback(hObject, eventdata, handles)
226 | % hObject handle to popupmenu1 (see GCBO)
227 | % eventdata reserved - to be defined in a future version of MATLAB
228 | % handles structure with handles and user data (see GUIDATA)
229 |
230 | % Hints: contents = get(hObject,'String') returns popupmenu1 contents as cell array
231 | % contents{get(hObject,'Value')} returns selected item from popupmenu1
232 |
233 |
234 | % --- Executes during object creation, after setting all properties.
235 | function popupmenu1_CreateFcn(hObject, eventdata, handles)
236 | % hObject handle to popupmenu1 (see GCBO)
237 | % eventdata reserved - to be defined in a future version of MATLAB
238 | % handles empty - handles not created until after all CreateFcns called
239 |
240 | % Hint: popupmenu controls usually have a white background on Windows.
241 | % See ISPC and COMPUTER.
242 | if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
243 | set(hObject,'BackgroundColor','white');
244 | end
245 |
246 | set(hObject, 'String', {'plot(rand(5))', 'plot(sin(1:0.01:25))', 'bar(1:.5:10)', 'plot(membrane)', 'surf(peaks)'});
247 |
248 |
249 | % --- If Enable == 'on', executes on mouse press in 5 pixel border.
250 | % --- Otherwise, executes on mouse press in 5 pixel border or over pushbutton1.
251 | function pushbutton1_ButtonDownFcn(hObject, eventdata, handles)
252 | % hObject handle to pushbutton1 (see GCBO)
253 |
254 | % eventdata reserved - to be defined in a future version of MATLAB
255 | % handles structure with handles and user data (see GUIDATA)
256 |
257 |
258 | % --- Executes on button press in pushbutton2.
259 | function pushbutton2_Callback(hObject, eventdata, handles)
260 | % hObject handle to pushbutton2 (see GCBO)
261 | % eventdata reserved - to be defined in a future version of MATLAB
262 | % handles structure with handles and user data (see GUIDATA)
263 | global dir;
264 | if(dir == 6)
265 | dir = 1;
266 | else
267 | dir = dir + 1;
268 | end
269 | set(handles.pushbutton2,'string',dir);
270 |
--------------------------------------------------------------------------------
/KaiserBesselDerived.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | % webrtc window
3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 | function window = KaiserBesselDerived(alpha,length)
5 |
6 | half = fix((length + 1) / 2);
7 | sum = 0.0;
8 | window = zeros(1,length);
9 |
10 | for i = 0: half
11 |
12 | r = (4.0 * i) / length - 1.0;
13 | sum = sum + I0(pi * alpha * sqrt(1.0 - r * r));
14 | window(i+1) = sum;
15 | end
16 | i = length - 1:-1:half;
17 | % for i = length - 1; i >= half; --i)
18 |
19 | window(length - i) = sqrt(window(length - i) / sum);
20 | window(i+1) = window(length - i);
21 | % end
22 | if (mod(length,2) == 1)
23 |
24 | window(half - 1) = sqrt(window(half - 1) / sum);
25 | end
26 |
27 | end
28 | function i0 = I0(x)
29 |
30 | y = x / 3.75;
31 |
32 | y = y*y;
33 | i0 = 1.0 + y * (3.5156229 + y * (3.0899424 + y * (1.2067492 + y * (0.2659732 + y * (0.360768e-1 + y * 0.45813e-2)))));
34 | end
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # differential-array
2 | a simple first order differential array using XMOS 6+1 board,use mic0 and one of mic 1~6,
3 |
4 | Test in matlab 2016b
5 |
6 | ## usage
7 | 1. run DispAngle.m
8 | 2. select your multi-channel soundcard number in command window
9 | 3. click Update button to start and click Direction button to change mic1~6,then you can listen output sound in your headphone
10 |
--------------------------------------------------------------------------------
/WPE/config.m:
--------------------------------------------------------------------------------
1 |
2 | num_mic = 2;
3 | num_out = 2;
4 | K = 512; % the number of subbands
5 | F = 2; % over-sampling rate
6 | N = K / F; % decimation factor
7 | D1 = 2; % subband preditction delay
8 | Lc1 = 30; % subband prediction order
9 | eps = 1e-4; % lower bound of rho(Normalizaton factor)
10 | max_iterations = 2;
--------------------------------------------------------------------------------
/WPE/fdndlp.m:
--------------------------------------------------------------------------------
1 | function y = fdndlp(x, cfgs, varargin)
2 | %
3 | % =============================================================================
4 | %
5 | % This program is an implementation of Variance-Normalizied Delayed Linear
6 | % Prediction in time-frequency domain, which is aimed at speech
7 | % dereverberation, known as weighted prediction error (WPE) method.
8 | %
9 | % Main parameters:
10 | % mic_num the number of channels
11 | % K the number of subbands
12 | % F over-sampling rate
13 | % N decimation factor
14 | % D1 subband preditction delay
15 | % Lc1 subband prediction order
16 | % eps lower bound of normalizaton factor
17 | %
18 | % Reference:
19 | % [1] Nakatani T, Yoshioka T, Kinoshita K, et al. Speech Dereverberation
20 | % Based on Variance-Normalized Delayed Linear Prediction[J]. IEEE
21 | % Transactions on Audio Speech & Language Processing, 2010, 18(7):1717-1731.
22 | %
23 | % =============================================================================
24 | % Created by Teng Xiang at 2017-10-14
25 | % Current version: 2018-08-10
26 | % =============================================================================
27 |
28 |
29 | % =============================================================================
30 | % Load Parameters
31 | % =============================================================================
32 | if ischar(cfgs)
33 | run(cfgs);
34 | else
35 | varnames = fieldnames(cfgs);
36 | for ii = 1 : length(varnames)
37 | eval([varnames{ii}, '= getfield(cfgs, varnames{ii});']);
38 | end
39 | end
40 |
41 | if exist('varargin', 'var')
42 | for ii = 1 : 2 : length(varargin)
43 | eval([varargin{ii}, '= varargin{ii+1};'])
44 | end
45 | end
46 |
47 | len = length(x);
48 |
49 | % =============================================================================
50 | % Frequency-domain variance-normalized delayed linear prediction
51 | % =============================================================================
52 | sig_channels = size(x, 2);
53 | if sig_channels > num_mic
54 | x = x(:,1:num_mic);
55 | fprintf('Only the first %d channels of input data are used\n\n', num_mic)
56 | elseif sig_channels < num_mic
57 | error('The channels of input does not match the channel setting');
58 | end
59 |
60 | tic
61 | fprintf('Procssing...')
62 |
63 | xk = stftanalysis(x, K, N);
64 | % xk = stftanalysis(x / max(max(abs(x))), K, N);
65 | LEN = size(xk, 1);
66 | dk = zeros(LEN, K, num_out);
67 |
68 | for k = 1 : K/2 + 1
69 | xk_tmp = zeros(LEN+Lc1, num_mic);
70 | xk_tmp(Lc1+1:end,:) = squeeze(xk(:,k,:));
71 | xk_tmp = xk_tmp.';
72 | x_buf = xk_tmp(1:num_out,Lc1+1:end).';
73 | X_BUF = zeros(num_mic * Lc1, LEN);
74 | for ii = 1 : LEN-D1
75 | xn_D = xk_tmp(:,ii+Lc1:-1:ii+1);
76 | X_BUF(:,ii+D1) = xn_D(:);
77 | end
78 | rho2 = max(mean(abs(x_buf(:,1:num_out)).^2, 2), eps);
79 | c_Err = max_iterations;
80 |
81 | while (c_Err > 1e-2)
82 | Lambda = diag(1 ./ rho2);
83 | Phi = X_BUF*Lambda*X_BUF';
84 | p = X_BUF*conj(x_buf./rho2(:,ones(1,num_out)));
85 | c = pinv(Phi)*p;
86 | dk(:,k,:) = (x_buf.' - c'*X_BUF).';
87 | rho2 = max(mean(squeeze(abs(dk(:,k,:)).^2),2), eps);
88 | c_Err = c_Err - 1;
89 | end
90 | end
91 | dk(:,K/2+2:end,:) = conj(dk(:,K/2:-1:2,:));
92 | y = stftsynthesis(dk, K, N);
93 | % y = y(1 : len, :) / max(max(abs(y)));
94 | y = y(1 : len, :);
95 | disp('Done!')
96 | toc
97 |
--------------------------------------------------------------------------------
/WPE/stftanalysis.m:
--------------------------------------------------------------------------------
1 |
2 | function y = stftanalysis(s, winsize, winshift)
3 | %
4 | %STFTANALYSIS short time Fourier transform analysis
5 | % Decompose the time domain signal into the time-frequency domain signal
6 | %
7 | % y = STFTANALYSIS(s, winsize, winshift)
8 | %
9 | % s is the time domain signal. If s is a matrix, the column of the matrix
10 | % will be treated a vector and the analysis will be performed on the vectors
11 | % separately.
12 | % y is the time-frequency signal. If number of channels equals to 1, the
13 | % the return value y will be a 2-D matrix (frame_number x window_size).
14 | % If the number of channels is more than 1, y will be a 3-D matrix
15 | % (frame_number x window_size x channel_number)
16 |
17 | % =============================================================================
18 | % Created by Teng Xiang at 2018-01-12
19 | % =============================================================================
20 |
21 | win = sqrt(hann(winsize+1));
22 | win = win(1:end-1);
23 | channel_num = size(s, 2);
24 | frame_num = ceil((size(s, 1) - winsize)/ winshift) + 1;
25 | s = [s; zeros(winshift - mod(length(s) - winsize, winshift), channel_num)];
26 | y = zeros(frame_num, winsize, channel_num);
27 |
28 | for l = 1 : frame_num
29 | index = (l-1) * winshift;
30 | y(l,:,:) = reshape(...
31 | fft(bsxfun(@times, s(index + 1:index+winsize, :), win)),...
32 | 1, winsize, channel_num);
33 | end
34 |
--------------------------------------------------------------------------------
/WPE/stftsynthesis.m:
--------------------------------------------------------------------------------
1 |
2 | function y = stftsynthesis(s, winsize, winshift)
3 | %
4 | %STFTSYNTHESIS short time Fourier transform synthesis
5 | % Sythesize the time domain signal from the time-frequency domain signal
6 | %
7 | % y1 = STFTSYNTHESIS(s, winsize, winshift)
8 | %
9 | % s is the T-F domain signal which should be arranged in a 3-D matrix,
10 | % whose size is frame_number x subband_number x channel_number. If s
11 | % is a 2-D matrix, it will be treated as an frame_number x subband_bumber x 1
12 | % 3-D matrix.
13 |
14 | % =============================================================================
15 | % Created by Teng Xiang at 2018-01-12
16 | % =============================================================================
17 |
18 | win = sqrt(hann(winsize+1));
19 | win = win(1:end-1);
20 |
21 | [frame_num, subband_number, channel_number] = size(s);
22 | if subband_number ~= winsize
23 | error('The 2rd dimension of input s must agree with the winsize');
24 | end
25 | y = zeros((frame_num - 1) * winshift + winsize, channel_number);
26 |
27 | for l = 1 : frame_num
28 | if(channel_number>1)
29 | sl = squeeze(s(l,:,:));
30 | else
31 | sl = squeeze(s(l,:,:))';
32 | end
33 | tmp = reshape(ifft(sl).*win, winsize, channel_number);
34 | index = (l-1) * winshift;
35 | y(index+1 : index + winsize, :) = y(index+1 : index + winsize, :) + tmp;
36 | end
--------------------------------------------------------------------------------
/applyProcess_real.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | %
3 | % endfire
4 | % refer to "A Dual-Microphone Speech Enhancement Algorithm
5 | % Based on the Coherence Function"
6 | %
7 | % broadside
8 | % refer to "A coherence-based noise reduction algorithm for binaural
9 | % hearing aids"
10 | %
11 | %
12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 | % close all
14 | % clear all;
15 | %addpath(genpath('lib'));
16 | addpath(genpath('DMA_SS'));
17 | c = 340; % speed of sound
18 |
19 | %%
20 | %% load recorded office noise audio
21 |
22 | fs = 16000;
23 |
24 | % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25 | M = size(x,2);
26 | %%
27 | frameLength = 256;
28 | overlap = 128;
29 | inc = frameLength - overlap;
30 | N_FFT = 256;
31 | % test xmos 4-mic circular array recordings
32 | x = loadwav('wav/xmos/rec/');
33 | d = 0.064;
34 | % x = loadwav('wav/4mic_r0.005/target_2mic_ganrao_180/');
35 | % d = 0.005;
36 | switch 2
37 | case 1
38 | x = x(:,[1,3]); % extract speaker-1
39 | disp('speaker-1 is in front of mic1')
40 | case 2
41 | x = x(:,[4,2]); % extract speaker-2
42 | disp('speaker-2 is in front of mic4')
43 | otherwise
44 | disp('other value')
45 | end
46 |
47 | x1 = x;
48 |
49 | frameLength = 256;
50 | overlap = frameLength - inc;
51 | t = 27;
52 | c = (331.3+0.606*t);
53 | tao0 = d/c;
54 | theta0 = 180;
55 | alpha = cos(theta0/180*pi);
56 | beta = 1;
57 | N_FFT = frameLength;
58 | omega = zeros(N_FFT/2+1,1);
59 | omega_c = pi/(2*tao0);
60 | Hf = zeros(2,N_FFT/2+1);
61 | Hb = zeros(2,N_FFT/2+1);
62 | HL = zeros(1,N_FFT/2+1);
63 |
64 | %% process
65 | y = zeros(size(x,1),1);
66 | [ y] = DMA1_SS( x,d);
67 |
68 | %% evaluate
69 | speech = sig.speech;
70 | % [pesq_mos]= pesq_vec(speech, out,fs)
71 | %rmpath(genpath('lib'));
72 | rmpath(genpath('DMA_SS'));
73 | visual( x(:,1),y );
74 | % util.fig(out, fs);
75 |
76 |
77 |
--------------------------------------------------------------------------------
/applyProcess_sim.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | %
3 | % endfire
4 | % refer to "A Dual-Microphone Speech Enhancement Algorithm
5 | % Based on the Coherence Function"
6 | %
7 | % broadside
8 | % refer to "A coherence-based noise reduction algorithm for binaural
9 | % hearing aids"
10 | %
11 | %
12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 | close all
14 | % clear all;
15 | addpath(genpath('lib'));
16 | addpath(genpath('DMA_SS'));
17 | c = 340; % speed of sound
18 |
19 | %%
20 | %% load recorded office noise audio
21 |
22 | fs = 16000;
23 |
24 | angle = [0,0]/180*pi;
25 | % array spacing
26 | d = 0.025;
27 | r = d/2;
28 |
29 | switch 1
30 | case 1
31 | slice = [1,3]; % extract speaker-1
32 | disp('speaker-1 is in front of mic1')
33 | case 2
34 | slice = [2,4]; % extract speaker-2
35 | disp('speaker-2 is in front of mic2')
36 | otherwise
37 | disp('other value')
38 | end
39 |
40 | [ sig ] = sim.signal_simulation( r,slice );
41 | x = sig.x;
42 |
43 | x1 = x;
44 |
45 | frameLength = 256;
46 | inc = frameLength/2;
47 | overlap = frameLength - inc;
48 | t = 27;
49 | c = (331.3+0.606*t);
50 | tao0 = d/c;
51 | theta0 = 180;
52 | alpha = cos(theta0/180*pi);
53 | beta = 1;
54 | N_FFT = frameLength;
55 | omega = zeros(N_FFT/2+1,1);
56 | omega_c = pi/(2*tao0);
57 | Hf = zeros(2,N_FFT/2+1);
58 | Hb = zeros(2,N_FFT/2+1);
59 | HL = zeros(1,N_FFT/2+1);
60 |
61 | %% process
62 | y = zeros(size(x,1),1);
63 | % [ out ] = DMA1( x,omega,Hb,Hf,HL,fs,N_FFT,tao0,alpha,beta);
64 | x = [x(:,1),x(:,2)];
65 | [ y] = DMA1_SS( x,d);
66 |
67 | %% evaluate
68 | speech = sig.speech;
69 | % [pesq_mos]= pesq_vec(speech, out,fs)
70 | rmpath(genpath('lib'));
71 | rmpath(genpath('DMA_SS'));
72 | visual( x(:,1),y );
73 | % util.fig(out, fs);
74 |
75 |
76 |
--------------------------------------------------------------------------------
/beam/DMA2_beam.m:
--------------------------------------------------------------------------------
1 | close all;
2 | theta = [0,90,135]'*pi/180;%0:2*pi/360:2*pi; %注视方向
3 | theta = linspace(0,2*pi,360);
4 |
5 | f = 1:1:8000;
6 |
7 | d = 0.010;
8 | c = 340;
9 | tao0 = d/c;
10 | omega = 2*pi*f;
11 |
12 | % Cardioid
13 | alpha_21 = -1;
14 | alpha_22 = 0;
15 |
16 | % Hypercardioid
17 | alpha_21 = -0.89;
18 | alpha_22 = -0.28;
19 |
20 | % % Supercardioid
21 | % alpha_21 = -0.81;
22 | % alpha_22 = 0.31;
23 |
24 | % Quadrupole
25 | alpha_21 = -1/sqrt(2);
26 | alpha_22 = 1/sqrt(2);
27 |
28 |
29 | N_FFT = 256;
30 | fs = 16000;
31 | half_bin = N_FFT/2+1;
32 | omega = [1:half_bin]*fs/N_FFT;
33 |
34 | H = zeros(3,length(omega));
35 | theta_target = 0*pi/180; % target
36 | alpha_1_1 = cos(180*pi/180); % 零点方向
37 | B = zeros(length(theta),length(omega));
38 | for i = 1:length(omega)
39 | omega_k = 2*pi*omega(i);
40 | B(:,i) = 1j/(omega_k*tao0*(alpha_1_1-1))*(1-exp(-1*1j*omega_k*tao0*(cos(theta)-alpha_1_1)));
41 | % B(:,i) = (1-exp(-1*1j*omega_k*tao0*(cos(theta)-cos(alpha))));
42 | % H(:,i) = 1j/(omega_k*tao0*(alpha_1_1-cos(theta_target)))*[1;
43 | % -exp(1j*omega_k*tao0*alpha_1_1)]; % eq.(3.7), approximation
44 | H(:,i) = 1/(-1*tao0^2*omega_k^2*(alpha_21-1)*(alpha_22-1))*[1;
45 | -exp(1j*omega_k*tao0*alpha_21)-exp(1j*omega_k*tao0*alpha_22);
46 | exp(1j*omega_k*tao0*(alpha_21+alpha_22))]; % eq. (3.16)
47 |
48 | H(:,i) = 1/(-1*tao0^2*omega_k^2*(alpha_21-1))*[-exp(-1j*omega_k*tao0);
49 | 1+exp(-1j*omega_k*2*tao0);
50 | -exp(1j*omega_k*tao0)]; % eq. (3.16)
51 |
52 | B(:,i) = 1/((alpha_21-1)*(alpha_22-1))*(cos(theta)-alpha_21).*(cos(theta)-alpha_22); % eq. (3.23), approximation
53 | end
54 | % figure,plot(pow2db(abs(B(1,:))),'b'),ylim([-20,5]),
55 | % set(gca,'XScale','log'),grid on
56 | % hold on
57 | % plot(pow2db(abs(B(90,:))),'r'),ylim([-20,5]),
58 | % hold on,
59 | % plot(pow2db(abs(B(135,:))),'g'),ylim([-20,5]),
60 | % legend('theta = 0','theta = 90','theta = 135');
61 |
62 | figure,polarplot(linspace(0,2*pi,360),abs(B(:,16)));
63 | figure, mesh(10*log10(abs(B(:,:)))),title('beampattren');
64 |
65 | beamOut = zeros(length(theta),length(omega)); % beamformer output
66 | for ang = 1:length(theta)
67 | for k = 1:length(omega)
68 | omega_k = 2*pi*omega(k); % normalized digital angular frequency
69 | % omega_k = omega(freIndex); % analog angular frequency
70 | a = [1,exp(-1j*omega_k*tao0*cos(theta(ang))),exp(-1j*omega_k*2*tao0*cos(theta(ang)))]; % signal model,steering vector
71 | if(sqrt(H(:,k)'*H(:,k))>1)
72 | H(:,k) = H(:,k)/sqrt(H(:,k)'*H(:,k));
73 | end
74 | beamOut(ang,k) = a*(H(:,k)); % y = w'*a;
75 | end
76 | end
77 |
78 | figure,polarplot(linspace(0,2*pi,360),abs(beamOut(:,16)));%rlim([0 1])
79 |
80 | figure,mesh(10*log10(abs(beamOut(:,:))))%,ylim([-60,60]);
81 |
82 | % [beamOut] = beampolar(H,d,tao0);
83 |
84 |
--------------------------------------------------------------------------------
/beam/DMA_beam.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/beam/DMA_beam.m
--------------------------------------------------------------------------------
/beam/beam.m:
--------------------------------------------------------------------------------
1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 | % beampattern for first-order differential arrays
3 | %
4 | % Created By Wang Wei
5 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 | close all;
7 |
8 | theta = linspace(0,2*pi,360); % incident angle
9 |
10 | f = 1:1:20000; % frequency
11 |
12 | d = 0.005; % sensitive to beampattern
13 | c = 345.8;
14 | tao0 = d/c; % delay
15 | omega = 2*pi*f; % analog angle frequency
16 |
17 | target = 0*pi/180; % target direction
18 | null = 180*pi/180; % null direction
19 |
20 | B = zeros(length(theta),length(f));
21 | HL = zeros(1,length(f));
22 | for i = 1:length(f)
23 | omega_k = omega(i);
24 |
25 | HL(i) = 1j/(omega(i)*tao0*(cos(null)-1)); % approximating e^x with 1+x
26 | % HL(i) = 1/(1-exp(1j*omega_k*tao0*(cos(null)-cos(target)))); % without approximating
27 | for ang = 1:length(theta)
28 | % steering vector
29 | a = [1,exp(-1j*omega_k*tao0*cos(theta(ang)))]; % signal model,steering vector
30 | % filter weights
31 | H = [1;
32 | -exp(1j*omega_k*tao0*cos(null))];
33 | % beamforming
34 | B(ang,i) = a*H; % without compensation filter
35 | B(ang,i) = B(ang,i)*HL(i); % with compensation filter
36 |
37 | % B(ang,i) = 1/(1-cos(null))*(cos(theta(ang))-cos(null)); % with compensation filter
38 | end
39 | end
40 | figure,plot(pow2db(abs(B(1,:))),'b'),ylim([-20,5]),
41 | set(gca,'XScale','log'),grid on
42 | hold on
43 | plot(pow2db(abs(B(90,:))),'r'),ylim([-20,5]),
44 | hold on,
45 | plot(pow2db(abs(B(135,:))),'g'),ylim([-20,5]),
46 | legend('theta = 0','theta = 90','theta = 135');
47 |
48 | figure,polarplot(linspace(0,2*pi,360),abs(B(:,480)));
49 | hold on,polarplot(linspace(0,2*pi,360),abs(B(:,960)));
50 | hold on,polarplot(linspace(0,2*pi,360),abs(B(:,1920)));
51 | hold on,polarplot(linspace(0,2*pi,360),abs(B(:,3840)));
52 |
53 | figure,mesh(abs(B(:,1:8000))),title('beampattern');
54 |
--------------------------------------------------------------------------------
/beam/beam.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/beam/beam.mlx
--------------------------------------------------------------------------------
/beam/beampolar.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/beam/beampolar.m
--------------------------------------------------------------------------------
/beam/beampolar_M12.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/beam/beampolar_M12.m
--------------------------------------------------------------------------------
/beam/beampolar_SS.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/beam/beampolar_SS.m
--------------------------------------------------------------------------------
/doc/DMA_SS.md:
--------------------------------------------------------------------------------
1 | ## 双麦差分+谱减降噪
2 |
3 | [TOC]
4 |
5 | ### 1.双麦配置[^1]
6 |
7 |
8 |
9 | ### 2.处理流程[^2]
10 |
11 |
12 |
13 | 处理流程分为固定波束和谱减两个部分
14 |
15 | #### 2.1 固定波束
16 |
17 | 已假定目标方向为正前方
18 |
19 | $b_{12}$、$b_{21}$和$n_{12}$分别表示消掉延时为$+\tau$、$-\tau$的信号,表示消掉目标信号后的参考噪声
20 |
21 | 1. $n_{12}$ 时域公式表示为:
22 | $$
23 | n_{12}(t)=x_{1}(t)-x_{2}(t)\tag1
24 | $$
25 |
26 |
27 | 频域表达式为:
28 | $$
29 | Y_{n_{12}}(\omega)=\left[\begin{array}{c}{1} \\ {-1}\end{array}\right] S(\omega)\tag2
30 | $$
31 |
32 |
33 |
34 |
35 | 2. $b_{12}$和$b_{21}$分别用来消掉从端射方向入射的信号
36 |
37 | 时域表达式为:
38 |
39 | $$
40 | b_{12}(t)=x_{1}(t-\tau)-x_{2}(t)\\
41 | b_{21}(t)=x_{1}(t)-x_{2}(t-\tau)\tag3
42 | $$
43 |
44 | 频域表达式为:
45 | $$
46 | Y_{b_{12}}(\omega)=\left[\begin{array}{c}{e^{-j \omega \tau}} \\ {-1}\end{array}\right] S(\omega)\\
47 | Y_{b_{21}}(\omega, \theta)=\left[\begin{array}{c}{e^{-j \omega \tau}} \\ {-1}\end{array}\right] S(\omega)\tag4
48 | $$
49 |
50 | 3. 波束输出
51 |
52 | 信号从$\theta$角入射,则上面三个固定波束输出分别表示为
53 | $$
54 | N_{12}(\omega, \theta)=\left[\begin{array}{ll}{1} & {e^{-j \omega \tau_{0} \sin \theta}}\end{array}\right]\left[\begin{array}{c}{1} \\ {-1}\end{array}\right] S(\omega)\tag5
55 | $$
56 |
57 | $$
58 | B_{12}(\omega, \theta)=\left[\begin{array}{ll}{1} & {e^{-j \omega \tau_{0} \sin \theta}}\end{array}\right]\left[\begin{array}{c}{e^{-j \omega \tau}} \\ {-1}\end{array}\right] S(\omega)\tag6
59 | $$
60 |
61 | $$
62 | B_{12}(\omega, \theta)=\left[\begin{array}{ll}{1} & {e^{-j \omega \tau_{0} \sin \theta}}\end{array}\right]\left[\begin{array}{c}{1} \\ {-e^{-j \omega \tau}}\end{array}\right] S(\omega)\tag7
63 | $$
64 |
65 | 画出三个固定波束图如下
66 |
67 |
68 |
69 | #### 2.2 谱减
70 |
71 | 用$M_{12}$对目标方向加强
72 | $$
73 | \left|M_{12}(\omega, k)\right|=\min \left[\left|B_{12}(\omega, k)\right|, | B_{21}(\omega, k)\right|]\tag8
74 | $$
75 | $M_{12}$的输出如下所示
76 |
77 |
78 |
79 | 功率谱减公式如下:
80 | $$
81 | \left|Y_{12}^{\prime}(\omega, k)\right|^{2}=\left\{\begin{array}{ll}{\left|M_{12}(\omega, k)\right|^{2}-\left|N_{12}(\omega, k)\right|^{2},} & {\text { if }\left|M_{12}(\omega, k)\right|>\left|N_{12}(\omega, k)\right|} \\ {0,} & {\text { otherwise }}\end{array}\right.\tag9
82 | $$
83 | 到这一步的输出波束图如下:
84 |
85 |
86 |
87 | #### 2.3 频率补偿
88 |
89 | 从$M_{12}$的波束图可以看到,当信号从正前方入射时,输出响应并不为1,最后需要添加一个补偿滤波器,分析过程参考[1],补偿系数形式如下
90 | $$
91 | H_L(\omega)=\frac{1}{\sqrt{2(1-\cos{\omega\tau_0})}}\tag{10}
92 | $$
93 | 经过频率补偿后,最终的频率不变波束图如下
94 |
95 |
96 |
97 | #### 2.4 相位恢复
98 |
99 | 和常规谱减法类似,使用带噪信号的相位作为目标信号的相位
100 |
101 | ### 3.误差分析
102 |
103 | 以上步骤最终画出来的波束图很理想,但实际录音数据测试效果并不好,分析可能原因如下
104 |
105 | * DOA误差
106 | * 混响影响
107 | * 双麦间距
108 | * 谱减
109 |
110 | #### 3.1 DOA误差
111 |
112 | 从最终的波束图可以看到,目标方向非常窄,用仿真数据测试,在$\pm20$度的时候目标声音就有一定程度的衰减变小
113 |
114 | #### 3.2 混响影响
115 |
116 | 用仿真数据测试,当目标声音没有混响时,输出质量很好,几乎听不到失真,当混响阶数及混响时间加大时,输出失真相应增大,分析可能原因为当有混响时,输出的参考噪声$N_{12}$的还是能听到目标声音,在下一步的谱减中会消掉目标声音而造成失真。
117 |
118 | #### 3.3 双麦间距
119 |
120 | 差分阵列对间距有要求,间距过大时无法画出频率不变波束图,仿真测试0.005间距的效果比0.025间距的失真小
121 |
122 | #### 3.4 谱减法
123 |
124 | (9)式是基础的半波整形谱减法,容易产生音乐残留噪声,可以尝试使用参数控制的过减谱减以及多带谱减等改进
125 |
126 | ### 4. 改进
127 |
128 | 贴一张有干扰录音处理前后的频谱图
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 | 批处理实际录音,识别效果并没有明显提升,根据以上分析,可以尝试的改进方法为在前一级加去混响模块、改进谱减算法减小音乐噪声等。
137 |
138 | 目前仿真数据的效果还是要好于实际录音的效果,可能还有其它因素没有考虑到,算法计算过程可能还需要深入理解,后续有发现再改进
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | 参考:
147 |
148 | [^1]:《Sound Source Separation Using Null-Beamforming and Spectral Subtraction for mobile Device》
149 | [^2]:《differential microphone arrays》
--------------------------------------------------------------------------------
/doc/pic/57563270-4C95-4f4e-A43E-A811F6E1ECE2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/57563270-4C95-4f4e-A43E-A811F6E1ECE2.png
--------------------------------------------------------------------------------
/doc/pic/{194544CE-17C5-45DC-B044-270623C30619}_20191021152956.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{194544CE-17C5-45DC-B044-270623C30619}_20191021152956.jpg
--------------------------------------------------------------------------------
/doc/pic/{1D9ED7CA-80A0-42BE-A554-B9F6A638282F}_20191023164007.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{1D9ED7CA-80A0-42BE-A554-B9F6A638282F}_20191023164007.jpg
--------------------------------------------------------------------------------
/doc/pic/{5FF73B88-7BB7-4AE4-9EC0-37BBDD2499F8}_20191023145635.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{5FF73B88-7BB7-4AE4-9EC0-37BBDD2499F8}_20191023145635.jpg
--------------------------------------------------------------------------------
/doc/pic/{73B28CF7-E00C-46C0-8393-FFED146AAD1D}_20191021203234.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{73B28CF7-E00C-46C0-8393-FFED146AAD1D}_20191021203234.jpg
--------------------------------------------------------------------------------
/doc/pic/{8CEB0A6C-7635-45BE-9668-B327E884334C}_20191023141623.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{8CEB0A6C-7635-45BE-9668-B327E884334C}_20191023141623.jpg
--------------------------------------------------------------------------------
/doc/pic/{97F38125-6E72-4774-B031-BF57999C8F17}_20191021153136.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{97F38125-6E72-4774-B031-BF57999C8F17}_20191021153136.jpg
--------------------------------------------------------------------------------
/doc/pic/{E5D9A13E-3F78-42D2-B864-DF4168E58AC6}_20191023164103.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{E5D9A13E-3F78-42D2-B864-DF4168E58AC6}_20191023164103.jpg
--------------------------------------------------------------------------------
/doc/pic/{EC4ED9E9-1EC2-4136-BB57-76AF5EE9E4F3}_20191023141233.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/doc/pic/{EC4ED9E9-1EC2-4136-BB57-76AF5EE9E4F3}_20191023141233.jpg
--------------------------------------------------------------------------------
/lib/+file/find_pcm.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/lib/+file/find_pcm.m
--------------------------------------------------------------------------------
/lib/+sim/RIR_generator_URA.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/lib/+sim/RIR_generator_URA.m
--------------------------------------------------------------------------------
/lib/+sim/generate_signal.m:
--------------------------------------------------------------------------------
1 | function [ x,varargin] = generate_signal( source,angle,r,distant,beta,varargin )
2 | %----------------------------------------------------------------------
3 | % generate micarray simulation signal
4 | %function
5 | %
6 | % Usage: (1) x = generate_signal( source,[90,0],0.032,1,0.2 )
7 | %
8 | % Inputs:
9 | % source source signal
10 | % angle incident angle
11 | % r radius of array
12 | % beta reverberation parameter
13 | % varargin
14 | % varargin{1} scale of room-impulse-response
15 | %
16 | % Outputs:
17 | % x multi-channel signal
18 | % varargin{1} room-impulse-response
19 | % dependencies:
20 | % rir-generator
21 | %
22 | % Authors: Wang wei
23 | % $Revision: 0.0 $ $Date: $
24 | %
25 | % ---------------------------------------------------------------------
26 |
27 | if nargin<2
28 | fprintf('Usage: [x]=generate_signal(source,angle) \n');
29 | return;
30 | end;
31 | if nargin<3
32 | r = 0.032;
33 | end;
34 | if nargin<4
35 | distant = 1.0;
36 | end;
37 | if nargin<5
38 | beta = 0.2;
39 | end;
40 | if nargin==6
41 | scale = varargin{1};
42 | else
43 | scale = 10;
44 | end;
45 | if nargin==7
46 | order = varargin{2};
47 | else
48 | order = -1;
49 | end
50 |
51 |
52 | angle = [angle(1) angle(2)]/180*pi; % source direction [0,180]
53 | [x1,y1,z1]=sph2cart(angle(1),angle(2),distant); % source position 1
54 | source_pos = [x1,y1,z1]; % Source position [x y z] (m)
55 |
56 | N = 4; % number of sensor
57 |
58 | h = sim.RIR_generator_URA( source_pos,beta,r,order);
59 | h = h*scale;
60 | x = zeros(length(source)+size(h,2)-1,N);
61 | for i=1:N
62 | x(:,i) = conv(source,h(i,:));
63 | end
64 |
65 | if nargout>1
66 | varargin{1} = h;
67 | end
68 |
69 | end
70 |
71 |
--------------------------------------------------------------------------------
/lib/+sim/noise_gen_URA.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/lib/+sim/noise_gen_URA.m
--------------------------------------------------------------------------------
/lib/+sim/signal_simulation.m:
--------------------------------------------------------------------------------
1 | function [ sig ] = signal_simulation( r,slice )
2 | % signal simulation function
3 | %
4 | % Usage: (1) [ sig ] = signal_simulation(0.064,[1,3]);
5 | %
6 | % Inputs:
7 | % r radius of circular array
8 | % slice choose which channel to use
9 | % varargin
10 | % arrayType array type,linear or circular,default linear
11 | %
12 | % Outputs:
13 | % sig 4-channel siganl [samples,channel]
14 | %
15 | % Created by Wang wei
16 | %% generate diffuse noise
17 | [ noise,Pos] = sim.noise_gen_URA(r);
18 |
19 | noise = noise'/500;
20 | %% signal simulation
21 | pathname = 'wav/';
22 |
23 | % use a clean speech audio as desired signal
24 | [speech ,fs] = audioread([pathname,'S_01_01.wav']);
25 | [interference] = audioread([pathname,'S_72_09.wav']);
26 |
27 | s = sim.generate_signal(speech,[90,0],r,2,0.2,10,-1);
28 | interf = sim.generate_signal(interference,[0,0],r,2,0.2,10,-1);
29 |
30 | % signal+interference+diffuse noise
31 | len_min = min(min(size(s,1),size(interf,1)),size(noise,1));
32 | % slice = [1,3];
33 | clean_s = s(1:len_min,slice);
34 | clean_i = interf(1:len_min,slice);
35 | clean_n = noise(1:len_min,slice);
36 | switch 1
37 | case 1
38 | x = clean_s+clean_i+clean_n;
39 | case 2
40 | x = clean_s+clean_i;
41 | clean_n = zeros(size(clean_n));
42 | case 3
43 | x = clean_s;
44 | clean_i = zeros(size(clean_i));
45 | clean_n = zeros(size(clean_n));
46 | case 4
47 | % ideal signal
48 | len_min_clean = min(length(speech),length(interference));
49 | speech = speech(1:len_min_clean);
50 | interference = interference(1:len_min_clean);
51 | clean_s = [speech(3:end),speech(1:end-2)];
52 | clean_i = [interference(1:size(clean_s,1)),interference(1:size(clean_s,1))];
53 | x = clean_s + clean_i;
54 | d = 0.0213*2;
55 | otherwise
56 | disp('other value')
57 | end
58 |
59 | SNR = snr(clean_s(:,1),clean_i(:,1))
60 |
61 | sig.speech = speech;
62 | sig.clean_s = clean_s;
63 | sig.clean_i = clean_i;
64 | sig.clean_n = clean_n;
65 | sig.x = x;
66 |
67 | end
68 |
69 |
--------------------------------------------------------------------------------
/lib/+util/fig.m:
--------------------------------------------------------------------------------
1 | function fig(data_in, fs)
2 |
3 | if nargin == 1
4 | [data, fs] = audioread(data_in);
5 | filename = data_in;
6 | else
7 | data = data_in;
8 | end
9 | Fs = 8000;
10 | noverlap = 128 * fs / Fs;
11 | nfft= 256 * fs / Fs;
12 |
13 | figure;
14 | spectrogram(data/max(abs(data)), hamming(nfft),noverlap,nfft,fs,'yaxis')
15 | set(gcf, 'position', [1, 235, 1366, 400]);
16 | set(gca, 'position', [0.05, 0.12, 0.85, 0.8]);
17 | if exist('filename','var')
18 | title(filename, 'interpreter', 'none');
19 | end
20 |
21 |
--------------------------------------------------------------------------------
/lib/+util/play.m:
--------------------------------------------------------------------------------
1 | function player = play(varargin)
2 |
3 | if ischar(varargin{1})
4 | [data, fs] = audioread(varargin{1});
5 | if length(varargin) == 1
6 | normalizemode = 1;
7 | else
8 | normalizemode = varargin{2};
9 | end
10 | else
11 |
12 | data = varargin{1};
13 | fs = varargin{2};
14 | if length(varargin) == 2
15 | normalizemode = 1;
16 | else
17 | normalizemode = varargin{3};
18 | end
19 | end
20 | if normalizemode
21 | data = data / max(abs(data));
22 | end
23 | player = audioplayer(data, fs);
24 | play(player)
--------------------------------------------------------------------------------
/lib/+util/plot.m:
--------------------------------------------------------------------------------
1 | function handle = plot(data_in, fs)
2 | % 1) plotwav(data)
3 | % data is the wav filename including path
4 | % 2) plotwav(data, fs)
5 |
6 | if nargin == 1
7 | [data, fs] = audioread(data_in);
8 | else
9 | data = data_in;
10 | end
11 | if nargout == 1
12 | handle = figure;
13 | else
14 | figure;
15 | end
16 | plot((0 : length(data) - 1) / fs, data);
17 | xlim([0 , (length(data) / fs)]);
18 | xlabel('Time(Secs)')
--------------------------------------------------------------------------------
/lib/+util/visual.m:
--------------------------------------------------------------------------------
1 | function [ output_args ] = visual( x,y )
2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 | %% visualization
4 | %
5 | %
6 | % example Usage:
7 | % x = stft( Y)
8 | %
9 | %
10 | % Inputs:
11 | % Y input time-frequency matrix,stored as [frameNum,half_bin]
12 | % nfft fft points
13 | % frameLength frame length
14 | % inc hop size
15 | % window analysis window
16 | % varargin
17 | %
18 | %
19 | % Outputs:
20 | % x time-domain data
21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22 |
23 | if nargin == 1
24 | x = x(:);
25 | X = stft(x);
26 | X = abs(squeeze(X)');
27 | figure,
28 | imagesc(10*log10(X))
29 | set(gca,'YDir','normal')
30 | caxis([-50 10])
31 | colorbar
32 | title('input signal')
33 | xlabel('frame')
34 | ylabel('frequeny')
35 | end
36 |
37 | if nargin == 2
38 | X = stft(x);
39 | Y = stft(y);
40 | X = abs(squeeze(X)');
41 | Y = abs(squeeze(Y)');
42 | figure,
43 | subplot(211)
44 | imagesc(10*log10(X))
45 | set(gca,'YDir','normal')
46 | caxis([-50 10])
47 | colorbar
48 | title('input signal')
49 | xlabel('frame')
50 | ylabel('frequeny')
51 | subplot(212)
52 | imagesc(10*log10(Y))
53 | set(gca,'YDir','normal')
54 | caxis([-50 10])
55 | colorbar
56 | title('output signal')
57 | xlabel('frame')
58 | ylabel('frequeny')
59 | end
60 |
61 |
62 |
63 | end
64 |
65 |
--------------------------------------------------------------------------------
/lib/GenNoiseMSC.m:
--------------------------------------------------------------------------------
1 | function [ Fvv ] = GenNoiseMSC(M,N_FFT,fs,r,varargin)
2 | %GenNoiseMSC compute diffuse noise field Mignitude-SquareD Coherence
3 | %function
4 | %
5 | % Usage: (1) [ Fvv ] = GenNoiseMSC(M,N,fs,r,arrayType);
6 | %
7 | % Inputs:
8 | % M input channels
9 | % N_FFT fft points
10 | % fs sample frequency in Hz
11 | % r array aperture
12 | % varargin
13 | % arrayType array type,linear or circular,default linear
14 | %
15 | % Outputs:
16 | % Fvv [half_bin,M,M] coherence function
17 | if(nargin>4)
18 | arrayType = varargin{1};
19 | else
20 | arrayType = 'linear';
21 | end
22 | c = 340;
23 | f = 0:fs/256:fs/2;
24 | Fvv = zeros(N_FFT/2+1,M,M);
25 | k_optimal = 1;
26 | for i = 1:M
27 | for j = 1:M
28 | if i == j
29 | Fvv(:,i,j) = ones(N_FFT/2+1,1);
30 | else
31 | switch(lower(arrayType))
32 | case 'linear'
33 | dij = abs(i-j)*r;
34 | case 'circular'
35 | mic_rad = abs(i-j)*(360/M)*pi/180; % radian between two sensor
36 | dij = np.sqrt(r^2+r^2-2*r*r*cos(mic_rad)); % distant between two sensor
37 | end
38 | Fvv(:,i,j) = sin(2*pi*f*dij*k_optimal/c)./(2*pi*f*dij*k_optimal/c);Fvv(1,i,j) = 0.998;%T(2) = 0.996;
39 | end
40 | % index = find(Fvv(:,i,j)>0.9);
41 | % if(size(index,1)>0)
42 | % Fvv(index,i,j)=0.9;
43 | % end
44 | end
45 | end
46 |
47 | end
48 |
49 |
--------------------------------------------------------------------------------
/lib/GenNoiseMSC_shift.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/lib/GenNoiseMSC_shift.m
--------------------------------------------------------------------------------
/lib/mycohere.m:
--------------------------------------------------------------------------------
1 | function [Cxy, f] = mycohere(varargin)
2 | %COHERE Coherence function estimate.
3 | % Cxy = COHERE(X,Y,NFFT,Fs,WINDOW) estimates the coherence of X and Y
4 | % using Welch's averaged periodogram method. Coherence is a function
5 | % of frequency with values between 0 and 1 that indicate how well the
6 | % input X corresponds to the output Y at each frequency. X and Y are
7 | % divided into overlapping sections, each of which is detrended, then
8 | % windowed by the WINDOW parameter, then zero-padded to length NFFT.
9 | % The magnitude squared of the length NFFT DFTs of the sections of X and
10 | % the sections of Y are averaged to form Pxx and Pyy, the Power Spectral
11 | % Densities of X and Y respectively. The products of the length NFFT DFTs
12 | % of the sections of X and Y are averaged to form Pxy, the Cross Spectral
13 | % Density of X and Y. The coherence Cxy is given by
14 | % Cxy = (abs(Pxy).^2)./(Pxx.*Pyy)
15 | % Cxy has length NFFT/2+1 for NFFT even, (NFFT+1)/2 for NFFT odd, or NFFT
16 | % if X or Y is complex. If you specify a scalar for WINDOW, a Hanning
17 | % window of that length is used. Fs is the sampling frequency which does
18 | % not effect the cross spectrum estimate but is used for scaling of plots.
19 | %
20 | % [Cxy,F] = COHERE(X,Y,NFFT,Fs,WINDOW,NOVERLAP) returns a vector of freq-
21 | % uencies the same size as Cxy at which the coherence is computed, and
22 | % overlaps the sections of X and Y by NOVERLAP samples.
23 | %
24 | % COHERE(X,Y,...,DFLAG), where DFLAG can be 'linear', 'mean' or 'none',
25 | % specifies a detrending mode for the prewindowed sections of X and Y.
26 | % DFLAG can take the place of any parameter in the parameter list
27 | % (besides X and Y) as long as it is last, e.g. COHERE(X,Y,'mean');
28 | %
29 | % COHERE with no output arguments plots the coherence in the current
30 | % figure window.
31 | %
32 | % The default values for the parameters are NFFT = 256 (or LENGTH(X),
33 | % whichever is smaller), NOVERLAP = 0, WINDOW = HANNING(NFFT), Fs = 2,
34 | % P = .95, and DFLAG = 'none'. You can obtain a default parameter by
35 | % leaving it off or inserting an empty matrix [], e.g.
36 | % COHERE(X,Y,[],10000).
37 | %
38 | % See also PSD, CSD, TFE.
39 | % ETFE, SPA, and ARX in the Identification Toolbox.
40 |
41 | % Author(s): T. Krauss, 3-31-93
42 | % Copyright (c) 1988-98 by The MathWorks, Inc.
43 | % $Revision: 1.1 $ $Date: 1998/06/03 14:42:19 $
44 |
45 | narginchk(2,7);
46 | x = varargin{1};
47 | y = varargin{2};
48 | %[msg,nfft,Fs,window,noverlap,p,dflag]=psdchk(varargin(3:end),x,y);
49 | %error(msg)
50 | nfft = varargin{3};
51 | Fs =varargin{4};
52 | window=hanning(nfft);
53 | noverlap = 0.75*nfft;
54 | p = .95;
55 | dflag = 'none';
56 |
57 | % compute PSD and CSD
58 | window = window(:);
59 | n = length(x); % Number of data points
60 | nwind = length(window); % length of window
61 | if n < nwind % zero-pad x , y if length is less than the window length
62 | x(nwind)=0;
63 | y(nwind)=0;
64 | n=nwind;
65 | end
66 | x = x(:); % Make sure x is a column vector
67 | y = y(:); % Make sure y is a column vector
68 | k = fix((n-noverlap)/(nwind-noverlap)); % Number of windows
69 | % (k = fix(n/nwind) for noverlap=0)
70 | index = 1:nwind;
71 |
72 | Pxx = zeros(nfft,1); Pxx2 = zeros(nfft,1);
73 | Pyy = zeros(nfft,1); Pyy2 = zeros(nfft,1);
74 | Pxy = zeros(nfft,1); Pxy2 = zeros(nfft,1);
75 | for i=1:k
76 | if strcmp(dflag,'none')
77 | xw = window.*x(index);
78 | yw = window.*y(index);
79 | elseif strcmp(dflag,'linear')
80 | xw = window.*detrend(x(index));
81 | yw = window.*detrend(y(index));
82 | else
83 | xw = window.*detrend(x(index),0);
84 | yw = window.*detrend(y(index),0);
85 | end
86 | index = index + (nwind - noverlap);
87 | Xx = fft(xw,nfft);
88 | Yy = fft(yw,nfft);
89 | Xx2 = abs(Xx).^2;
90 | Yy2 = abs(Yy).^2;
91 | Xy2 = Yy.*conj(Xx);
92 | Pxx = Pxx + Xx2;
93 | Pxx2 = Pxx2 + abs(Xx2).^2;
94 | Pyy = Pyy + Yy2;
95 | Pyy2 = Pyy2 + abs(Yy2).^2;
96 | Pxy = Pxy + Xy2;
97 | Pxy2 = Pxy2 + Xy2.*conj(Xy2);
98 | end
99 |
100 | % Select first half
101 | if ~any(any(imag([x y])~=0)), % if x and y are not complex
102 | if rem(nfft,2), % nfft odd
103 | select = [1:(nfft+1)/2];
104 | else
105 | select = [1:nfft/2+1]; % include DC AND Nyquist
106 | end
107 | Pxx = Pxx(select);
108 | Pxx2 = Pxx2(select);
109 | Pyy = Pyy(select);
110 | Pyy2 = Pyy2(select);
111 | Pxy = Pxy(select);
112 | Pxy2 = Pxy2(select);
113 | else
114 | select = 1:nfft;
115 | end
116 | %Coh = (abs(Pxy).^2)./(Pxx.*Pyy); % coherence function estimate
117 | Coh = Pxy./sqrt(Pxx.*Pyy);
118 | freq_vector = (select - 1)'*Fs/nfft;
119 |
120 | % set up output parameters
121 | if (nargout == 2),
122 | Cxy = Coh;
123 | f = freq_vector;
124 | elseif (nargout == 1),
125 | Cxy = Coh;
126 | elseif (nargout == 0), % do a plot
127 | newplot;
128 | plot(freq_vector,Coh), grid on
129 | xlabel('Frequency'), ylabel('Coherence Function Estimate');
130 | end
--------------------------------------------------------------------------------
/lib/patternURA.m:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/lib/patternURA.m
--------------------------------------------------------------------------------
/lib/spectral_subtraction.m:
--------------------------------------------------------------------------------
1 | %SPECTRAL_SUBTRACTION Compute spectral subtraction weights.
2 | %
3 | % weights = spectral_subtraction(SNR,alpha,beta,mu,Gmin)
4 | %
5 | % alpha = 1; beta = 1; % power subtraction
6 | % alpha = 2; beta = 0.5; % magnitude subtraction
7 | % alpha = 2; beta = 1; % Wiener filter
8 | % mu: noise overestimation
9 | % Gmin: gain floor
10 | %
11 | % Andreas Schwarz (schwarz@lnt.de)
12 | % Multimedia Communications and Signal Processing
13 | % Friedrich-Alexander-Universitaet Erlangen-Nuernberg (FAU)
14 | % Cauerstr. 7, 91058 Erlangen, Germany
15 | function weights = spectral_subtraction(SNR,alpha,beta,mu,Gmin)
16 |
17 | if (nargin == 1)
18 | % default: magnitude subtraction
19 | alpha = 2;
20 | beta = 0.5;
21 | mu = 1;
22 | end
23 |
24 | if ~exist('Gmin','var')
25 | Gmin = 0.1;
26 | end
27 |
28 | SNR = max(SNR,0);
29 | weights = max(1 - (mu./(SNR + 1)).^beta, 0).^alpha;
30 | weights = max(weights,0);
31 | weights = max(sqrt(weights),Gmin);
32 |
33 | end
--------------------------------------------------------------------------------
/lib/stft_test.m:
--------------------------------------------------------------------------------
1 | [x,fs] = audioread('S_01_01.wav');
2 |
3 | % x = [zeros(128,1);x];
4 | Y = stft(x);
5 |
6 | x_rec = istft(Y);
7 |
8 | % Y = stftanalysis(x,256,128);
9 | %
10 | % x_rec = stftsynthesis(Y,256,128);
11 |
--------------------------------------------------------------------------------
/lib/update_CSD.m:
--------------------------------------------------------------------------------
1 | function [ Pxij ] = update_CSD( X,alpha,Pxij)
2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 | % calculate cross-spectral power density
4 | %
5 | %
6 | % example Usage:
7 | % [ Pxij ] = update_CSD( X,alpha,Pxij)
8 | %
9 | % Inputs:
10 | % X Multichannel input data,stored in column-wise
11 | % alpha average factor
12 | % Pxij last Pxij,size of [N(N-1)/2,half_bin]
13 | %
14 | %
15 | % Outputs:
16 | % Pxij recursively averaged CSD
17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18 | N = size(X,1); % channel
19 | for i = 1:N
20 | for j = 1:N
21 | Xi = X(i,:);
22 | Xj = X(j,:);
23 | if(i==j)
24 | Fvv(i,j,:) = 1;
25 | else
26 | Pxij_i_j = squeeze(Pxij(i,j,:)).';
27 | Pxij(i,j,:) = alpha*Pxij_i_j+(1-alpha)*Xi.*conj(Xj);
28 |
29 | end
30 | end
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/lib/update_MSC.m:
--------------------------------------------------------------------------------
1 | function [ P ] = update_MSC(X,P,alpha,varargin)
2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 | % calculate coherence function
4 | %
5 | %
6 | % example Usage:
7 | % [ Pxii,Pxij,Fvv ] = update_MSC(X,Pxii,Pxij,Fvv,alpha)
8 | %
9 | % Inputs:
10 | % X Multichannel input data,size of [channel,half_bin]
11 | % alpha average factor
12 | % Pxii previous Pxii,size of [N(N-1)/2,half_bin]
13 | % Pxij previous Pxij,size of [N(N-1)/2,half_bin]
14 | % Fvv previous Fvv,size of [N,N,,half_bin]
15 | % varargin
16 | % alpha_MSC MSC average factor
17 | %
18 | %
19 | % Outputs:
20 | % Pxii,Pxij,Fvv recursively averaged Pxii,Pxij,Fvv
21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22 |
23 | N = size(X,1); % channel
24 |
25 |
26 | if nargin <3
27 | alpha = 0.6;
28 | end
29 | if nargin ==4
30 | alpha_MSC = varargin{1};
31 | else
32 | alpha_MSC = 0;
33 | end
34 |
35 | Pxii = P.Pxii;
36 | Pxij = P.Pxij;
37 | Fvv = P.Fvv;
38 |
39 | % Pxii = update_PSD(X,alpha,Pxii);
40 | % Pxij = update_CSD(X,alpha,Pxij);
41 |
42 | for i = 1:N
43 | Xi = X(i,:);
44 | % update auto-spectral power density
45 | Pxii(i,:) = alpha*Pxii(i,:)+(1-alpha)*Xi.*conj(Xi);
46 | end
47 | for i = 1:N
48 | for j = 1:N
49 | Xi = X(i,:);
50 | Xj = X(j,:);
51 | if(i==j)
52 | Fvv(i,j,:) = 1;
53 | else
54 | Pxij_i_j = squeeze(Pxij(i,j,:)).';
55 | Pxij(i,j,:) = alpha*Pxij_i_j+(1-alpha)*Xi.*conj(Xj);
56 | Pxij_i_j = squeeze(Pxij(i,j,:)).';
57 |
58 | % complex coherence function
59 | Fvv_i_j_curr = Pxij_i_j./(sqrt(Pxii(i,:).*Pxii(j,:)));
60 |
61 | Fvv_i_j = squeeze(Fvv(i,j,:)).';
62 | Fvv(i,j,:) = alpha_MSC*Fvv_i_j+(1-alpha_MSC)*Fvv_i_j_curr;
63 | % Fvv_i_j_t = Pxij(t,:)./(sqrt(Pxii(i,:).*Pxii(j,:)));
64 | end
65 | end
66 | end
67 |
68 | P.Pxii = Pxii;
69 | P.Pxij = Pxij;
70 | P.Fvv = Fvv;
71 |
72 |
--------------------------------------------------------------------------------
/lib/update_PSD.m:
--------------------------------------------------------------------------------
1 | function [ Pxii ] = update_PSD( X,alpha,Pxii)
2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 | % calculate auto-spectral power density
4 | %
5 | %
6 | % example Usage:
7 | % [ Pxii ] = update_PSD( X,alpha,Pxii)
8 | %
9 | % Inputs:
10 | % X Multichannel input data,stored in column-wise
11 | % alpha average factor
12 | % Pxii last Pxii,size of [N(N-1)/2,half_bin]
13 | %
14 | %
15 | % Outputs:
16 | % Pxii recursively averaged PSD
17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18 | N = size(X,1); % channel
19 | for i = 1:N
20 | Xi = X(i,:);
21 | % update auto-spectral power density
22 | Pxii(i,:) = alpha*Pxii(i,:)+(1-alpha)*Xi.*conj(Xi);
23 | end
24 |
25 | end
26 |
27 |
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_180/1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_180/1.wav
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_180/2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_180/2.wav
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_180/3.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_180/3.wav
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_180/4.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_180/4.wav
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_90/1.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_90/1.wav
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_90/2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_90/2.wav
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_90/3.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_90/3.wav
--------------------------------------------------------------------------------
/wav/4mic_r0.005/target_2mic_ganrao_90/4.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/4mic_r0.005/target_2mic_ganrao_90/4.wav
--------------------------------------------------------------------------------
/wav/STEREO_0024.pcm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/STEREO_0024.pcm
--------------------------------------------------------------------------------
/wav/STEREO_0111.pcm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/STEREO_0111.pcm
--------------------------------------------------------------------------------
/wav/xmos/rec/readme.txt:
--------------------------------------------------------------------------------
1 | target:0
2 | interf:270
--------------------------------------------------------------------------------
/wav/xmos/rec/音轨-2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec/音轨-2.wav
--------------------------------------------------------------------------------
/wav/xmos/rec/音轨-3.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec/音轨-3.wav
--------------------------------------------------------------------------------
/wav/xmos/rec/音轨-4.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec/音轨-4.wav
--------------------------------------------------------------------------------
/wav/xmos/rec/音轨-5.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec/音轨-5.wav
--------------------------------------------------------------------------------
/wav/xmos/rec96/readme.txt:
--------------------------------------------------------------------------------
1 | target:0
2 | inferf:270
--------------------------------------------------------------------------------
/wav/xmos/rec96/音轨-2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec96/音轨-2.wav
--------------------------------------------------------------------------------
/wav/xmos/rec96/音轨-3.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec96/音轨-3.wav
--------------------------------------------------------------------------------
/wav/xmos/rec96/音轨-4.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec96/音轨-4.wav
--------------------------------------------------------------------------------
/wav/xmos/rec96/音轨-5.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wangwei2009/differential-array/487cbfe7299ad7bb7443a6314e451f4e685e6159/wav/xmos/rec96/音轨-5.wav
--------------------------------------------------------------------------------