Turn a Raspberry Pi into the ultimate relaxation machine that plays soothing wav files.
Here are the features of the Ultimate Noise Machine:
- Produces CD-quality stereophonic audio.
- Uses real audio samples with gapless undetectable looping
- Line level audio output jack to use with high quality powered speakers
- Intuitive control panel with rotary wheel and LCD screen
- Web-based control too with a responsive UI
This is the full-size unit based on a Raspberry Pi 3 with custom 3D-printed faceplate:
The smaller version uses smaller buttons and a Raspberry Pi Zero 2W:
At a minimum, you need a Pi and the audio bonnet specified below. If you don't use the buttons, rotary encoder, or display, you can control the Noise Box from its built-in web page by browsing to the device's IP address or enabling the Public URL feature.
- Raspberry Pi 3, 4, or Zero 2W
- Adafruit I2S Audio Bonnet
- Momentary SPST pushbutton such as this one
- 1.44 inch TFT LCD screen
- Rotary encoder (why not get a nice knob too?)
- I2C Rotary Encoder Breakout
Wire the switches into the audio bonnet following the schematic below. You can solder directly into the pads on the bonnet, which show the GPIO number.
Wire the LCD into the bonnet using the diagram for the 1.44" display found here.
Solder the rotary encoder to the encoder board as detailed here. Finally, wire the rotary encoder board into the bonnet. You could use the Qwiic connector on one end, but either way the INT terminal on the rotary board will need to be wired in to GPIO 17.
Attach the audio bonnet to the Pi.
Use your favorite project case, and to enhance the project, print your own faceplate to mount the controls. You can find STL files in this repo for the 3D faceplates used in the pictures above. Unfortunately the cases used for them no longer appear available from Radio Shack online.
This project uses the balena platform for ease of deployment, device management and as the best way to run containers on the Pi. Sign up for a free account - the first 10 devices are free and fully featured. After assembling your hardware and creating a balena account, simply click the button below to generate a microSD card image to burn and insert in your Pi:
After you create a fleet, add a new device. Choose the type of Pi you'll be using and you can also add your WiFi credentials at this point. You'll be able to download the SD card image after you add the device. You can use balenaEtcher to burn your SD card image. After powering on your Pi, it should start downloading the software.
After the software has downloaded, you'll need to go into the device configuration in balenaCloud and add the following configuration variable:
BALENA_HOST_CONFIG_dtoverlay
With the value:
"hifiberry-dac","i2s-mmap"
If you want to make your own changes to the software, clone this repo and use the balena CLI to push the modified code to your device.
The unit comes with nine pre-recorded relaxation sounds. To add more sounds, browse to the device's IP address (you can find it on the dashboard) on port 9000. (i.e. 192.168.1.100:9000 - but use your IP) The initial login for the Minio browser is myminio
/myminio123
here you can drag and drop additional sound files. They must be of the following type: uncompressed PCM format wav files. The sound file should be optimized for looping playback. If you would like an accompanying image for each sound file, give it the same name but with a .jpg file extension. Images should be 128x128 pixels. After uploading additional files, you should reboot the device from the balenaCloud dashboard.
You can scroll through the available sounds by rotating the wheel. Push the wheel to play the selected sound. The stop button stops playback of the current sound.
The display button cycles through the volume display and the device info display. You can adjust the volume level with the wheel when the volume bar is displayed, however controlling the actual volume is currently not implemented.
The four preset buttons instantly start playing the preset sound. To store a preset, open the web interface to the device by browsing its IP address (port 80).
Next to each sound you'll see buttons labeled 1 - 4. Click the button number next to a sound to assign it to that preset number.
The application is made up of multiple containers that communicate with each other through APIs and also share a storage volume. This project is a great example of how containers can work together and cleanly separate functionality. Also note how we add entire functionality by pulling images made by the various software authors.
Here is a summary of the function of each container:
This is the Python program that plays back the audio files through the audio block. It uses Pygame to achieve gapless looping playback. The audio files must be in uncompressed PCM wav file format. It exposes an API (using FlaskAPI)
GET /
returns the current status (status
) and currently playing file (file
) and a list of valid API calls.POST /play/<noisename>/
immediately starts looping playback of specified noise, and returns the current status (status
) and currently playing file (file
)POST /stop/
immediately stops any file playback, and returns the current status (status
)
Note <noisename>
and returned file are the name of the noise, with no path or extension, and underscore (_) instead of spaces.
This is a Node/Express webserver that generates a single page for stopping or starting a noise from the library or presets. It is also currently the only place you can assign presets to noises. The four presets mirror the four physical buttons on the hardware control panel. This application uses XMLHttpRequest to communicate with the backend for stopping, starting and assigning presets. It is set to run on port 80 by default and can be made available outside your network if you enable the device's public URL.
An in-memory data structure store. It can periodically write to the local storage as well. This is used to store and retreive the values of the preset buttons, last volume level and most recently played file.
S3 compatible object storage. This provides a web interface for uploading new audio files and their associated jpegs to the device. To access the interface, browse to the local URL using port 9000. To change the username and password, set new values in the docker-compose.yml
file before first use! (You'll need to clone this repo and push using the CLI in order to do this.)
This is the versatile balena audio block that runs a PulseAudio server optimized for balenaOS and is the core of balenaSound. We use it here to take care of setting up and routing all audio needs on the Pi hardware, so the noise container just sends its audio here.
A custom Python program that responds to button presses on the control panel, reads the rotary dial position and drives the LCD display.
Some of the included sounds and their accompanying images were derived from the following royalty-free image and sound libraries:
Waterfall sound by NickyPe from Pixabay
Splash sound by JuliusH from Pixabay
Rain sound by sergei_spas from Pixabay
Brown image extracted from photo by Pawel Czerwinski on Unsplash
Pink noise image extracted from photo by Joel Filipe on Unsplash
Underwater image extracted from photo by Sarah Lee on Unsplash
Rain image extracted from photo by Jan-Willem on Unsplash
Splash image extracted from photo by Amadej Tauses on Unsplash
Waterfall photo by Nathan Anderson on Unsplash