声源数目测定

本文使用协方差矩阵特征值分解的方法求解声音数目,对比两种主特征值数目的判定方法,代码如下

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)

运行结果如下

使用特征值比值法效果不理想,使用比例法,效果稍好,但是主特征值里面较大的会对较小的形成掩蔽,影响误差。

如果能在测定数目的同时,将声源位置进行测定,结合两个测试结果就能对整个语句内声源数做一个比较准确的统计,可以近似认为不同帧里面的音源如果来自同一个方向是一个声源的。

猜你喜欢

转载自blog.csdn.net/ljl86400/article/details/82705342