https://github.com/brouberol/pico-mixer
Mix different sound ambiances with a Pimoroni Keypad and a Raspberry Pi Pico
https://github.com/brouberol/pico-mixer
ambient-sounds diy diy-electronics dnd ttrpg
Last synced: 5 months ago
JSON representation
Mix different sound ambiances with a Pimoroni Keypad and a Raspberry Pi Pico
- Host: GitHub
- URL: https://github.com/brouberol/pico-mixer
- Owner: brouberol
- License: mit
- Created: 2022-09-16T17:40:57.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-03T16:10:31.000Z (9 months ago)
- Last Synced: 2024-08-03T17:28:48.433Z (9 months ago)
- Topics: ambient-sounds, diy, diy-electronics, dnd, ttrpg
- Language: Python
- Homepage:
- Size: 120 KB
- Stars: 21
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## Pico-mixer

This project was born after thinking that I'd really like to have something like a [Launchpad](https://novationmusic.com/en/launch/launchpad-x) 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](https://shop.pimoroni.com/products/pico-rgb-keypad-base?variant=32369517166675), as well as a [Raspberry Pi Pico](https://learn.pimoroni.com/article/getting-started-with-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](https://www.thingiverse.com/thing:4883873/files).
### Setup
The `code.py` script runs on a Raspberry Pi Pico, running [CircuitPython](https://circuitpython.org/), itself connected onto the [Pimoroni Keypad](https://shop.pimoroni.com/products/pico-rgb-keypad-base?variant=32369517166675). 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.
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.
### Limitations
The `mixer.py` script currently uses [`pygame.mixer`](https://www.pygame.org/docs/ref/mixer.html) 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](#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
As the browser is really good at streaming `` elements, the app can start immediately without having to load all audio files in memory.
### Colors
The key colors were generated from [iwanthue](https://medialab.github.io/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](https://github.com/brouberol/pico-mixer/blob/2c5acb191eb22d45affdfcc4eb21ec853d690a0e/pico/code.py#L57-L60) to the web-server at [propagated](https://github.com/brouberol/pico-mixer/blob/2c5acb191eb22d45affdfcc4eb21ec853d690a0e/pico_mixer_web/assets/js/script.js#L70-L71) 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](https://learn.adafruit.com/welcome-to-circuitpython) first.)
Open a terminal, then run the following commands:
```console
$ 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:
```console
$ 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:
```console
$ 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](https://learn.adafruit.com/welcome-to-circuitpython) 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](https://www.python.org/downloads/windows/), 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](https://blog.balthazar-rouberol.com/my-diy-dungeons-and-dragons-ambiance-mixer#isso-102) first.