BMSTU/02-dspmd-03-hw-report.tex

173 lines
13 KiB
TeX
Raw Permalink Normal View History

2023-01-27 22:32:16 +03:00
\documentclass[a4paper,fontsize=14bp]{article}
\input{../common-preamble}
\input{../bmstu-preamble}
\input{../fancy-listings-preamble}
\numerationBottom
\newcolumntype{s}{>{\tiny{}}c}
\begin{document}
\thispagestyle{empty}
\makeBMSTUHeader
\makeReportTitle{домашней}{3}{Звуковой эффект}{Микропроцессорные устройства обработки сигналов}{}{проф. каф. ИУЗ, д.т.н. \\В.С. Выхованец}
\newpage
\thispagestyle{empty}
\tableofcontents
\addtocontents{toc}{\vspace{2ex}}
\newpage
\pagestyle{fancy}
\section{Постановка задачи}
Целью домашнего задания является разработка алгоритма звукового эффекта «Контроллер динамического диапазона». Для выполнения домашнего задания необходимо:
\begin{itemize}
\item ознакомиться с рекомендованной литературой \cite{dsp:lectures};
\item привести в отчете описание звукового эффекта;
\item описать алгоритм обработки сигналов и данных.
\end{itemize}
При разработке алгоритма необходимо учесть, что исходный звуковой сигнал поступает на обработку от звукового кодека по одному отсчету, получаемому при вызове функции \code{sam = GetSample()}, где \code{sam} текущий входной отсчет звукового сигнала в формате с фиксированной запятой. Обработанные отсчеты передаются звуковому кодеку обратно путем вызова функции \code{PutSample(res)}, где \code{res} текущий выходной отсчет звукового сигнала в формате с фиксированной запятой.
\section{Выполнение}
\subsection{Описание звукового эффекта}
Контроллер динамического диапазона - это адаптивная регулировка динамического диапазона сигнала. Динамический диапазон - это соотношение между наибольшими и наименьшими значениями, которые может принять определенная величина. Существует несколько типов контроллеров. В данной лабораторной работе будет рассматриваться ограничитель. Назначение ограничителя состоит в том, чтобы обеспечить контроль над самыми высокими пиками сигнала, но при этом, как можно меньше изменять динамику сигнала. Это достигается за счёт использования характеристической кривой с бесконечным отношением \cite[с. 109]{dsp:dafx}. Ограничитель динамического диапазона подавляет громкость звуков, пересекающих заданный порог (рисунок \hrf{pic:limiter}).
\begin{figure}[H]
\captionsetup{labelsep=endash}
\centering
\def\svgwidth{100mm}
\input{pics/02-dsp-03lab-limiter.pdf_tex}
\caption{Иллюстрация работы ограничителя сигнала}
\label{pic:limiter}
\end{figure}
Для достижения плавности кривой применяемого ослабления громкости используются такие параметры, как время атаки и высвобождения. Время атаки и время высвобождения соответствуют времени, за которое сигнал увеличивается или уменьшается до конечного значения (рисунок \hrf{pic:limiter-explain}). На рисунке видно, что при отсутствии времени атаки и освобождения усиление применяется сразу, создавая неплавные «обрезанные» кривые (жёсткое урезание).
\begin{figure}[H]
\captionsetup{labelsep=endash}
\centering
\def\svgwidth{170mm}
\input{pics/02-dsp-03lab-limiter-explain.pdf_tex}
\caption{Иллюстрация влияния времени атаки и освобождения}
\label{pic:limiter-explain}
\end{figure}
Ограничитель обычно используется для того, чтобы «поймать» самые громкие моменты источника, уменьшив их таким образом, чтобы защитить от нежелательных искажений и сохранить целостность общего баланса звука.
\subsection{Математическое описание ограничителя}
\label{sect:description}
Динамическая обработка выполняется усилительными устройствами, где коэффициент усиления автоматически регулируется уровнем входного сигнала. Динамическая обработка проходит в несколько этапов:
\begin{enumerate}[label=\arabic*),ref=\arabic*]
\item Сначала используется схема определения амплитуды/уровня по алгоритму PEAK \cite[с. 107]{dsp:dafx}.
В начале алгоритма значение переменной $X_{peak}$ равно нулю. Далее сравнивается модуль поступающего сигнала $|x(n)|$ с предыдущим значением $X_{peak}$. В случае если значение модуля поступающего сигнала больше, то значение $X_{peak}$ для текущего элемента вычисляется с использованием коэффициента $AT$, которое используется, как сокращение для времени атаки (attack time). В ином случае вычисление значения $X_{peak}$ для текущего элемента производится с помощью коэффициента $RT$, то есть времени освобождения (release time). Математическая формула описанного выше алгоритма
\begin{equation}
X_{p}(n) = \begin{cases}
(1 - AT) \times X_{p}(n - 1) + AT \times |X(n)|, |X(n)| > X_{p}(n - 1)\\
(1 - RT) \times X_{p}(n - 1), |X(n)| \leq X_{p}(n - 1),
\end{cases}
\end{equation}
где $X_{p}$ - пиковое значение $X_{peak}$, $AT$ время атаки, $RT$ время освобождения, $n$ номер текущего элемента.
\item После определения значения $X_{peak}$ выполняется функция для получения коэффициента усиления $f$ по формуле
\begin{equation}
f(n) = min \bigg( 1; \frac{lt}{X_{peak}n} \bigg),
\end{equation}
где $n$ номер текущего элемента, $lt$ пороговое значение.
\item После вычисления коэффициента усиления используется сглаживающий фильтр для предотвращения слишком резких изменений усиления. Для его реализации используется формула
\begin{equation}
cfc = \begin{cases}
AT, f(n) < f(n-1)\\
RT, f(n) \geq f(n-1),
\end{cases}
\end{equation}
где $n$ номер текущего элемента.
\item Далее вычисляется множитель для регулирования входного сигнала по формуле
\begin{equation}
g(n) = (1 - cfc) \times g(n - 1) + cfc \times f(n)
\end{equation}
\item После получения искомого множителя входного сигнала, его значение умножается на задержанный в буфере задержки входной сигнал. Сигнал задерживается для того, чтобы компенсировалась любая задержка при вычислении множителя \cite[с. 106]{dsp:dafx}.
\end{enumerate}
Результирующая комбинированная система, схематично демонстрирующая все шаги преобразования, изображена на рисунке \hrf{pic:limiter-scheme} \cite[с. 109]{dsp:dafx}.
\begin{figure}[H]
\captionsetup{labelsep=endash}
\centering
\def\svgwidth{165mm}
\input{pics/02-dsp-03lab-limiter-scheme.pdf_tex}
\caption{Принципиальная схема алгоритма работы ограничителя}
\label{pic:limiter-scheme}
\end{figure}
\subsection{Алгоритм обработки сигналов}
Алгоритм реализован на основе раздела \hrf{sect:description}. Основная реализующая алгоритм функция приведена в приложении \hrf{appendix:dyn-control-func}.
На вход алгоритма принимается массив с отсчетами. Пороговое значение задаётся константой \code{LT} в теле функции.
\subsubsection{Основная программа \code{main}}
Функция \code{main} вызывается при запуске программы и реализует следующие шаги:
\begin{enumerate}[label=\arabic*),ref=\arabic*]
\item Инициализация кодека;
\item Чтение из кодека текущего отсчета сигнала;
\item Получение выходного отсчета сигнала;
\item Переход на шаг 2.
\end{enumerate}
\subsubsection{Функция ограничителя \code{dynDiaCtrl}}
Функция ограничителя получает в качестве аргумента текуший отсчет \code{х} и возвращает его модифицированное значение \code{у}. Функция реализует следующие шаги алгоритма.
\begin{enumerate}[label=\arabic*),ref=\arabic*]
\item Получение модуля входного значения;
\item Определение коэффициента для вычисления уровня;
\item Вычисление уровня;
\item Определение коэффициента усиления;
\item Определение коэффициента для вычисления управляющего коэффициента;
\item Запись выходного отсчета;
\item Возврат из функции.
\end{enumerate}
Функция использует математические функции из стандартной библиотеки для корректной работы с числами в формате с фиксированной запятой.
\section{Выводы}
В результате выполнения домашнего задания изучен звуковой эффект «Контроллер динамического диапазона», на примере ограничителя, для которого разработан и описан реализующий его алгоритм.
\nocite{gost:texts}
\newpage
\printbibliography[heading=bibintoc, title={Список литературы}, resetnumbers=1]
\newpage
\begin{appendices}
\renewcommand{\thesubsection}{\Asbuk{subsection}}
\subsection{Функция контроллера динамического диапазона}
\label{appendix:dyn-control-func}
\begin{lstlisting}[language=C,style=CCodeStyle]
volatile Int16 xpeak = 0;
volatile Int16 g = 1;
void dynDiaCtrl(Int16 *x, Int16 *y, Int16 nx) {
const Int16 at_cfc = 9830;
const Int16 rt_cfc = 328;
int i;
for (i = 0; i < nx; i++) {
// step 1
Int16 a = abs(x[i]);
xpeak = (a > xpeak)
? (_smpy((32767 - at_cfc), xpeak) + _smpy(at_cfc, a))
: _smpy((32767 - rt_cfc), xpeak);
// step 2
Int16 cmp = LT / xpeak;
Int16 f = (cmp < 1) ? cmp : 1;
// step 3
Int16 cfc = (f < g) ? at_cfc : rt_cfc;
// step 4
g = _smpy((1 - cfc), g) + _smpy(cfc, f);
y[i] = _smpy(g, x[i]);
}
\end{lstlisting}
\end{appendices}
\end{document}