Skip to content

Latest commit

 

History

History
110 lines (59 loc) · 8.11 KB

README.md

File metadata and controls

110 lines (59 loc) · 8.11 KB

Pico-mixer

keypad

This project was born after thinking that I'd really like to have something like a Launchpad to control and mix sound ambiances while DMing a Dungeons and Dragons game.

What I wanted was a way to create an immersive atmosphere at the table, by being able to start, stop, pause and resume multiple individual soundtracks, adjust their volume, and flash pretty colors.

I used a Pimoroni Keypad, as well as a Raspberry Pi Pico, for a total budget of roughly 30 euro. The black casing was 3D-printed using the rgb_keypad_-_bottom.stl file from this Thingiverse model.

Setup

The code.py script runs on a Raspberry Pi Pico, running CircuitPython, itself connected onto the Pimoroni Keypad. The first 12 keys control what audio tracks to play/stop, and the last 4 keys allow you to control the volume of individual tracks, as well as pause the whole stream.

Screen Shot 2022-09-17 at 15 20 23

When a key (or a combination of Volume up/down + track key) is pressed, a JSON-formatted message is sent over USB. This message is read by the mixer.py script, a curses app displaying each individual track, associated with their volume bar.

Screen Shot 2022-09-17 at 15 15 47

Limitations

The mixer.py script currently uses pygame.mixer to play the individual track sound files over separate channels. While this works, the startup time can be excruciatingly slow, as each sound file must be fully loaded in memory before the app can start.

This is due to the fact that pygame can handle sound 2 different ways:

  • it can stream large sound files as background music via mixer.music (which is what we want!), but it can only play one track at a time()
  • it can play multiple sound files on different channels via pygame.mixer.{Sound,Channel}, but it has to fully load these sound files into memory. It's usually ok because these sounds files are very small, as it's mostly for quick sound effects.

We're trying to shoehorn both mixer.Sound and mixer.music together, which has sadly proven to not work, as pygame implement streaming from an audio file directly in the mixer.music class, without exposing it as a standalone utility.

Local web application

One way I found to circumvent the previously stated limitations was to implement a slightly more complex web application composed of 3 elements:

  • the keypad CircuitPython code
  • a webpage in charge of displaying the soundbars and active tracks as well as actually controlling the audio tracks
  • a Flask webserver receiving the keypad messages over USB and serving them to the webpage over a websocket, as well as serving the static audio files to the webpage

Screenshot 2022-09-18 at 17 06 35

As the browser is really good at streaming <audio> elements, the app can start immediately without having to load all audio files in memory.

Screenshot 2022-09-21 at 20 25 38

Colors

The key colors were generated from iwanthue and are stored in the COLORS list, in pico/code.py. Any changes to the colors will be reflected in the web UI, as they are advertised to the web-server at propagated to the UI when the keypad starts.

Getting started on macOS and Linux

(This guide assumes that CircuitPython has been installed on the pico. If that is not the case, follow these instructions first.)

Open a terminal, then run the following commands:

$ cd ~/Downloads
$ curl -L https://github.com/brouberol/pico-mixer/archive/refs/heads/main.zip -o main.zip
$ unzip main.zip
$ cd pico-mixer-main
$ python3 -m pip install --user poetry
$ make install

Plug the keypad, and run:

$ make pico-sync

The keypad should light up. Unplug it.

Now, copy all the sounds files you would like to play (12 max) under the pico_mixer_web/assets/sounds folder, and replace each example title attribute under the config.json file with the name of a sound file you copied under sounds. Feel free to add a couple of descriptive tags under the tags attribute. Save the config.json file.

Run the following command to start the webserver:

$ make webmixer

At that point, the webserver will start and the webpage will open. Plug the keypad in. You are now ready.

Getting started on Windows

(This guide assumes that CircuitPython has been installed on the pico. If that is not the case, follow these instructions first.)

Before being able to execute this application on your Windows machine, you will need to install the Python programming language. To do this, go to the Windows download page, click on the "Latest Python 3 Release" link, and follow the installation instructions.

Now that Python is installed, click on the green Code button at the top of this page, and then on Download zip. This will download the project as a zip file in your Downloads folder. Unzip it by right-clicking on the archive, and click on "Extract here".

Open the pico-mixer-main folder, and its subfolder, until you can see a README.md file. Open the pico folder. Plug the keypad to your computer using the USB cable. A file explorer window should open. Copy all the files in the current pico folder to the CIRCUITPY USB volume. At that point, the keypad should light up. Unplug it. Go back to the parent folder.

Double click on the win-install file to install all dependencies.

Now, copy all the sounds files you would like to play (12 max) under the pico_mixer_web\assets\sounds folder, and open the config file with a text editor, such as Notepad. Replace each example title attribute with the name of a sound file you copied under sounds and, feel free to add a couple of descriptive tags under the tags attribute. Save the file.

We can now execute the web server, by double clicking on win-run. This will start the app and open your internet browser on http://localhost:8000.

Plug the keypad in. At that point, you should see as many bars as you have sound files (12 max), with colors, and you should see the 🔌 ✅ emoji, indicating that the keypad is plugged and recognized.

Press a key, and lo and behold, a sound should play. If that is not the case, check out the output of the command you ran in the terminal. If you see some lines with 404 -, this means that you made a typo in the title attribute of that track, in the config.json file, and that it does not match the filename of the actual sound file. Fix the typo, kill the webserver by pressing Ctrl-C and restart it. If nothing works, checke the Q/A at the bottom of the webpage.

Warning: if you find instructions unclear or struggle to run through them, please have a look at the Need help❓ section in the app, and possibly this comment first.