├── .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 | 57563270-4C95-4f4e-A43E-A811F6E1ECE2 8 | 9 | ### 2.处理流程[^2] 10 | 11 | {97F38125-6E72-4774-B031-BF57999C8F17}_20191021153136 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 | {73B28CF7-E00C-46C0-8393-FFED146AAD1D}_20191021203234 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 | {EC4ED9E9-1EC2-4136-BB57-76AF5EE9E4F3}_20191023141233 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 | {8CEB0A6C-7635-45BE-9668-B327E884334C}_20191023141623 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 | {5FF73B88-7BB7-4AE4-9EC0-37BBDD2499F8}_20191023145635 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 | {1D9ED7CA-80A0-42BE-A554-B9F6A638282F}_20191023164007 131 | 132 | 133 | 134 | {E5D9A13E-3F78-42D2-B864-DF4168E58AC6}_20191023164103 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 --------------------------------------------------------------------------------