exponenta event banner

Акустическое формирование луча с помощью микрофонной решетки

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

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

Определение однородного линейного массива

Сначала мы определяем однородную линейную матрицу (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.

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

Формирователь луча временной задержки компенсирует разности времени прихода по матрице для сигнала, поступающего из конкретного направления. Синхронизированные по времени многоканальные сигналы когерентно усредняются для улучшения отношения сигнал/шум (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

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

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.

Процесс с помощью формирователя морозного луча

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

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

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

Обратите внимание, что пересечение теперь отменено. Формирователь луча Frost имеет коэффициент усиления матрицы 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] О. Л. Фрост III, Алгоритм линейной адаптивной обработки массива с ограничением, Proceedings of the IEEE, Vol. 60, Number 8, Aug. 1972, pp. 925-935.