"white noise" generator with sox for Linux

Posted on: Wed, 01/17/2007 - 17:39 By: Tom Swiss

I am a light sleeper. So a while back I was thinking about getting a "white noise" generator for my bedroom.

Then I remembered that my computer sits right across from my bed. Certainly there must be a software option...

Sox is "the swiss army knife of sound processing programs". It comes standard on most GNU/Linux distributions and is available for other platforms.

It includes sound generation capabilties, for pure tones and for white noise. More agreeable for my purpose, though, is "pink noise", which is also in sox's bag of tricks.

After a bit of experimentation, I found the following shell script produced agreeable results:

pinknoise:


#!/bin/sh
 
len='7:00:00'
 
if [ "$1" != '' ]; then
  len=$1
fi
 
sox -t sl - -t sl - synth $len pinknoise < /dev/zero |\
  sox -t sl - -t ossdsp /dev/dsp band -n 1200 200 vibro 20 .1

The script takes an optional argument providing the length of time to run and produce sound (hh:mm:ss format); it defaults to seven hours, where its output will mask minor noises to allow a decent night's sleep. The first sox invocation generates the noise, while the second applies a filter and a light vibrato effect that I find a little more pleasant than the raw noise.

You may have to change the "-t ossdsp" and/or the "/dev/dsp" depending on your audio setup. man sox to discover other options. Share and enjoy.


September 2009 update

The latest sox renamed the "vibro" effect to "tremolo", breaking my script when I updated. That was annoying. I've also reworked the thing so the pipe is no longer needed. Here's the revised, updated version:


#!/bin/sh

len='7:00:00'

if [ "$1" != '' ]; then
  len=$1
fi

play -t sl - synth $len  pinknoise \ 
     band -n 1200 200 tremolo 20 .1 < /dev/zero


Thanks all for your interest.

This beats the heck out of "cat /dev/urandom > /dev/dsp". The band filter is nice to take out the pops.

I will probably keep looking at other options such as Broodle to see what is out there. But this is a really cool one liner. I had no idea that sox could do this! Should somebody be looking for such a thing I'll be sure and point them to this page.

Thanks a lot.

With recent versions of sox, things are a little simpler:
play -n synth 60:00 brownnoise
produces brown noise for an hour. (Replace brown with pink/white if you prefer. My baby sleeps best with brown).

In reply to by gi1242 (not verified)

This tip is a godsend to me. Just switching to Ubuntu on my new netbook and this works like a charm. I was missing the app Noise, which I use on the Mac. I wonder if this would work using Terminal on the Mac? Anyway, thanks so much.

I'm still working out how to do this using a single command, I.E. without the pipe, but the 'vibro' effect is now called tremolo in the latest version of Sox.

Thanks for posting this anyway, I've had much more luck in 5 minutes with this than with Boodle.

In reply to by Tom (not verified)

I just figured out the rename (it was driving me nuts that it broke after I upgraded my box) and came over to update the page, only to find your comment.

The two sox invocations can be replaced with one call to play:

play -t sl - synth $len pinknoise band -n 1200 200 tremolo 20 .1 < /dev/zero

Tom Swiss - proprietor, unreasonable.org

Suppose I want to do Brainwave Entrainment, so I want to play a 400hz pure tone in the left ear, and a 410hz tone in the right ear, and then I wanted to merge with that the pink or brown noise at 1/4th the volume. Can sox actually generate all that in a single command line?

And can sox do frequency shifts?

That would be awesome if it could! :)

In reply to by John Arrowwood (not verified)


LENGTH='5:00'
sox -m "|sox -n -c 2 -p synth $LENGTH brown gain -5" "|sox -n -p synth $LENGTH sine 400 sine 410 gain -3" -t alsa fade h 5
# (you may need to change 'alsa' to fit your sound setup)

# varying frequencies example
play -n synth 2 square 440-880 fade h 2 gain -5 : synth 2 square 880-660 gain -5

Is there a way to turn this script into a program for Windows or even a mobile phone?

Thanks

The brown noise sounds the best in my opinion.

In reply to by Anonymous (not verified)

I am sure sox can output into a file, which could be looped on the mobile device, but it brings a few aches, like large memory consumption, pops at the end, and such, but... It works :)

Thanks a lot for this. I had previously been using boodler's noise libraries but this method is far superior since you can adjust the bandpass just how you like it right from the command line. I have been using something like this:

play -r 32000 -t sl - synth $len pinknoise band -n 600 400 tremolo 20 .1 < /dev/zero

I adapted the line to a "my neighbor is having a party and I need to study" situation:

play -c 2 -n synth pinknoise band -n 2500 4000 reverb 20

The band pass is centered on human voice frequencies and wide enough to also cover most of the musical frequency range, without producing annoying high-pitched noise. The slight reverb adds a background/ambient quality for less distraction.

In reply to by Dennis Murczak (not verified)

works absolutely great for those that have someone watching tv in the same room. and also when i am at the coffee shop.

though i must admit i added gain -20 on my computer, that way i could still hear to watch youtube videos, or should i say videos from places like udacity(youtube backend)

Thanks for the excellent article, and useful comments. Learned alot about the sox package and signal processing. I documented and modified the one-liner to a full script with detailed references:

http://gist.github.com/1209835

The CPU usage was high if the process was running for a long time, so I found a way to reduce it by 95%.

TODO [ ] - could add volume oscillation (amplitude modulation) to simulate waves or breathing pattern -- any suggestions for accomplishing this ??

I use this for the play command in the script above. No bandpass, and the tremolo values make it sound more like waves breaking on a beach, aaaaahhhhh

play -r 41k -t sl - synth $len brownnoise tremolo .13 70 < /dev/zero

In reply to by Anonymous (not verified)

Thanks to the comments I've improved the beach wave noise:

play -n -n --combine merge synth $len pinknoise band -n 1200 1800 tremolo 50 10 tremolo 0.14 70 tremolo 0.2 50

In reply to by Rafx71 (not verified)

Not sure if you'll ever see this message, but wanted to give you a huge thanks for posting this "beach wave" style sox script. We play it in my almost-5 month old daughter's room every night, and she sleeps through the night every single time. Wakes up almost on cue when the time setting expires in the morning.

So many thanks from two well-rested parents!

Here's how you can get a stereo (or multichannel!) version:

play -n -n --combine merge synth '24:00:00' pinknoise band -n 750 750 tremolo 50 1

In reply to by Jake Goulding (not verified)

In a future where we use "-n" instead of "-t sl", is your trick any different from using -c2 ?

Also, I've been rounding up the subject and to anyone else researching this, theses are the other links you are looking for:

http://www.reddit.com/r/scifi/comments/n7q5x/want_to_pretend_you_are_ab…

https://ubuntuincident.wordpress.com/2012/01/06/playing-star-trek-backg…

And this what I sleep to:

>count=5
>timer=300
>while [ $count -gt 0 ]
>do
> play -V0 -c2 -n synth $timer pinknoise band -n 100 24 band -n 300 100 gain +20 fade h 2 0 2 ; \
> play -V0 -c2 -n synth $timer whitenoise lowpass -1 120 lowpass -1 120 lowpass -1 120 gain +14 fade h 2 0 2 ; \
> play -V0 -c2 -n synth $timer pinknoise band -n 280 80 band -n 60 25 gain +20 treble +40 500 bass -3 20 flanger 4 2 95 50 .$
> play -V0 -c2 -n synth $timer whitenoise band -n 100 20 band -n 50 20 gain +25 fade h 2 0 2 ; \
> (( count-- ))
>done

[Edited to make links work. -Tom]

Use this:

# sox cannot use ladspa plugins with more than one audio input port
sox -c 2 -r 48000 -n -b 16 -c 2 -e signed-integer -r 48000 --endian little -t raw - synth 0 brownnoise vol -20db | bs2bstream -e l -b 16 -r 48 -l c | paplay --rate 48000 --format s16le --channels 2 --raw