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

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

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

Задайте универсальную линейную матрицу

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

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

Nele = 10;
ula = phased.ULA(Nele,0.05,'Element',microphone);
c = 340;                         % sound speed, 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; % noise power

Мы теперь запускаем симуляцию. При выводе полученный сигнал хранится в матрице с 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
audioWriter = audioDeviceWriter('SampleRate',fs, ...
        'SupportVariableSizeInput', true);
isAudioSupported = (length(getAudioDevices(audioWriter))>1);

dftFileReader = dsp.AudioFileReader('dft_voice_8kHz.wav',...
    'SamplesPerFrame',NSampPerFrame);
speechFileReader = dsp.AudioFileReader('cleanspeech_voice_8kHz.wav',...
    'SamplesPerFrame',NSampPerFrame);
laughterFileReader = dsp.AudioFileReader('laughter_8kHz.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);
    if isAudioSupported
        play(audioWriter,0.5*temp(:,3));
    end
    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]);

Процесс с формирователем луча с временной задержкой

Формирователь луча с временной задержкой компенсирует различия времени поступления через массив для сигнала, прибывающего из определенного направления. Время выровнялось, многоканальные сигналы когерентно усреднены, чтобы улучшить отношение сигнал-шум (SNR). Теперь, задайте держащийся угол, соответствующий инцидентному направлению первой речи, сигнализируют и создают формирователь луча с временной задержкой.

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

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

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

cbfOut = zeros(NTSample,1);

for m = 1:NSampPerFrame:NTSample
    temp = beamformer(signalsource());
    if isAudioSupported
        play(audioWriter,temp);
    end
    cbfOut(m:m+NSampPerFrame-1,:) = temp;
end

plot(t,cbfOut);
xlabel('Time (Sec)'); ylabel ('Amplitude (V)');
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 дБ. Однако фоновый смех все еще сопоставим с речью. Чтобы получить лучшую производительность формирователя луча, используйте формирователь луча Фроста.

Процесс с формирователем луча мороза

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

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

Затем, обработайте синтезируемый сигнал с помощью формирователя луча Фроста.

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

Мы можем проигрывать и построить целый звуковой сигнал, если он обрабатывается.

if isAudioSupported
    play(audioWriter,FrostOut);
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 дБ, которое на 4,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
    FrostOut2(m:m+NSampPerFrame-1,:) = frostbeamformer(signalsource(),...
        ang_cleanspeech_est);
end

if isAudioSupported
    play(audioWriter,FrostOut2);
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 усилений дБ от формирователя луча, производительность страдает от неточного руководящего направления. Один способ улучшить робастность формирователя луча Фроста состоит в том, чтобы использовать диагональную загрузку. Этот подход добавляет небольшое количество в диагональные элементы предполагаемой ковариационной матрицы. Здесь мы используем диагональное значение 1e-3.

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

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

if isAudioSupported
    play(audioWriter,FrostOut2_dl);
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);
if isAudioSupported
    pause(3); % flush out AudioPlayer buffer
    release(audioWriter);
end
rng(prevS);

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

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

Ссылка

[1] О. Л. Фрост III, алгоритм для линейной ограниченной адаптивной обработки матриц, Продолжений IEEE, Издания 60, Номера 8, август 1972, стр 925-935.