Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

My kids (4 and 5) yell a lot when playing games on the computer. I found an effective cure for this. When I hear loud noises, I ssh into the game computer and do:

chvt 3;  sleep 15;  chvt 7 

This will turn off the screen for 15 seconds on Linux. I've told them that the computer doesn't like loud noises. They totally believe this and beg the computer for forgiveness. They became much quieter, but not to the level that I would be happy, and so I need to continue this educational process. However, I am not always around to do this manually.

Is it possible to automate this? A microphone is attached to the box. If the level of loudness passes some threshold then I want to run a command.

share|improve this question

migrated from stackoverflow.com Feb 2 '13 at 0:01

This question came from our site for professional and enthusiast programmers.

384  
One suggestion would be to just program the kids directly. However, some people prefer the indirect route through the computer, which does provide a convenient pre-existing portal. –  Carl Feb 1 '13 at 23:35
150  
You have done this so many times manually that you feel you need to automate it... Doesnt that suggest to you that this method isnt working? –  Keltari Feb 2 '13 at 3:20
188  
Seriously curious; which game do they play on Linux, that makes them yell? –  user4553 Feb 2 '13 at 14:37
131  
I'd note critiques on the op's parenting technique are probably best left to parenting.stackexchange especially when it comes to answers. Moving it there would be the wierdest migration ever. If we forget the bit about using this method as a way of reinforcing a behaviour, I'm quite sure we could find other possible uses for it. Maybe as a way of monitoring and reporting excessive noise of other sorts? –  Journeyman Geek Feb 2 '13 at 15:08
95  
You know what would be awesome? A solution that fits the request, but also includes voice recognition and turns the screen back on early if it detects an apology. –  aslum Feb 4 '13 at 16:06

7 Answers 7

Use sox from SoX to analyze a short audio sample:

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

With -t .wav we specify we process the wav type, "|arecord -d 2" executes the arecord program for two seconds, -n outputs to the null file and with stat we specify we want statistics.

The output of this command, on my system with some background speech, is:

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

The maximum amplitude can then be extracted via:

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

We grep for the line we want, use tr to trim away the space characters and then cut it by the : character and take the second part which gives us 0.068383 in this example. As suggested by comments, RMS is a better measure of energy than maximum amplitude.

You can finally use bc on the result to compare floating-point values from the command-line:

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

If you build a loop (see Bash examples) that calls sleep for 1 minute, tests the volume, and then repeats, you can leave it running in the background. The last step is to add it to the init scripts or service files (depending on your OS / distro), such that you do not even have to launch it manually.

share|improve this answer
231  
I would disrecommend taking the maximum amplitude. It's not nice for the kids when their screen goes blank just because someone clapped or something similar. Average seems more appropriate. –  nightcracker Feb 1 '13 at 17:59
23  
Just a clarification, by "average" you mean RMS Amplitude right? The Mean Amplitude is going to be close to 0 if the noise is of a consistent loudness over the 2 seconds (the positive and negative halves will cancel each other out). –  Luke Feb 2 '13 at 20:10
5  
A simple "energy" detector for a series of samples is to just add the value of all the peaks together. You wouldn't have to even average it if you didn't want to. A peak is just any point where sample[n]>sample[n-1]&&sample[n]>sample[n+1] I've used this as a rudimentary mechanism for measuring the energy of a song and it works quite well. Just search for a magic number at which you're happy with the volume level. –  Kaslai Feb 3 '13 at 1:45
4  
I left this answer when the question was still active on stackoverflow, and now @Tom Wijsman has edited in links and great explanations and the answer has > 200 upvotes. Wow! –  tucuxi Feb 4 '13 at 7:57
5  
Fantastic! I must now hurry up and have some more kids to test it! :-) I only hope my kid doesn't read this thread and program an "if (( noise > RMS.threshold )); eject parents from bed" –  Alberto Feb 11 '13 at 9:36

Here's how it can be done with Pure Data:

Kid yell prevention using Pure Data

I am a Pure Data newbie, so this is probably not optimal at all. As you can see, grace period and locking takes up way more space than audio code does.

But making a solution with ring buffers and/or moving averages should be way easier than doing it with sox. So I don't think it's a bad idea to use Pure Data for this. But the screen blanking itself and the locking doesn't fit with the dataflow paradigm, so that should probably be done in a shell script.

The PD file is at gist.github.com: ysangkok - kidsyell.pd.

share|improve this answer
6  
very nice! You could make this to be quite responsive using this technique: track the average sound level over a minute, then use that as the baseline, so that when the kids go over 20 dB above the baseline, it triggers. Then it'll automatically adjust to the ambient sound level. –  Hans-Christoph Steiner Feb 5 '13 at 16:33
1  
Yes, that makes sense @Hans-ChristophSteiner. But in a way, wouldn't the ambient noise level actually require the kids to yell louder, since they would make up a smaller proportion of the overall noise? That of course would only apply if the existing noise is white or pink or otherwise ignored. –  Janus Troelsen Feb 5 '13 at 16:40
2  
if it was quieter than usual, like a weekend morning, then it would make it more sensitive, since it would always be 20 dB above the ambient level –  Hans-Christoph Steiner Feb 5 '13 at 16:42
    
This is the extended PD? –  iccthedral Feb 9 '13 at 15:09
    
@iccthedral: I used pd-extended to make it, but I don't know if I used any pd-extended specific constructs. –  Janus Troelsen Feb 10 '13 at 12:56

Check "How to detect the presence of sound/audio" by Thomer M. Gil.

Basically it records the sound every 5 seconds, than checks for the sound amplitude, using sox, and decides if trigger a script or not. I think you can easily adapt the ruby script for your children! Or you can choose to hack away on the Python script (using PyAudio) that he has provided as well.

share|improve this answer
4  
What about those outbursts less than 5 seconds that avoid detection? –  RhysW Feb 4 '13 at 10:13
21  
We'll give em that.... the point is to keep it down not to destroy fun. We cheat all the time on our kids, Santa... X-mas, Religion. Boogieman. Parents stating they don't trick or lie to their kids should look up 'reverse psychology' on wiki. It's a short term method, who has it's place. The point is to switch it off once they are almost complying. A little slack won't hurt. –  Glenn Plas Feb 4 '13 at 14:23
    
@GlennPlas I agree to the situation with the OP that the slack won't hurt, but as a comment on the question points out, this also has other uses for noise monitoring, my comment was more to direct a reinforced answer for those people who want to use this solution for non parenting reasons! –  RhysW Oct 28 '13 at 12:24

You can get information from the microphone by doing something like:

arecord -d1 /dev/null -vvv

You might have to play with the settings a little, such as:

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

From there on out, it's a simple matter of parsing the output.

share|improve this answer

My 2 cents for the C or C++ solution: maybe not the most effective approach, but on Linux, you can use the ALSA API (built-in audio handling library of Linux) and use some numerical technique (for example, calculating the average sound level each second) to obtain the level of noise.

Then you can check it in an infinite loop, and if it's greater than a preset treshold, you can use the X11 library to turn off the screen for some seconds, or alternatively (less elegant, but it works) invoke the chvt command using system("chvt 3; sleep 15; chvt 7 ");.

share|improve this answer
    
If using command I would consider something different then chvt. ArchWiki has nice examples. –  A.D. Feb 5 '13 at 13:20

This is one of the more fun questions that I've seen. I would like to thank tucuxi for such a fine answer; that I have set as a bash script

#!/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
share|improve this answer
3  
If you start this running by adding a line to /etc/rc4.d/S99rc.local and then change the input mic from unamplified to 100% you too can end up being thrown over to tty3 (you can jump back before the sleep is over with Ctrl+Alt+F7), and if your keyboard is too loud to open a terminal, to run sudo killall too_loud then Ctrl+Alt+F1 and log in there.) –  Alexx Roche Feb 10 '13 at 12:45

I would use something like Pure Data for this. It is very easy to make something where you check the level from the mic and send the command if it passes a certain treshold.

share|improve this answer
70  
Welcome to Super User! Could you please expand your answer to explain in more detail how to go about doing this? –  slhck Feb 2 '13 at 17:50

protected by Community Feb 2 '13 at 18:53

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.