Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
6 семестр / course / Пояснительная записка.docx
Скачиваний:
2
Добавлен:
18.02.2023
Размер:
154.98 Кб
Скачать

3 Программная реализация

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

3.1 Детальная реализация функциональных частей по

Для начала подключим функцию обратного вызова к потоку аудио ввода. Для этого необходимо указать следующие параметры:

  • samplerate – частота дискретизации;

  • device – идентификатор аудиоустройства в системе;

  • channels – количество каналов для записи;

  • callback – имя функция обратного вызова для обработки получаемых данных.

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

Листинг 3.1 – Задание параметров потока аудио ввода

  1. if samplerate is None:

  2. device_info = sd.query_devices(device, 'input')

  3. samplerate = int(device_info['default_samplerate'])

  4. with sd.InputStream(samplerate=samplerate, device=device,

  5. channels=channels, callback=callback):

  6. logging.info('Listening...')

  7. print('Listening...')

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

  • indata – аудиоданные;

  • frames – количество кадров;

  • time – словарь со следующими ключами: input_buffer_adc, current_time и output_buffer_dac_time (значения см. в документации PortAudio);

  • status – один из флагов обратного вызова (значения см. в документации PortAudio).

Данные будут сохраняться в очередь записи. Здесь необходимо предусмотреть задание времени записи, ограничение максимального времени записи и подсчет количества данных в очереди. Создадим для них глобальные переменные: timeout, max_timeout, qsize. Для запуска записи измерим уровень громкости и сравним с порогом акустопуска. Для порога акустопуска создадим глобальную переменную trigger.

Листинг 3.2 – Функция обратного вызова

  1. def callback(indata, frames, time, status):

  2. global timeout, max_timeout, qsize

  3. volume = numpy.linalg.norm(indata) * 100

  4. if volume > trigger:

  5. timeout = t.time() + record_seconds

  6. if max_timeout == 0:

  7. max_timeout = t.time() + max_record_seconds

  8. if t.time() < timeout and t.time() < max_timeout:

  9. q.put(indata.copy())

  10. qsize += 1

  11. else:

  12. timeout = 0

  13. max_timeout = 0

Теперь приступим к записи файлов. Проверив наличие данных в очереди для записи, убедимся в существовании папки с текущей датой, в которую будет записывать аудиофайлы. Если папка отсутствует – создаем. После этого создаем звуковой файл для чего необходимо указать следующие параметры:

  • path – путь к файлу, включая его имя и расширение;

  • mode – режим записи файла;

  • sfinfo – структура в которой задаются параметры аудио файла.

Проверяем время записи и наличие данных в очереди. Извлекаем данные из очереди и записываем в файл. Уменьшаем счетчик размера очереди. Процесс повторяется вновь при помощи цикла while.

Листинг 3.3 – Запись аудиофайла

  1. while True:

  2. if qsize > 0:

  3. now = dt.datetime.now()

  4. folder = now.strftime('%Y-%m-%d')

  5. if not os.path.isdir(folder)

  6. os.mkdir(folder)

  7. os.chdir(folder)

  8. filename = now.strftime('%Y-%m-%d %H-%M-%S.wav')

  9. with sf.SoundFile(filename, mode='x',

  10. samplerate=samplerate,

  11. channels=channels, subtype=subtype) as file:

  12. logging.info('Recording started: ' +

  13. repr(filename))

  14. print('Recording started: ' + repr(filename))

  15. while t.time() < timeout or qsize > 0:

  16. if qsize > 0:

  17. file.write(q.get())

  18. qsize -= 1

  19. logging.info('Recording finished: ' +

  20. repr(filename))

  21. print('Recording finished: ' + repr(filename))

  22. os.chdir("..")

При запуске программы добавим проверку на наличие конфигурационного файла. При наличии его будет производиться чтение параметров с записью в глобальные переменные. При его отсутствии будет создан новый с значениями по умолчанию. Значения по умолчанию будем записывать следующие:

Таблица 3.1 – Значения по умолчанию для файла конфигурации

Название параметра

Значение

device

0

samplerate

None

channels

1

subtype

‘PCM_24’

record_seconds

10

max_record_seconds

600

trigger

50

log_level

20

Листинг 3.4 – Создание и чтение файла конфигурации

  1. if os.path.exists('settings.ini'):

  2. config = cp.ConfigParser()

  3. config.read('settings.ini')

  4. # читаем значения из конфиг. файла

  5. device = int(config.get('settings', 'device'))

  6. samplerate = config.get('settings', 'samplerate')

  7. channels = int(config.get('settings', 'channels'))

  8. subtype = config.get('settings', 'subtype')

  9. record_seconds = int(config.get('settings',

  10. 'record_seconds'))

  11. max_record_seconds = int(config.get('settings',

  12. 'max_record_seconds'))

  13. trigger = int(config.get('settings', 'trigger'))

  14. log_level = int(config.get('settings', 'log_level'))

  15. if samplerate == 'None':

  16. samplerate = None

  17. else:

  18. samplerate = int(samplerate)

  19. else:

  20. logging.warning('Error opening the settings file')

  21. print('Error opening the settings file')

  22. config = cp.ConfigParser()

  23. config.add_section('settings')

  24. config.set('settings', 'device', str(device))

  25. config.set('settings', 'samplerate', str(samplerate))

  26. config.set('settings', 'channels', str(channels))

  27. config.set('settings', 'subtype', str(subtype))

  28. config.set('settings', 'record_seconds',

  29. str(record_seconds))

  30. config.set('settings', 'max_record_seconds',

  31. str(max_record_seconds))

  32. config.set('settings', 'trigger', str(trigger))

  33. config.set('settings', 'log_level', str(log_level))

  34. with open('settings.ini', "w") as config_file:

  35. config.write(config_file)

Соседние файлы в папке course