2013-02-01 17:14:09 +0000 2013-02-01 17:14:09 +0000
1554
1554

Как сделать машину "пустым экраном" на некоторое время (в качестве наказания), если достигнут определенный уровень шума?

Мои дети (4 и 5) много кричат, когда играют в игры на компьютере. Я нашла эффективное лекарство от этого. Когда я слышу громкие звуки, я захожу в игровой компьютер и делаю это:

chvt 3; sleep 15; chvt 7

Это выключит экран на 15 секунд под Linux. Я сказал им, что компьютер не любит громкие звуки. Они полностью в это верят и умоляют компьютер о прощении. Они стали намного тише, но не до того уровня, на котором я был бы счастлив, и поэтому мне нужно продолжать этот образовательный процесс. Однако я не всегда могу сделать это вручную.

Можно ли это автоматизировать? К коробке прикреплен микрофон. Если уровень громкости превышает какой-то порог, я хочу запустить команду.

Ответы (6)

647
647
647
2013-02-01 17:36:38 +0000

Используйте sox из * SoX ** для анализа короткого аудио сэмпла:

sox -t .wav "|arecord -d 2" -n stat

С -t .wav мы указываем, что обрабатываем тип волны, "|arecord -d 2" выполняет программу arecord в течение двух секунд, -n выводит в нулевой файл и с stat мы указываем, что нам нужна статистика.

Вывод этой команды, в моей системе с некоторой фоновой речью:

Recording WAVE 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono
Samples read: 16000
Length (seconds): 2.000000
Scaled by: 2147483647.0
Maximum amplitude: 0.312500
Minimum amplitude: -0.421875
Midline amplitude: -0.054688
Mean norm: 0.046831
Mean amplitude: -0.000044
RMS amplitude: 0.068383
Maximum delta: 0.414063
Minimum delta: 0.000000
Mean delta: 0.021912
RMS delta: 0.036752
Rough frequency: 684
Volume adjustment: 2.370

Максимальная амплитуда может быть извлечена через нее:

grep -e "RMS.*amplitude" | tr -d ' ' | cut -d ':' -f 2

Мы grep для нужной нам строки используем tr для обрезки пробельных символов, а затем cut его символом : и берем вторую часть, которая дает нам 0.068383 в данном примере. Как следует из комментариев, RMS является лучшим измерением энергии, чем максимальная амплитуда.

Вы можете, наконец, использовать bc на результат, чтобы сравнить значения с плавающей точкой из командной строки:

if (( $(echo "$value > $threshold" | bc -l) )) ; # ...

Если вы построите цикл (см. Bash примеры ), который вызывает спящий в течение 1 минуты, проверяет громкость, а затем повторяет, вы можете оставить его запущенным в фоновом режиме. Последний шаг - добавить его в init-скрипты или служебные файлы (в зависимости от вашей операционной системы / дистрибутива), чтобы вам даже не пришлось запускать его вручную.

133
133
133
2013-02-05 16:20:11 +0000

Вот как это можно сделать с помощью Pure Data :

Метро - это метроном, а “метро 100” продолжает бить каждые 100 мс.

Звук идет из adc~, громкость вычисляется по env~. “pd dsp 0” выключает DSP при ударе, “pd dsp 1” включает его. “shell” выполняет переданную команду в оболочке, я использую Linux xrandr API для установки яркости в X, вам нужно адаптировать это для Wayland.

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

Решение с кольцевыми буферами и/или скользящими средними должно быть намного проще, чем с sox. Поэтому я не думаю, что это плохая идея использовать для этого Pure Data. Но самоблокирование экрана и блокировка не соответствует парадигме потока данных.

Файл PD находится по адресу gist.github.com: ysangkok - kidsyell.pd .

104
104
104
2013-02-01 17:32:18 +0000

Проверьте “Как обнаружить присутствие звука/аудио” Томера М. Гила .

В основном записывает звук каждые 5 секунд, затем проверяет амплитуду звука, используя sox, и решает, запускать сценарий или нет. Я думаю, что вы можете легко адаптировать сценарий ruby для ваших детей! Или вы можете выбрать, чтобы взломать на Python сценарий (с помощью PyAudio), что он предоставил, а также.

54
54
54
2013-02-01 17:28:44 +0000

Вы можете получить информацию с микрофона, сделав что-нибудь вроде:

arecord -d1 /dev/null -vvv

Возможно, вам придется немного поиграть с настройками, например:

arecord -d1 -Dhw:0 -c2 -fS16_LE /dev/null -vvv

С этого момента достаточно просто разобрать выходной сигнал.

46
46
46
2013-02-08 14:10:44 +0000

Это один из самых забавных вопросов, которые я видел. Я хотел бы поблагодарить tucuxi за такой прекрасный ответ; который я установил как скрипт bash

#!/bin/bash

threshold=0.001
# we should check that sox and arecord are installed
if [$1]; then threshold=$1; fi
while [1 -gt 0]; do
 if(( $(echo "$(sox -t .wav '|arecord -d 2' -n stat 2>&1|grep -e 'RMS.*amplitude'|tr -d ' '|cut -d ':' -f 2 ) > $threshold"|bc -l) ))
 then
  chvt 3; sleep 5; chvt 7;
 fi
done
42
42
42
2013-02-01 17:32:58 +0000

Мои 2 цента для решения на С или С++: может быть не самый эффективный подход, но в Linux, вы можете использовать ALSA API (встроенную библиотеку обработки звука Linux) и использовать некоторую числовую технику (например, вычисление среднего уровня звука каждую секунду) для получения уровня шума.

Тогда вы можете проверить его в бесконечном цикле, и если он больше заданного порога деревьев, вы можете использовать библиотеку X11 для выключения экрана на несколько секунд, или, в качестве альтернативы (менее элегантно, но работает), вызвать команду chvt, используя system("chvt 3; sleep 15; chvt 7 ");.

Похожие вопросы

10
16
11
10
5