Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

практика научная / Практика_отчёт_БИК2205

.pdf
Скачиваний:
0
Добавлен:
13.05.2026
Размер:
753.25 Кб
Скачать

На функциональной схеме модели изображен алгоритм загрузки и обработки аудиофайла. На схеме отсутствуют функции, которые не влияют напрямую на функционал модели, однако делают ввод и вывод данных более дружелюбным к пользователю. Эти функции будут описаны в этом разделе ниже, после «основных».

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

Далее с помощью функции «lbrs_load()» библиотеки «librosa» осуществляется загрузка указанного аудиофайла для дальнейшей работы. Функция

«lbrs_load()» загружает файл в виде массива со значениями амплитуды каждого отсчёта, размерности (<колво_отсчётов>x<количество_каналов>),

возвращая описанный массив, а также частоту дискретизации.

В рамках модели аудиофайл загружается в стерео режиме с частотой дискретизации 44100 Гц и 8-ю байтами на хранение значения амплитуды каждого отсчёта.

После задаются необходимые диапазоны частот для цифровых фильтров, а

также необходимые количества байт на хранение амплитуд отсчётов каждого диапазона.

В рамках модели, это 1 Гц – 5500 Гц, 5501 Гц – 11000 Гц, 11001 Гц – 16500 Гц,

16501 – 22000 Гц и 8, 4, 2, 2 соответственно;

Фильтрация загруженного аудиофайла по заданным диапазонам осуществляется в цикле с помощью функции «filtration()», которая по заданным параметрам синтезирует цифровой полосовой фильтр и

«пропускает» сигнал через синтезированный фильтр, возвращая фильтрованный сигнал. Синтез фильтра осуществляется с помощью функций

«kaiserord()» – рассчитывает порядок фильтра и параметр Кайзера – «firwin()»

– рассчитывает коэффициенты полосового КИХ-фильтра с окном Кайзера по

10

полученным параметрам – библиотеки «scipy.signal». Фильтрация осуществляется с помощью функции «lfiilter()» – применяет фильтр с указанными коэффициентами к полученному сигналу – той же библиотеки.

После этого, так как фильтр не способен полностью занулить сигнал,

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

В рамках модели, помимо диапазонов частот, используются следующие параметры при синтезе фильтров: частота Найквиста равна 22050 Гц, ширина переходной зоны равна 5/22050 Гц, ослабление вне зоны пропускания равно

15 дБ.

После фильтрации четыре полученных сигнала объединяются в один с помощью функции «signal_mixing()», которая, посимвольно сравнивая все четыре сигнала, «выцепляет» из них ненулевое значение амплитуды отсчёта,

ограничивает количество байт на хранение значения амплитуды найденного отсчёта в соответствии с принадлежностью отсчёта одному из диапазонов, и

записывает обработанный отсчёт в новый массив, сохраняя очерёдность следования отсчётов. На выходе функции получается один массив отсчётов,

значения амплитуд которых занимают разный объём памяти.

Далее микшированное аудио поступает на кодер – функцию «encoder()»,

которая осуществляет разностное кодирование: вместо амплитуд отсчётов,

кодер сохраняет лишь разность между амплитудами текущего и предыдущего отсчётов. В качестве «опорного» отсчёта используется первый поступивший в кодер.

Кодированный сигнал поступает на кодер – функцию «decoder()», которая выполняет обратную операцию: вместо разности между амплитудами, декодер возвращает значения амплитуд отсчётов. В качестве «опорной» разности используется первая поступившая в декодер.

11

После этого из итогового обработанного сигнала, с помощью функции

«show_waveform()», формируются графики волнового представления сигнала.

Непосредственное формирование графиков осуществляется с помощью функции «waveshow()» библиотеки «librosa». Функция «show_waveform()» же позволяет пользователю указывать дополнительные параметры графика:

номер графика, заголовок графика, а также формировать легенду к графикам.

В конце работы модели пользователю поступает запрос на вывод получившихся аудио в файл. По согласию, фильтрованное или итоговое аудио выводится в файл с помощью функции «sf_write()» библиотеки «soundfile».

Вывод осуществляется в формате .wav способом PCM(ИКМ) c разрядностью

16 бит.

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

Ввод и вывод текстовой информации осуществляется с помощью библиотеки

«curses» и её встроенных функций.

Функция «init_cnvs()» переводит окно консоли в режим ввода/вывода информации, убирает отображение курсора и отображает рамку по краям окна консоли;

Функция «draw_text()» выводит в окно консоли указанный текст;

Функция «get_text()» осуществляет ввод информации, в виде строки,

которой пользователь ввёл с клавиатуры;

Функция «get_char()» осуществляет ввод информации, в виде одного символа, которой пользователь ввёл с клавиатуры.

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

а также запрашиваются у пользователя и считываются различные данные.

12

3.3 ПОДБОР ВХОДНЫХ И ВЫХОДНЫХ ДАННЫХ

ДЛЯ МОДЕЛИ

В качестве входных данных для модели используются любые аудиофайлы расширения .wav, длительностью более одной секунды. Это обусловлено тем, при передаче по радиоканалу, передающее устройство работает сразу с декомпрессованным аудиопотоком (декомпрессия производится внешним источником), для встраивания в аудиопоток дополнительной информации (например, звуков уведомлений). Поэтому модуль работает с аудиофайлами без сжатия, чтобы сымитировать принятие потока данных от внешнего источника. Длительность более одной секунды обусловлена тем, что частота дискретизации модели установлена на 44100 Гц,

как наиболее часто распространённая, то есть в одной секунде присутствует

44100 отсчётов. Уменьшение этого количества отсчёта (длительности аудиофайла меньше одной секунды) может привести к нестабильной работе модели.

3.4 ВИЗУАЛИЗАЦИЯ РЕЗУЛЬТАТОВ РАБОТЫ

МОДЕЛИ

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

аудио после кодирования и декодирования, а также исходного и фильтрованного аудио на одном графике.

13

Рисунок 3.4.1 – Волновое представление исходного аудио

Рисунок 3.4.2 – Волновое представление аудио после фильтрации и микширования

14

Рисунок 3.4.3 – Волновое представление аудио после кодирования и декодирования

Рисунок 3.4.4 – Волновое представление исходного и фильтрованного аудио, наложенные друг на друга

15

3.5 ВЫВОДЫ ПО РЕЗУЛЬТАТАМ ИССЛЕДОВАНИЯ

По результатам работы модели установлено, что выбранный метод

обладает следующими достоинствами и недостатками:

Метод является очень простым для кодирования и декодирования с математической точки зрения, что обеспечивает достаточно быстрое кодирование-декодирование;

Несмотря на быстрое и простое кодирование-декодирование,

предположительное использование полосовых фильтров в качестве разделения сигнала на частотные диапазоны, сильно (до 10 раз)

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

Применение адаптивного кодирование в методе позволяет сократить затраты памяти, необходимые на хранение информации а аудиофайле,

при этом из-за разностного кодирования-декодирования, погрешности при декодировании настолько малы, что ими можно пренебречь;

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

16

4СПИСОК ЛИТЕРАТУРЫ

1.VladikSS. Аудио через Bluetooth: максимально подробно о профилях,

кодеках и устройствах / VladikSS. – Текст: электронный // Хабр. – URL: https://habr.com/en/articles/427997/ (дата обращения: 08.06.2024).

2.Hoene Christian. Technical Report: Considering Bluetooth’s Subband

Codec (SBC) for Wideband Speech and Audio on the Internet / Christian Hoene, Mansoor Hyder. – D-72076 Tübingen, Germany: Interactive Communication Systems Wilhelm-Schickard-Institut Universtiät Tübingen, October 2009. – 47 с. – ISSN 0946-3852.

3.Johansson Gustav. Bachelor Degree Project in Information Technology: Bluetooth audio codecs in a real-time interactive context / Gustav Johansson, Mattias Adeväg, Jacob Milton. – Skövde, Sweden: University of Skövde, spring 2023. – 52 с.

4.Дорошев, Д.В. Импульсно-кодовая модуляция для кодирования звука /

Д.В. Дорошев. – Гомель, Беларусь: Гомельский государственный технический университет имени П.О. Сухого. – 4 с.

5.Неизвестный автор. Тема 2.3. Дифференциальная ИКМ / Неизвестный автор. – Текст: электронный // Интернет-портал narod.ru. – URL: https://tss-vosp.narod.ru/csp/zan/z09/z09v00.htm (дата обращения:

09.06.2024).

6.Robert Triggs. aptX and aptX HD: Bluetooth audio codecs explained / Robbert Triggs. – Текст: электронный // SOUNDGUYS. – URL: https://www.soundguys.com/understanding-bluetooth-codecs-15352/ (дата обращения: 09.06.2024).

17

5ПРИЛОЖЕНИЕ

5.1ИСХОДНЫЙ КОД ПРОГРАММЫ

1.from scipy.signal import firwin, lfilter, kaiserord #type: ignore

2.from soundfile import write as sf_write #type: ignore

3.from librosa import load as lbrs_load

4.from librosa.display import waveshow

5.from matplotlib import pyplot as plt #type: ignore

6.from time import perf_counter_ns

7.from os.path import isfile

8.import numpy.typing as npt

9.import typing as typ

10.import numpy as np

11.import curses #type: ignore

12.

13.#Функция подготовки окна консоли к использованию

14.def init_cnvs(canvas):

15.win = curses.initscr()

16.curses.curs_set(0)

17.canvas.border()

18.canvas.refresh()

19.return win

20.

21.#Отрисовка текста на экране в выбранной позиции

22.def draw_text(canvas,r: int,c: int,text: str) -> None:

23.canvas.addstr(r,c,text)

24.canvas.refresh()

25.curses.napms(500)

26.

27.#Считывание строки, введённой пользователем

28.def get_text(canvas,r: int, c: int) -> str:

29.curses.curs_set(1)

30.canvas.refresh()

31.text: str = canvas.getstr(r,c)

32.curses.curs_set(0)

33.canvas.border()

34.canvas.refresh()

35.curses.flushinp()

36.return text

37.

38.#Считывание символа, введённого пользователем

39.def get_char(canvas,r: int, c: int) -> str:

40.curses.curs_set(1)

41.canvas.refresh()

42.char: str = canvas.getkey(r,c)

43.curses.curs_set(0)

44.canvas.border()

45.canvas.refresh()

18

46.curses.flushinp()

47.return char

48.

49.#Фильтрация

50.def filtration(samples: npt.NDArray,sr: float,cutoff_hz: typ.Tuple[int,int],bts: npt.DTypeLike) -> npt.NDArray:

51.nyq_rate: float = sr/2.0 #Частота Найквиста

52.trans_width: float = 5.0/nyq_rate #Ширина перехдной зоны

53.ripple_db: float = 15.0 #Величина затухание вне области пропускания

54.N, beta = kaiserord(ripple_db, trans_width) #Порядок и параметр Кайзера

55. filter_coeffs: npt.NDArray = firwin(N,cutoff_hz,window=('kaiser',beta),pass_zero='bandpass',fs

=sr) #Получение коэффициентов фильтра

56.

filtered_samples:

npt.NDArray

=

lfilter(filter_coeffs,1.0,samples,axis=1) #Фильтрация

 

57.filtered_samples[0][abs(filtered_samples[0])<=1/((ripple _db/10)**10)] = 0 #Фильтрация по затуханию

58.filtered_samples[1][abs(filtered_samples[1])<=1/((ripple _db/10)**10)] = 0 #Фильтрация по затуханию

59.filtered_samples = filtered_samples.astype(bts)

60.return filtered_samples

61.

62.#Сведение всех отфильтрованных сигналов в один

63.def signal_mixing(f_samples: typ.List[npt.NDArray]) -> typ.List[typ.List]:

64.counter: int = 0

65.mixed_signal: typ.List[typ.List] = [[],[]]

66.while counter != len(f_samples[0][0]):

67.

if f_samples[0][0][counter] != 0:

68.

#

69.

mixed_signal[0].append(f_samples[0][0][counter])

70.

mixed_signal[1].append(f_samples[0][1][counter])

71.

#

72.

elif f_samples[1][0][counter] != 0:

73.

#

74.

mixed_signal[0].append(f_samples[1][0][counter])

75.

mixed_signal[1].append(f_samples[1][1][counter])

76.

#

77.

elif f_samples[2][0][counter] != 0:

78.

#

79.

mixed_signal[0].append(f_samples[2][0][counter])

80.

mixed_signal[1].append(f_samples[2][1][counter])

81.

#

82.

else:

83.

#

84.

mixed_signal[0].append(f_samples[3][0][counter])

85.

mixed_signal[1].append(f_samples[3][1][counter])

86.

#

87.

counter += 1

 

19

Соседние файлы в папке практика научная