Акустическое формирование луча с использованием массива микрофонов

Этот пример иллюстрирует формирование луча микрофонной решётки для извлечения желаемых речевых сигналов в доминирующей в интерференциях шумном окружении. Такие операции применяются для улучшения качества речевого сигнала для восприятия или дальнейшей обработки. Например, шумным окружением может быть торговая комната, и массив микрофонов может быть установлен на мониторе торгового компьютера. Если торговый компьютер должен принимать речевые команды от трейдера, операция формирования луча имеет решающее значение для повышения качества принимаемой речи и достижения расчетной точности распознавания речи.

В примере показаны два типа формирователей луча во временном интервале: beamformer с задержкой во времени и Frost beamformer. Это также иллюстрирует, как можно использовать диагональную загрузку, чтобы улучшить робастность Фрост-beamformer. Вы можете слушать речевые сигналы на каждом шаге обработки.

Этот пример требует Phased Array System Toolbox.

Задайте равномерный линейный массив

Сначала задайте равномерный линейный массив (ULA), чтобы принять сигнал. Массив содержит 10 всенаправленных элементов (микрофонов), расположенных на расстоянии 5 см друг от друга. Установите верхнюю границу для интересующих областей значений частоты 4 кГц, потому что сигналы, используемые в этом примере, дискретизированы на 8 кГц.

microphone = ...
    phased.OmnidirectionalMicrophoneElement('FrequencyRange',[20 4000]);

Nele = 10;
ula = phased.ULA(Nele,0.05,'Element',microphone);
c = 340;  % speed of sound, in m/s

Симулируйте принятые сигналы

Затем моделируйте многоканальный сигнал, принимаемый массивом микрофонов. В качестве интересующего звука используются два речевых сигнала. В качестве интерференции используется сегмент звука смеха. Частота дискретизации аудиосигналов составляет 8 кГц.

Поскольку аудиосигналы обычно большие, часто нецелесообразно считывать весь сигнал в память. Поэтому в этом примере вы считываете и обрабатываете сигнал потоковым способом, т.е. разбиваете сигнал на небольшие блоки на входе, обрабатываете каждый блок, а затем собираете их на выходе.

Направление падения первого речевого сигнала составляет -30 степени по азимуту и 0 степени по повышению. Направление второго речевого сигнала составляет -10 степени по азимуту и 10 степени по повышению. Интерференция происходит от 20 степеней по азимуту и 0 степени по повышению.

ang_dft = [-30; 0];
ang_cleanspeech = [-10; 10];
ang_laughter = [20; 0];

Теперь можно использовать широкополосный коллектор, чтобы симулировать 3-секундный сигнал, принятый массивом. Заметьте, что этот подход принимает, что каждый входной одноканальный сигнал принимается в начале массива одним микрофоном.

fs = 8000;
collector = phased.WidebandCollector('Sensor',ula,'PropagationSpeed',c, ...
    'SampleRate',fs,'NumSubbands',1000,'ModulatedInput', false);

t_duration = 3;  % 3 seconds
t = 0:1/fs:t_duration-1/fs;

Сгенерируйте сигнал белого шума с степенью 1e-4 Вт, чтобы представлять тепловой шум для каждого датчика. Локальный поток случайных чисел обеспечивает воспроизводимые результаты.

prevS = rng(2008);
noisePwr = 1e-4;

Запустите симуляцию. На выходе принятый сигнал сохранен в 10-столбцовой матрице. Каждый столбец матрицы представляет сигнал, собранный одним микрофоном. Обратите внимание, что аудио воспроизводится во время симуляции.

% preallocate
NSampPerFrame = 1000;
NTSample = t_duration*fs;
sigArray = zeros(NTSample,Nele);
voice_dft = zeros(NTSample,1);
voice_cleanspeech = zeros(NTSample,1);
voice_laugh = zeros(NTSample,1);

% set up audio device writer
player = audioDeviceWriter('SampleRate',fs);

dftFileReader = dsp.AudioFileReader('SpeechDFT-16-8-mono-5secs.wav', ...
    'SamplesPerFrame',NSampPerFrame);
speechFileReader = dsp.AudioFileReader('FemaleSpeech-16-8-mono-3secs.wav', ...
    'SamplesPerFrame',NSampPerFrame);
laughterFileReader = dsp.AudioFileReader('Laughter-16-8-mono-4secs.wav', ...
    'SamplesPerFrame',NSampPerFrame);

% simulate
for m = 1:NSampPerFrame:NTSample
    sig_idx = m:m+NSampPerFrame-1;
    x1 = dftFileReader();
    x2 = speechFileReader();
    x3 = 2*laughterFileReader();
    temp = collector([x1 x2 x3], ...
        [ang_dft ang_cleanspeech ang_laughter]) + ...
        sqrt(noisePwr)*randn(NSampPerFrame,Nele);
    player(0.5*temp(:,3));
    sigArray(sig_idx,:) = temp;
    voice_dft(sig_idx) = x1;
    voice_cleanspeech(sig_idx) = x2;
    voice_laugh(sig_idx) = x3;
end

Заметьте, что смех маскирует речевые сигналы, делая их невразумительными. Постройте график сигнала в канале 3.

plot(t,sigArray(:,3));
xlabel('Time (sec)'); ylabel ('Amplitude (V)');
title('Signal Received at Channel 3'); ylim([-3 3]);

Процесс с задержкой по времени Beamformer

Блок формирования луча с временной задержкой компенсирует различия во времени прихода через массив для сигнала, поступающего с определенного направления. Согласованные по времени многоканальные сигналы когерентно усредняются, чтобы улучшить отношение сигнал/шум (ОСШ). Задайте угол управления, соответствующий направлению падения первого речевого сигнала, и создайте блок формирования луча задержки по времени.

angSteer = ang_dft;
beamformer = phased.TimeDelayBeamformer('SensorArray',ula, ...
    'SampleRate',fs,'Direction',angSteer,'PropagationSpeed',c)
beamformer = 

  phased.TimeDelayBeamformer with properties:

          SensorArray: [1x1 phased.ULA]
     PropagationSpeed: 340
           SampleRate: 8000
      DirectionSource: 'Property'
            Direction: [2x1 double]
    WeightsOutputPort: false

Обработайте синтезированный сигнал, затем постройте график и прослушайте выход обычного устройства формирования луча.

signalsource = dsp.SignalSource('Signal',sigArray, ...
    'SamplesPerFrame',NSampPerFrame);

cbfOut = zeros(NTSample,1);

for m = 1:NSampPerFrame:NTSample
    temp = beamformer(signalsource());
    player(temp);
    cbfOut(m:m+NSampPerFrame-1,:) = temp;
end

plot(t,cbfOut);
xlabel('Time (s)'); ylabel ('Amplitude');
title('Time Delay Beamformer Output'); ylim([-3 3]);

Можно измерить увеличение речи усилением массива, которое является отношением выхода сигнала к интерференции плюс шум (SINR) к входу SINR.

agCbf = pow2db(mean((voice_cleanspeech+voice_laugh).^2+noisePwr)/ ...
    mean((cbfOut - voice_dft).^2))
agCbf =

    9.5022

Заметьте, что первый речевой сигнал начинает появляться в выходе пучка задержки во времени. Вы получаете улучшение SINR на 9,4 дБ. Однако фоновый смех пока сопоставим с речью. Для получения более высокой эффективности лучевого форматора используйте лучевой форматор Frost.

Процесс с помощью морозообразующего луча

Путем присоединения конечных импульсных характеристик к каждому датчику, Frost beamformer имеет больше весов формирования луча, чтобы подавить помехи. Это адаптивный алгоритм, который помещает значения null в выученных интерференционных направлениях, чтобы лучше подавить интерференцию. В направлении рулевого управления светоформатор Frost использует ограничения без искажений, чтобы гарантировать, что требуемые сигналы не подавлены. Создайте Frost beamformer с 20-контактной конечной импульсной характеристикой после каждого датчика.

frostbeamformer = ...
    phased.FrostBeamformer('SensorArray',ula,'SampleRate',fs, ...
    'PropagationSpeed',c,'FilterLength',20,'DirectionSource','Input port');

Обработайте и воспроизведите синтезированный сигнал с помощью Frost beamformer.

reset(signalsource);
FrostOut = zeros(NTSample,1);
for m = 1:NSampPerFrame:NTSample
    temp = frostbeamformer(signalsource(),ang_dft);
    player(temp);
    FrostOut(m:m+NSampPerFrame-1,:) = temp;
end

plot(t,FrostOut);
xlabel('Time (sec)'); ylabel ('Amplitude (V)');
title('Frost Beamformer Output'); ylim([-3 3]);

% Calculate the array gain
agFrost = pow2db(mean((voice_cleanspeech+voice_laugh).^2+noisePwr)/ ...
    mean((FrostOut - voice_dft).^2))
agFrost =

   14.4385

Заметьте, что пересечение теперь отменено. Коэффициент усиления луча Фроста массива 14,5 дБ, что примерно на 5 дБ выше, чем коэффициент усиления луча с временной задержкой. Повышение эффективности впечатляет, но имеет высокую вычислительную стоимость. В предыдущем примере для каждого микрофона используется конечная импульсная характеристика порядка 20. Со всеми 10 датчиками ему нужно инвертировать матрицу 200 на 200, которая может быть дорогой при обработке в реальном времени.

Используйте диагональную загрузку, чтобы улучшить робастность мороженого

Затем направьте массив в направлении второго речевого сигнала. Предположим, что вы знаете только приблизительную оценку азимута- 5 степеней и повышения 5 степеней для направления второго речевого сигнала.

release(frostbeamformer);
ang_cleanspeech_est = [-5; 5];  % Estimated steering direction

reset(signalsource);
FrostOut2 = zeros(NTSample,1);
for m = 1:NSampPerFrame:NTSample
    temp = frostbeamformer(signalsource(), ang_cleanspeech_est);
    player(temp);
    FrostOut2(m:m+NSampPerFrame-1,:) = temp;
end

plot(t,FrostOut2);
xlabel('Time (sec)'); ylabel ('Amplitude (V)');
title('Frost Beamformer Output');  ylim([-3 3]);

% Calculate the array gain
agFrost2 = pow2db(mean((voice_dft+voice_laugh).^2+noisePwr)/ ...
    mean((FrostOut2 - voice_cleanspeech).^2))
agFrost2 =

    6.1927

Речь едва слышна. Несмотря на коэффициент усиления в 6,1 дБ от лучевого форматора, эффективность страдает от неточного направления рулевого управления. Один из способов улучшить робастность лучевого форматора Frost относительно несоответствия направления прибытия - использовать диагональную загрузку. Этот подход добавляет небольшую величину к диагональным элементам предполагаемой ковариационной матрицы. Недостатком этого способа является то, что трудно оценить правильный коэффициент загрузки. Здесь вы пробуете диагональную загрузку со значением 1e-3.

% Specify diagonal loading value
release(frostbeamformer);
frostbeamformer.DiagonalLoadingFactor = 1e-3;

reset(signalsource);
FrostOut2_dl = zeros(NTSample,1);
for m = 1:NSampPerFrame:NTSample
    temp = frostbeamformer(signalsource(),ang_cleanspeech_est);
    player(temp);
    FrostOut2_dl(m:m+NSampPerFrame-1,:) = temp;
end

plot(t,FrostOut2_dl);
xlabel('Time (sec)'); ylabel ('Amplitude (V)');
title('Frost Beamformer Output');  ylim([-3 3]);

% Calculate the array gain
agFrost2_dl = pow2db(mean((voice_dft+voice_laugh).^2+noisePwr)/ ...
    mean((FrostOut2_dl - voice_cleanspeech).^2))
agFrost2_dl =

    6.4788

Выход речевой сигнал улучшен, и вы получаете улучшение усиления на 0,3 дБ от метода диагональной загрузки.

release(frostbeamformer);
release(signalsource);
release(player);

rng(prevS);

Сводные данные

Этот пример показывает, как использовать формирователи луча временного интервала для извлечения речевых сигналов от измерений шумного массива. Пример также показывает, как симулировать доминирующий по интерференциям сигнал, принятый массивом микрофонов. В примере использовали и задержку по времени, и лучевые форматоры Фроста и сравнивали их эффективность. Светоформатор Frost обладает лучшей способностью подавления помех. Пример также иллюстрирует использование диагональной загрузки для улучшения робастности Фрост-формирования луча.

Ссылка

[1] O. L. Frost III, Алгоритм для линейной обработки адаптивных массивов с ограничениями, Труды IEEE, Vol. 60, Number 8, Aug. 1972, pp. 925-935.