Як зробити машину «порожнім екраном» протягом певного періоду часу (як штраф), якщо досягнуто певного рівня шуму?


1548

Мої діти (4 та 5) сильно кричать під час гри в комп’ютер. Я знайшов ефективне ліки від цього. Коли я чую гучні шуми, я впадаю в ігровий комп'ютер і роблю:

chvt 3;  sleep 15;  chvt 7 

Це вимкне екран на 15 секунд у Linux. Я сказав їм, що комп’ютер не любить гучних шумів. Вони повністю вірять цьому і просять комп’ютер пробачення. Вони стали набагато тихішими, але не до рівня, на який я був би радий, і тому мені потрібно продовжувати цей навчальний процес. Однак я не завжди збираюся робити це вручну.

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


2
Поки вони не навчаться натискати CTRL + ALT + F7
Suici Doga

1
@SuiciDoga Гей; вони не знають, що відбувається!
wizzwizz4

Подяка за технічне рішення. Але я думаю, важливо завжди говорити правду дітям.
peterh

Відповіді:


645

Використовуйте soxвід SoX для аналізу короткого зразка звуку:

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

З -t .wavзадамо ми обробляємо тип 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 або службових файлів (залежно від вашої ОС / дистрибутива), щоб навіть не потрібно було запускати його вручну.


280
Я б не рекомендував брати максимальну амплітуду. Дітям не приємно, коли їхній екран порожній лише тому, що хтось плескав чи щось подібне. Середній здається більш підходящим.
orlp

34
Просто уточнення, під "середнім" ви маєте на увазі амплітуду RMS так? Середня амплітуда буде близькою до 0, якщо шум буде постійною гучністю протягом 2 секунд (позитивні та негативні половини скасують одна одну).
Лук

6
Простий «енергетичний» детектор для серії зразків - це просто додати значення всіх піків разом. Вам би не довелося навіть оцінювати її середнього, якщо цього не хочете. Пік - це будь-яка точка, де sample[n]>sample[n-1]&&sample[n]>sample[n+1]я використовував це як рудиментарний механізм вимірювання енергії пісні, і він працює досить добре. Просто шукайте чарівне число, яким ви задоволені рівнем гучності.
Каслай

3
Я хотів би побачити зразок виходу вашої першої команди, коли це дійсно доходить до того, як дитина кричить, для довідки.
Альвін Вонг

3
Для описаного використання (почніть автоматично + запускайте кожні кілька хвилин) завдання cron є правильним інструментом для використання. Набагато простіший у налаштуванні та більш надійний, ніж використання сценарію init + bash loop + sleep.
m000

130

Ось як це можна зробити за допомогою чистих даних :

Профілактика дитячого крику з використанням даних Pure

Метро - метроном, і "метро 100" продовжує стукати кожні 100 мс.

Звук надходить від adc ~, гучність обчислюється env ~. "pd dsp 0" вимикає DSP при ударі, "pd dsp 1" включає його. "shell" виконує передану команду в оболонці, я використовую API xrandr Linux для встановлення яскравості на X, вам потрібно адаптувати це для Wayland.

Як бачите, пільговий період та блокування займають набагато більше місця, ніж звуковий код.

Зробити рішення за допомогою кільцевих буферів та / або рухомих середніх значень має бути набагато простіше, ніж робити це sox. Тому я не думаю, що використовувати для цього чисті дані погано. Але сам екран блокується і блокування не відповідає парадигмі потоку даних.

Файл PD знаходиться на веб- сайті gist.github.com: ysangkok - kidsyell.pd .


11
дуже хороша! Ви можете зробити це досить чуйним за допомогою цієї методики: відслідковуйте середній рівень звуку протягом хвилини, а потім використовуйте це як базовий рівень, так що коли діти переходять на 20 дБ вище базової лінії, це спрацьовує. Тоді він автоматично налаштується на рівень зовнішнього звуку.
Ганс-Крістоф Штайнер

1
Так, це має сенс @ Ганс-КристофШтейнер. Але певним чином, чи не насправді рівень шуму навколишнього середовища вимагатиме від дітей кричати голосніше, оскільки вони становлять меншу частку загального шуму? Це звичайно застосовуватиметься лише в тому випадку, якщо наявний шум буде білим або рожевим або іншим чином ігнорується.
Янус Троельсен

4
якби вона була тихішою, ніж зазвичай, як ранок у вихідні, то це зробить її більш чутливою, оскільки вона завжди буде на 20 дБ вище рівня навколишнього середовища
Ганс-Крістоф Штайнер

Це розширений PD?
недійсний

@icct Cathedral: Я використовував pd-Extended, щоб зробити це, але я не знаю, чи використовував я будь-які конкретні конструкції, розширені pd.
Янус Трольсен

102

Поставте прапорець "Як визначити наявність звуку / звуку" від Thomer M. Gil .

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


5
Що з тими спалахами менше 5 секунд, які уникають виявлення?
RhysW

53

Ви можете отримати інформацію з мікрофона, зробивши щось на зразок:

arecord -d1 /dev/null -vvv

Можливо, вам доведеться трохи пограти з налаштуваннями, такими як:

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

З цього моменту це просто питання аналізу результатів.


43

Це одне із найсмішніших питань, які я бачив. Я хотів би подякувати 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

7
Якщо ви почнете цей запуск, додавши рядок до /etc/rc4.d/S99rc.local, а потім зміните вхідний мікрофон з непідвладного на 100%, ви також можете перекинутись на tty3 (ви можете перейти назад до сну перейдіть за допомогою Ctrl + Alt + F7), і якщо клавіатура занадто гучна, щоб відкрити термінал, запустити sudo killall too_loud, тоді Ctrl + Alt + F1 і увійдіть туди.)
Alexx Roche

41

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

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


2
Якщо за допомогою команди я б тоді розглядав щось інше chvt. ArchWiki має приємні приклади.
AD
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.