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

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

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

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

Сначала зададим равномерный линейный массив (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]);

Figure contains an axes. The axes with title Signal Received at Channel 3 contains an object of type line.

Процесс с задержкой по времени 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());
    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]);

Figure contains an axes. The axes with title Time Delay Beamformer Output contains an object of type line.

Можно измерить увеличение речи усилением массива, которое является отношением выхода сигнала к интерференции плюс шум (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
    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]);

Figure contains an axes. The axes with title Frost Beamformer Output contains an object of type line.

% 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]);

Figure contains an axes. The axes with title Frost Beamformer Output contains an object of type line.

% 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
    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]);

Figure contains an axes. The axes with title Frost Beamformer Output contains an object of type line.

% 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);

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

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

Ссылка

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