声源数目测定
程序员文章站
2024-03-07 18:25:45
...
本文使用协方差矩阵特征值分解的方法求解声音数目,对比两种主特征值数目的判定方法,代码如下
clc
clear
close all
frameLength = 160;
audioDataArray = zeros(frameLength,5);
audioDataArray2 = zeros(frameLength,5);
signalSourceInfo = zeros(4,1);
signalSourceInfo2 = zeros(4,1);
run audioRead.m;
framesNumber = size(audioSource1.Signal,1)/160;
timeAxisOfAudiodata = 1/fs1:1/fs1:(1/fs1)*size(channel1,1);
%% detection of signal number block1
numTSteps = fix(framesNumber*160/frameLength);
timeAxisOfFrames = frameLength/fs1:frameLength/fs1:numTSteps*(frameLength/fs1);
signalNumber = zeros(2,numTSteps);
mainEigenValue = zeros(5,1);
while(numTSteps)
audioDataArray(:,1) = audioSource1();
audioDataArray(:,2) = audioSource2();
audioDataArray(:,3) = audioSource3();
audioDataArray(:,4) = audioSource4();
audioDataArray(:,5) = audioSource5();
audioDataArrayCovarianceArray = (audioDataArray*audioDataArray')/frameLength;
eigenValue = eig(audioDataArrayCovarianceArray); % 此处用协方差矩阵的特征值分解进行声源数目判定,
% 实际上完全可以用观测信号的奇异值分解算法代替
eigenValue = sort(eigenValue,'descend');
mainEigenValue = eigenValue(1:5);
for iloop1 = 1:4
signalSourceInfo(iloop1) = mainEigenValue(iloop1)/mainEigenValue(iloop1 + 1);
end
[maxRatio,maxRatioOrder] = max(signalSourceInfo);
signalNumber(1,numTSteps) = maxRatioOrder ;
signalNumber(2,numTSteps) = maxRatio;
numTSteps = numTSteps -1;
end
%% detection of signal number block2
run audioRead.m;
numTSteps2 = fix(framesNumber*160/frameLength);
signalNumber2 = zeros(2,numTSteps2);
mainEigenValue2 = zeros(5,1);
while(numTSteps2)
audioDataArray2(:,1) = audioSource1();
audioDataArray2(:,2) = audioSource2();
audioDataArray2(:,3) = audioSource3();
audioDataArray2(:,4) = audioSource4();
audioDataArray2(:,5) = audioSource5();
audioDataArrayCovarianceArray2 = (audioDataArray2*audioDataArray2')/frameLength;
eigenValue2 = eig(audioDataArrayCovarianceArray2); % 此处用协方差矩阵的特征值分解进行声源数目判定,
% 实际上完全可以用观测信号的奇异值分解算法代替
eigenValue2 = sort(eigenValue2,'descend');
mainEigenValue2 = eigenValue2(1:5);
sumMainEigenValue2 = sum(mainEigenValue2,1);
sumSignalEigenValue = 0;
for iloop1 = 1:4
sumSignalEigenValue = sumSignalEigenValue + mainEigenValue2(iloop1);
ratio = sumSignalEigenValue/sumMainEigenValue2;
if (ratio > 0.93)
signalNumber2(1,numTSteps2) = iloop1;
signalNumber2(2,numTSteps2) = ratio;
break;
end
end
numTSteps2 = numTSteps2 -1;
end
%% plot block1 result
figure(1)
subplot(3,1,1)
plot(timeAxisOfAudiodata,channel1)
subplot(3,1,2)
stem(timeAxisOfFrames,fliplr(signalNumber(1,:)))
subplot(3,1,3)
stem(timeAxisOfFrames,fliplr(signalNumber(2,:)))
figure(2)
subplot(3,1,1)
plot(timeAxisOfAudiodata,channel1)
subplot(3,1,2)
stem(timeAxisOfFrames,fliplr(signalNumber2(1,:)))
subplot(3,1,3)
stem(timeAxisOfFrames,fliplr(signalNumber2(2,:)))
figure(3)
plot(timeAxisOfAudiodata,channel1)
hold on
plot(timeAxisOfAudiodata,channel2)
% sound(channel1,fs1)
运行结果如下
使用特征值比值法效果不理想,使用比例法,效果稍好,但是主特征值里面较大的会对较小的形成掩蔽,影响误差。
如果能在测定数目的同时,将声源位置进行测定,结合两个测试结果就能对整个语句内声源数做一个比较准确的统计,可以近似认为不同帧里面的音源如果来自同一个方向是一个声源的。
推荐阅读
-
声源数目测定
-
c# 可变数目参数params实例
-
c# 可变数目参数params实例
-
【shell】linux 查看文件夹以及文件大小数目等信息
-
取数目字的正则方法
-
array_rand()—遍历数组的键名,随机返回指定数目的键名;
-
【ERROR】EXECUTE 后的事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配。上一计数 = 0,当前计数 = 1。
-
com.microsoft.sqlserver.jdbc.SQLServerException: 传入的请求具有过多的参数。该服务器支持最多 2100 个参数。请减少参数的数目,然后重新发送该请求。
-
判断A数组的数目字是否大于B数组
-
PHP数目字格式化,数字每三位加逗号,可以保留小数