Belirli gürültü seviyelerine ulaşıldığında bir makineyi bir süre (ceza olarak) bir süre “boş ekran” yapabilirim?


1549

Çocuklarım (4 ve 5) bilgisayarda oyun oynarken çok bağırıyorlar. Bunun için etkili bir tedavi buldum. Yüksek sesler duyduğumda, oyun bilgisayarına girip şunu yapıyorum:

chvt 3;  sleep 15;  chvt 7 

Bu, Linux'ta 15 saniye boyunca ekranı kapatacak. Onlara bilgisayarın yüksek seslerden hoşlanmadığını söyledim. Buna tamamen inanıyorlar ve bilgisayara bağışlama için yalvarıyorlar. Çok daha sessiz hale geldiler, ama mutlu olacağım seviyesine gelmedi ve bu yüzden bu eğitim sürecine devam etmem gerekiyor. Ancak, bunu el ile yapmak için her zaman buralarda değilim.

Bunu otomatikleştirmek mümkün mü? Kutuya bir mikrofon bağlı. Ses seviyesi bir eşikten geçerse, o zaman bir komut çalıştırmak istiyorum.


2
CTRL + ALT + F7
Suici Doga

1
@SuiciDoga Hey; ne olduğunu bilmiyorlar!
wizzwizz4

Teknik bir çözüm için tebrikler. Fakat bence çocuklara her zaman doğruyu söylemek önemlidir.
Peter

Yanıtlar:


646

Kullanım soxgelen SOX kısa ses örneğini analiz etmek:

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

İle -t .wavbiz wav türünü işlemek belirtin "|arecord -d 2"yürütür arecord , iki saniye programı -nboş dosyaya verir ve birlikte statbiz biz istatistiklerini istiyoruz belirtin.

Bu komutun çıktısı, bazı arka plan konuşmalarına sahip sistemimde:

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

Maksimum genlik daha sonra yoluyla elde edilebilir:

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

Biz grepistediğimiz hattı için kullanmak trboşluk karakterleri uzak trim ve daha sonra cutbunu tarafından :karakter ve bize verdiği ikinci katılmak 0.068383bu örnekte. Yorumlar tarafından önerildiği gibi, RMS , maksimum genlikten daha iyi bir enerji ölçüsüdür.

bcSonuçta kayan nokta değerlerini komut satırından karşılaştırmak için sonucu kullanabilirsiniz :

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

1 dakika boyunca uyku çağıran bir döngü oluşturursanız ( Bash örneklerine bakın ), sesi sınar ve ardından tekrarlarsa, arka planda çalışmaya devam edebilirsiniz. Son adım, init komut dosyalarına veya servis dosyalarına (işletim sisteminize / dağıtımınıza bağlı olarak) manuel olarak başlatmanıza gerek kalmayacak şekilde eklemektir.


281
Maksimum amplitüd almayı kabul etmem. Sadece birileri çırptığından ya da benzer bir şey yüzünden ekranı boşaldığında çocuklar için hiç hoş değil. Ortalama daha uygun görünüyor.
orlp

34
Sadece bir açıklama, "ortalama" derken demek RMS Genlik değil mi? Gürültü 2 saniye boyunca sürekli bir yükseklikte ise, Ortalama Genlik 0'a yakın olacaktır (pozitif ve negatif yarımlar birbirini iptal edecektir).
Luke

6
Bir dizi örnek için basit bir "enerji" dedektörü tüm piklerin değerini bir araya getirmektir. İsteseydin bile ortalamasını yapmak zorunda kalmazdın. Zirve, sample[n]>sample[n-1]&&sample[n]>sample[n+1]bir şarkının enerjisini ölçmek için basit bir mekanizma olarak kullandığım herhangi bir nokta ve gayet iyi çalışıyor. Sadece ses seviyesinden memnun olduğunuz sihirli bir numarayı arayın.
Kaslai

3
Referans için gerçekten bağıran bir çocuk söz konusu olduğunda ilk komutunuzun bir örnek çıktısını görmek isterim.
Alvin Wong,

3
Açıklanan kullanım için (otomatik olarak başlat + birkaç dakikada bir çalıştır) bir cron işi kullanmak için doğru araçtır. Kurulumu çok daha basittir ve init script + bash loop + sleep komutunu kullanmaktan daha sağlamdır.
m000

131

İşte Saf Veri ile nasıl yapılabileceği :

Saf Veri kullanarak çocuk bağırma önleme

Metro bir metronomdur ve "metro 100" her 100 ms'de bir çarpmaya devam ediyor.

Ses adc ~ 'dan geliyor, ses env ~ ile hesaplanıyor. "pd dsp 0", vurulduğunda DSP'yi kapatır, "pd dsp 1" onu açar. "shell" pass komutunu bir shell'de uygular, parlaklığı X'e ayarlamak için Linux xrandr API kullanıyorum, bunu Wayland için uyarlamanız gerekir.

Gördüğünüz gibi, ödemesiz süre ve kilitleme, ses kodundan çok daha fazla yer kaplar.

Halka tamponları ve / veya hareketli ortalamalarla bir çözüm yapmak, yapmaktan daha kolay olmalıdır sox. Bu yüzden bunun için Saf Veri kullanmanın kötü bir fikir olduğunu sanmıyorum. Ancak ekran kendini boşaltır ve kilitlenir, veri akışı paradigmasına uymaz.

PD dosyası gist.github.com adresinde bulunmaktadır: ysangkok - kidsyell.pd .


11
çok hoş! Bunu, bu tekniği kullanarak oldukça duyarlı hale getirebilirsiniz: bir dakika boyunca ortalama ses seviyesini takip edin, sonra bunu taban çizgisi olarak kullanın, böylece çocuklar taban çizgisinin 20 dB üstüne çıktığında tetikler. Sonra otomatik olarak ortam ses seviyesine ayarlanır.
Hans-Christoph Steiner,

1
Evet, @ Hans-ChristophSteiner @ mantıklı. Ancak, bir anlamda, ortam gürültüsü aslında çocukların daha yüksek sesle bağlanmalarını gerektirmez, çünkü genel gürültünün daha küçük bir kısmını oluştururlar mı? Tabii ki, yalnızca mevcut gürültü beyaz veya pembe ise veya başka türlü görmezden gelinirse uygulanır.
Janus Troelsen

4
normalden daha sessiz olsaydı, bir haftasonu sabahı gibi, o zaman daha duyarlı hale gelirdi, çünkü her zaman ortam seviyesinden 20 dB yukarıda olurdu
Hans-Christoph Steiner

Genişletilmiş PD bu mu?
nullpotent

@iccthedral: Bunu yapmak için pd genişletilmiş kullandım, ancak herhangi bir genişletilmiş özel yapı kullanıp kullanmadığımı bilmiyorum.
Janus Troelsen

103

Kontrol Thomer M. Gil tarafından "Nasıl ses / ses varlığını tespit etmek" .

Temel olarak, sesi her 5 saniyede bir kaydeder, ses şiddetini kontrol eder, kullanır soxve bir betiği tetikleyip tetiklememeye karar verir. Bence rubysenaryoyu çocuklarınız için kolayca uyarlayabilirsiniz ! Veya sağladığı Python betiğini (PyAudio kullanarak) kesmeyi de seçebilirsiniz.


5
Peki ya algılamayı engelleyen 5 saniyeden daha az patlayanlar?
RhysW

53

Gibi bir şey yaparak mikrofondan bilgi alabilirsiniz:

arecord -d1 /dev/null -vvv

Ayarlarla biraz oynamak zorunda kalabilirsiniz, örneğin:

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

Oradan itibaren, çıktıyı ayrıştırmak basit bir mesele.


44

Bu gördüğüm en eğlenceli sorulardan biri. Böyle güzel bir cevap için Tucuxi'ye teşekkür etmek istiyorum ; bash betiği olarak ayarladığım

#!/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
Bu çalışmaya /etc/rc4.d/S99rc.local 'a bir çizgi ekleyerek başlatır ve daha sonra giriş mikrofonunu% 100'den% 100' e değiştirirseniz, tty3 'e atılabilir (uykudan önce geri atlayabilirsiniz) Ctrl + Alt + F7 ile) ve klavyeniz bir terminal açmak için çok yüksekse, sudo killall too_loud komutunu çalıştırmak için Ctrl + Alt + F1 tuşlarına basıp oturum açın.)
Alexx Roche

41

C veya C ++ çözümü için 2 sentim: belki de en etkili yaklaşım değil, ancak Linux'ta, ALSA API'sini (Linux'un yerleşik ses işleme kitaplığı) kullanabilir ve bazı sayısal teknikler kullanabilirsiniz (örneğin, ortalama ses hesaplaması) Her saniye seviyesi) gürültü seviyesini elde etmek için.

Daha sonra sonsuz bir döngüde kontrol edebilirsiniz ve önceden belirlenmiş bir eşikten büyükse , ekranı birkaç saniye süreyle kapatmak için X11 kitaplığını kullanabilirsiniz veya alternatif olarak (daha az zarif, ancak işe yarar ) chvtkomutunu kullanarak onu çağırırsınız system("chvt 3; sleep 15; chvt 7 ");.


2
Komutu kullanarak farklı bir şey düşünürdüm o zaman chvt. ArchWiki'nin güzel örnekleri var.
AD
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.