Этот пример показывает, как моделировать цифровое аудио многополосная система сжатия динамического диапазона.
Сжатие динамического диапазона уменьшает динамический диапазон сигнала путем ослабления уровня сильного peaks при оставлении более слабого peaks без изменений. Сжатие имеет приложения в аудиозаписи, смешивании, и в широковещательной передаче.
Многополосное сжатие сжимает различные полосы звуковой частоты отдельно первым разделением звукового сигнала в несколько полос и затем передачи каждой полосы через ее собственный независимо корректируемый компрессор. Многополосное сжатие широко используется в аудио мастеринге и часто включается в аудио рабочие станции.
Многополосный компрессор в этом примере сначала разделяет звуковой сигнал в различные полосы, использующие многополосный перекрестный фильтр. Linkwitz-раздраженные перекрестные фильтры используются, чтобы получить полную allpass частотную характеристику. Каждая полоса затем сжата с помощью отдельного компрессора динамического диапазона. Ключевые характеристики компрессора, такие как коэффициент сжатия, время нападения и релиза, порог и ширина колена, являются независимо настраиваемыми для каждой полосы. Эффект сжатия на динамическом диапазоне сигнала продемонстрирован.
Linkwitz-раздраженный перекрестный фильтр состоит из комбинации lowpass и фильтра highpass, каждый сформированный путем расположения каскадом двух lowpass или highpass Фильтров Баттерворта. Подведение итогов ответа двух фильтров приводит к усилению 0 дБ на перекрестной частоте, так, чтобы перекрестное соединение действовало как фильтр allpass (и поэтому вводящий искажение в звуковом сигнале).
crossoverFilter может использоваться, чтобы реализовать Linkwitz-раздраженный Системный объект. Поскольку Linkwitz-раздраженный перекрестный фильтр формируется путем расположения каскадом двух Фильтров Баттерворта, его порядок всегда ровен. Наклон Фильтра Баттерворта равен 6*N дБ/октава, где N является порядком фильтра. Когда свойство CrossoverSlopes crossoverFilter является делимым 12 (т.е. фильтр даже упорядочен), объект реализует Linkwitz-раздраженное перекрестное соединение. В противном случае объект реализует перекрестное соединение Баттерворта, где lowpass и разделы highpass каждый реализованы с помощью одного Фильтра Баттерворта или порядка CrossoverSlopes/6, соответственно.
Вот пример, где четвертый порядок Linkwitz-раздраженное перекрестное соединение используется, чтобы отфильтровать сигнал. Заметьте, что lowpass и highpass разделяют, у каждого есть-6 усилений дБ на перекрестной частоте. Сумма lowpass и разделов highpass является allpass.
Fs = 44100; % Linkwitz-Riley filter crossover = crossoverFilter(1,5000,4*6,Fs); % Transfer function estimator transferFuncEstimator = dsp.TransferFunctionEstimator( ... 'FrequencyRange','onesided','SpectralAverages',20); frameLength = 1024; scope = dsp.ArrayPlot( ... 'PlotType','Line', ... 'YLimits',[-40 1], ... 'YLabel','Magnitude (dB)', ... 'XScale','log', ... 'SampleIncrement',(Fs/2)/(frameLength/2+1), ... 'XLabel','Frequency (Hz)', ... 'Title','Eighth order Linkwitz-Riley Crossover Filter', ... 'ShowLegend',true, ... 'ChannelNames',{'Band 1','Band 2','Sum'}); tic; while toc < 10 in = randn(1024,1); % Return lowpass and highpass responses of the crossover filter [ylp,yhp] = crossover(in); % sum the responses y = ylp + yhp; v = transferFuncEstimator(repmat(in,1,3),[ylp yhp y]); scope(20*log10(abs(v))); end
crossoverFilter может также использоваться, чтобы реализовать многополосный перекрестный фильтр путем объединения фильтров перекрестного соединения 2D полосы, и allpass просачивается древовидная структура. Фильтр делит спектр на несколько полос, таким образом, что их сумма является совершенным фильтром allpass.
Пример ниже показов перекрестный фильтр с четырьмя полосами, сформированный из четвертого порядка Linkwitz-раздраженные перекрестные фильтры. Заметьте allpass ответ суммы этих четырех полос.
Fs = 44100; crossover = crossoverFilter(3,[2e3 5e3 10e3],[24 24 24],44100); transferFuncEstimator = dsp.TransferFunctionEstimator... ('FrequencyRange','onesided',... 'SpectralAverages',20); L = 2^14; scope = dsp.ArrayPlot( ... 'PlotType','Line', ... 'XOffset',0, ... 'YLimits',[-120 5], ... 'XScale','log', ... 'SampleIncrement', .5 * Fs/(L/2 + 1 ), ... 'YLabel','Frequency Response (dB)', ... 'XLabel','Frequency (Hz)', ... 'Title','Four-Band Crossover Filter', ... 'ShowLegend',true, ... 'ChannelNames',{'Band 1','Band 2','Band 3','Band 4','Sum'}); tic; while toc < 10 in = randn(L,1); % Split the signal into four bands [ylp,ybp1,ybp2,yhp] = crossover(in); y = ylp + ybp1 + ybp2 + yhp; z = transferFuncEstimator(repmat(in,1,5),[ylp,ybp1,ybp2,yhp,y]); scope(20*log10(abs(z))) end
компрессором является Системный объект компрессора динамического диапазона. Входной сигнал сжат, когда он превышает заданный порог. Объемом сжатия управляет заданный коэффициент сжатия. Времена нападения и релиза определяют, как быстро компрессор запускает или прекращает сжиматься. Ширина колена обеспечивает плавный переход для усиления компрессора вокруг порога. Наконец, усиление состава может быть применено при выводе компрессора. Это усиление состава усиливает и сильный и слабый peaks одинаково.
Статическая характеристика сжатия компрессора зависит от коэффициента сжатия, порога и ширины колена. Пример ниже иллюстрирует статическую характеристику сжатия для твердого колена:
drc = compressor(-15,5); visualize(drc);
В порядке просмотреть эффект порога, отношения и ширины колена на статической характеристике компрессора, изменяют значения Порога, свойств Ratio и KneeWidth. График статической характеристики должен измениться соответственно.
Время атаки компрессора задано как время (в msec), это берет для усиления компрессора, чтобы повыситься с 10% до 90% его окончательного значения, когда уровень сигнала превышает порог. Время релиза компрессора задано как время (в секундах), это берет усиление компрессора, чтобы понизиться с 90% до 10% его значения, когда уровень сигнала опускается ниже порога. Пример ниже иллюстрирует конверт сигнала для различного релиза и время атаки:
Fs = 44100; % Sample rate drc = compressor(-10,5, ... 'SampleRate',Fs, ... 'AttackTime',0.050, ... 'ReleaseTime',0.200, ... 'MakeUpGainMode','Property'); x = [ones(Fs,1);0.1*ones(Fs,1)]; [y,g] = drc(x); t = (1/Fs) * (0: 2*Fs - 1); figure subplot(211) plot(t,x); hold on; grid on; plot(t,y,'r') ylabel('Amplitude') legend('Input','Compressed Output') subplot(212) plot(t,g) grid on legend('Compressor gain (dB)') xlabel('Time (sec)') ylabel('Gain (dB)')
Входной максимальный уровень составляет 0 дБ, который является выше заданного порога на-10 дБ. Установившийся компрессор вывод для входа на 0 дБ-10 + 10/5 =-8 дБ. Усиление - поэтому-8 дБ. Время атаки задано как время, это берет усиление компрессора, чтобы повыситься с 10% до 90% его окончательного значения, когда уровень на входе выходит за предел порога, или в этом случае, от-0.8 дБ до-7.2 дБ. Давайте найдем времена, в которые усиления на этапе сжатия равны-0.8 дБ и-7.2 дБ, соответственно:
[~,t1] = min(abs(g(1:Fs) + 0.1 * 8));
[~,t2] = min(abs(g(1:Fs) + 0.9 * 8));
tAttack = (t2 - t1) / Fs;
fprintf('Attack time is %d s\n',tAttack)
Attack time is 5.000000e-02 s
Входной сигнал затем роняет вниз к 0, где нет никакого сжатия. Время релиза задано как время, которое оно берет усиление, чтобы пропустить с 90% до 10% его абсолютного значения, когда вход понижается порог, или в этом случае,-7.2 дБ к-0.8 дБ. Давайте найдем времена, в которые усиления на этапе без сжатий равны-7.2 дБ и-0.8 дБ, соответственно:
[~,t1] = min(abs(g(Fs:end) + 0.9 * 8));
[~,t2] = min(abs(g(Fs:end) + 0.1 * 8));
tRelease = (t2 - t1) / Fs;
fprintf('Release time is %d s\n',tRelease)
Release time is 2.000000e-01 s
Пример ниже иллюстрирует эффект сжатия динамического диапазона на звуковом сигнале. Порог сжатия устанавливается к-15 дБ, и коэффициент сжатия равняется 7.
frameLength = 1024; reader = dsp.AudioFileReader('Filename', ... 'RockGuitar-16-44p1-stereo-72secs.wav', ... 'SamplesPerFrame',frameLength); % Compressor. Threshold = -15 dB, ratio = 7 drc = compressor(-15,7, ... 'SampleRate',reader.SampleRate, ... 'MakeUpGainMode','Property', ... 'KneeWidth',5); scope = dsp.TimeScope('SampleRate',reader.SampleRate, ... 'TimeSpan',1,'BufferLength',44100*4, ... 'ShowGrid',true, ... 'LayoutDimensions',[2 1], ... 'NumInputPorts',2, ... 'TimeSpanOverrunAction','Scroll'); scope.ActiveDisplay = 1; scope.YLimits = [-1 1]; scope.ShowLegend = true; scope.ChannelNames = {'Original versus compressed audio'}; scope.ActiveDisplay = 2; scope.YLimits = [-6 0]; scope.YLabel = 'Gain (dB)'; scope.ShowLegend = true; scope.ChannelNames = {'compressor gain in dB'}; while ~isDone(reader) x = reader(); [y,g] = drc(x); x1 = x(:,1); y1 = y(:,1); scope([x1,y1],g(:,1)) end
Следующая модель реализует многополосный пример сжатия динамического диапазона:
model = 'audiomultibanddynamiccompression';
open_system(model)
В этом примере звуковой сигнал сначала разделен на четыре полосы, использующие многополосный перекрестный фильтр. Каждая полоса сжата с помощью отдельного компрессора. Эти четыре полосы затем повторно объединены, чтобы сформировать аудиовыход. Динамический диапазон несжатых и сжатых сигналов (заданный как отношение самого большого абсолютного значения сигнала к RMS сигнала) вычисляется. Чтобы услышать различие между исходными и сжатыми звуковыми сигналами, переключите переключатель на верхнем уровне.
Модель интегрирует Пользовательский интерфейс (UI), разработанный, чтобы взаимодействовать с симуляцией. Пользовательский интерфейс позволяет вам настройкам параметров, и результаты отражаются в симуляции немедленно. Чтобы запустить пользовательский интерфейс, который управляет симуляцией, щелкните по ссылке 'Launch Parameter Tuning UI' на модель.
set_param(model,'StopTime','(1/44100) * 8192 * 20'); sim(model);
Закройте модель:
bdclose(model)
HelperMultibandCompressionSim
является функция MATLAB, содержащая многополосную реализацию примера сжатия динамического диапазона. Это инстанцирует, инициализирует и продвигается через объекты, формирующие алгоритм.
Функциональный multibandAudioCompressionExampleApp
переносит HelperMultibandCompressionSim
и итеративно вызывает его. Это также строит несжатое по сравнению со сжатыми звуковыми сигналами. Графический вывод происходит, когда вход plotResults
к функции 'верен'.
Выполните multibandAudioCompressionExampleApp
, чтобы запустить симуляцию и построить результаты на осциллографах. Обратите внимание на то, что симуляция запускается столько, сколько пользователь явным образом не останавливает ее.
multibandAudioCompressionExampleApp
запускает пользовательский интерфейс, разработанный, чтобы взаимодействовать с симуляцией. Пользовательский интерфейс позволяет вам настройкам параметров, и результаты отражаются в симуляции немедленно. Для получения дополнительной информации о пользовательском интерфейсе обратитесь к HelperCreateParamTuningUI
.
MATLAB Coder может использоваться, чтобы сгенерировать код С для функционального HelperMultibandCompressionSim
. В порядке сгенерировать файл MEX для вашей платформы, выполните HelperMultibandCompressionCodeGeneration
.
Путем вызывания функции обертки multibandAudioCompressionExampleApp
с 'true'
в качестве аргумента сгенерированный файл MEX может использоваться вместо HelperMultibandCompressionSim
для симуляции. В этом сценарии пользовательский интерфейс все еще запускается в среде MATLAB, но основной алгоритм обработки выполняется файлом MEX. Производительность улучшается в этом режиме, не ставя под угрозу способность к настройкам параметров.
Вызовите multibandAudioCompressionExampleApp(true)
, чтобы использовать файл MEX для симуляции. Снова, выполнения симуляции, пока пользователь явным образом не останавливает его от пользовательского интерфейса.