ฉันจะสร้างเครื่อง“ หน้าจอว่างเปล่า” ได้อย่างไรในช่วงระยะเวลาหนึ่ง (เป็นค่าปรับ) หากระดับเสียงดังถึงระดับหนึ่ง


1549

ลูก ๆ ของฉัน (4 และ 5) ตะโกนมากเมื่อเล่นเกมบนคอมพิวเตอร์ ฉันพบวิธีรักษาที่มีประสิทธิภาพสำหรับสิ่งนี้ เมื่อฉันได้ยินเสียงดังฉันก็เข้าคอมพิวเตอร์และทำสิ่งต่อไปนี้

chvt 3;  sleep 15;  chvt 7 

สิ่งนี้จะปิดหน้าจอเป็นเวลา 15 วินาทีบน Linux ฉันบอกพวกเขาว่าคอมพิวเตอร์ไม่ชอบเสียงดัง พวกเขาเชื่ออย่างนี้และขอคอมพิวเตอร์ยกโทษให้ พวกเขาเงียบกว่าเดิม แต่ไม่ถึงระดับที่ฉันจะมีความสุขและดังนั้นฉันจึงต้องดำเนินการศึกษาต่อไป อย่างไรก็ตามฉันไม่ได้อยู่ที่นี่ด้วยตนเอง

เป็นไปได้ไหมที่จะทำสิ่งนี้โดยอัตโนมัติ ติดไมโครโฟนเข้ากับกล่อง หากระดับความดังผ่านเกณฑ์บางอย่างแล้วฉันต้องการเรียกใช้คำสั่ง


2
จนกว่าพวกเขาจะเรียนรู้ที่จะกด CTRL + ALT + F7
Suici Doga

1
@SuiciDoga เฮ้; พวกเขาไม่รู้ว่าเกิดอะไรขึ้น!
wizzwizz4

ขอแสดงความยินดีกับโซลูชันด้านเทคนิค แต่ฉันคิดว่ามันเป็นสิ่งสำคัญที่จะพูดความจริงกับเด็กเสมอ
เตอร์

คำตอบ:


646

ใช้soxจากSoXเพื่อวิเคราะห์ตัวอย่างเสียงสั้น ๆ :

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

ด้วยการที่-t .wavเราระบุว่าเราประมวลผลชนิด wav "|arecord -d 2"ดำเนินการarecord โปรแกรมเป็นเวลาสองวินาที-nส่งออกไปยังไฟล์ null และ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) )) ; # ... 

หากคุณสร้างลูป (ดูตัวอย่างทุบตี ) ที่โทรเข้าโหมดสลีปเป็นเวลา 1 นาทีทดสอบระดับเสียงแล้วเล่นซ้ำคุณสามารถปล่อยให้ลูปทำงานในพื้นหลัง ขั้นตอนสุดท้ายคือการเพิ่มลงในสคริปต์เริ่มต้นหรือไฟล์บริการ (ขึ้นอยู่กับ OS / distro ของคุณ) ดังนั้นคุณไม่จำเป็นต้องเปิดมันด้วยตนเอง


281
ฉันจะไม่แนะนำให้ใช้แอมพลิจูดสูงสุด มันไม่ดีสำหรับเด็ก ๆ เมื่อหน้าจอว่างเพราะมีคนตบมือหรืออะไรทำนองนั้น ค่าเฉลี่ยดูเหมือนจะเหมาะสมกว่า
orlp

34
เพียงชี้แจงโดย "เฉลี่ย" คุณหมายถึง RMS Amplitude ใช่มั้ย ค่าเฉลี่ยความแอมพลิจูดจะใกล้เคียงกับ 0 หากเสียงมีความดังที่สอดคล้องกันในช่วง 2 วินาที (ครึ่งบวกและลบจะยกเลิกซึ่งกันและกัน)
ลุค

6
เครื่องตรวจจับ "พลังงาน" อย่างง่ายสำหรับชุดตัวอย่างคือการเพิ่มมูลค่าของพีกทั้งหมดเข้าด้วยกัน คุณจะไม่ต้องเฉลี่ยแม้ถ้าคุณไม่ต้องการ จุดสูงสุดเป็นเพียงจุดใด ๆ ที่sample[n]>sample[n-1]&&sample[n]>sample[n+1]ฉันใช้สิ่งนี้เป็นกลไกพื้นฐานในการวัดพลังงานของเพลงและทำงานได้ค่อนข้างดี เพียงค้นหาหมายเลขเวทย์มนตร์ที่คุณพอใจกับระดับเสียง
Kaslai

3
ฉันต้องการที่จะดูตัวอย่างผลลัพธ์ของคำสั่งแรกของคุณเมื่อมันมาถึงเด็กตะโกนสำหรับการอ้างอิง
Alvin Wong

3
สำหรับการใช้งานที่อธิบายไว้ (เริ่มโดยอัตโนมัติ + เรียกใช้ทุกสองสามนาที) งาน cron เป็นเครื่องมือที่เหมาะสมที่จะใช้ ง่ายต่อการติดตั้งและมีประสิทธิภาพมากกว่าการใช้ init script + bash loop + sleep
m000

131

นี่เป็นวิธีที่สามารถทำได้ด้วย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


11
ดีมาก! คุณสามารถทำให้สิ่งนี้ตอบสนองได้ดีโดยใช้เทคนิคนี้: ติดตามระดับเสียงเฉลี่ยในหนึ่งนาทีจากนั้นใช้เสียงนั้นเป็นพื้นฐานเพื่อที่ว่าเมื่อเด็ก ๆ ไปสูงกว่า 20 เดซิเบลเหนือระดับพื้นฐานมันจะกระตุ้น จากนั้นจะปรับเป็นระดับเสียงรอบข้างโดยอัตโนมัติ
Hans-Christoph Steiner

1
ใช่นั่นสมเหตุสมผลแล้ว @ Hans-ChristophSteiner แต่ในทางใดทางหนึ่งระดับเสียงรบกวนรอบข้างจะไม่ต้องการให้เด็กตะโกนดังขึ้นเพราะพวกเขาจะทำให้สัดส่วนของเสียงโดยรวมลดลงหรือไม่? แน่นอนว่าจะมีผลบังคับใช้ต่อเมื่อเสียงที่มีอยู่เป็นสีขาวหรือสีชมพูหรือไม่เช่นนั้น
Janus Troelsen

4
ถ้ามันเงียบกว่าปกติเหมือนตอนเช้าวันหยุดสุดสัปดาห์มันจะทำให้ไวขึ้นเพราะมันจะอยู่ที่ระดับ 20 เดซิเบลเหนือระดับบรรยากาศเสมอ
Hans-Christoph Steiner

นี่คือ PD แบบขยายหรือไม่
nullpotent

@iccthedral: ฉันใช้ pd-extended เพื่อสร้างมัน แต่ฉันไม่รู้ว่าฉันใช้ pd ที่ขยายแบบเฉพาะเจาะจงหรือไม่
Janus Troelsen

103

ตรวจสอบ"วิธีการตรวจสอบสถานะของเสียง / เสียง" โดย Thomer เอ็มกิล

โดยทั่วไปจะบันทึกเสียงทุก 5 วินาทีกว่าการตรวจสอบความกว้างของเสียงการใช้soxและตัดสินใจว่าจะเรียกสคริปต์หรือไม่ ฉันคิดว่าคุณสามารถดัดแปลงrubyสคริปต์ให้กับลูก ๆ ของคุณได้อย่างง่ายดาย! หรือคุณสามารถเลือกที่จะแฮ็คสคริปต์ Python (โดยใช้ PyAudio) ที่เขาให้ไว้ได้เช่นกัน


5
สิ่งที่เกี่ยวกับการปะทุเหล่านั้นน้อยกว่า 5 วินาทีที่หลีกเลี่ยงการตรวจสอบ?
RhysW

53

คุณสามารถรับข้อมูลจากไมโครโฟนได้โดยทำสิ่งต่อไปนี้

arecord -d1 /dev/null -vvv

คุณอาจต้องเล่นกับการตั้งค่าเล็กน้อยเช่น:

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

จากตรงนี้มันเป็นเรื่องง่าย ๆ ในการแยกวิเคราะห์เอาต์พุต


44

นี่เป็นหนึ่งในคำถามที่สนุกกว่าที่ฉันเคยเห็น ฉันขอขอบคุณtucuxi สำหรับคำตอบที่ดีเช่นนี้ ที่ฉันได้ตั้งเป็นสคริปต์ทุบตี

#!/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 เกินไป _loud จากนั้นกด Ctrl + Alt + F1 แล้วลงชื่อเข้าใช้ที่นั่น)
Alexx Roche

41

2 เซนต์ของฉันสำหรับโซลูชัน C หรือ C ++: อาจไม่ใช่วิธีที่มีประสิทธิภาพที่สุด แต่บน Linux คุณสามารถใช้ALSA API (ไลบรารีการจัดการระบบเสียงในตัวของ Linux) และใช้เทคนิคเชิงตัวเลข (เช่นการคำนวณเสียงเฉลี่ย ระดับแต่ละวินาที) เพื่อให้ได้ระดับของเสียง

จากนั้นคุณสามารถตรวจสอบในวง จำกัด และถ้ามันเป็นมากกว่า treshold ที่ตั้งไว้คุณสามารถใช้ห้องสมุด X11เพื่อปิดหน้าจอสำหรับบางวินาทีหรือหรือ (สง่างามน้อย แต่ทำงาน) เรียกคำสั่งใช้chvtsystem("chvt 3; sleep 15; chvt 7 ");


2
chvtถ้าใช้คำสั่งฉันจะพิจารณาบางสิ่งบางอย่างที่แตกต่างกันแล้ว ArchWikiมีตัวอย่างที่ดี
โฆษณา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.