欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

声源数目测定

程序员文章站 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)

运行结果如下

声源数目测定

 

声源数目测定

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

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