daft-engineers / vocoder

Open source vocoder designed for the Raspberry Pi.
https://daft-engineers.github.io/vocoder/
Mozilla Public License 2.0
11 stars 0 forks source link
audio-processing music realtime

Header

We are building a vocoder, which is a vocal effect that combines your voice with a sound wave. The result is a unique sound used in popular songs like Daft Punk's "Harder, Better, Faster, Stronger" (the inspiration for our name), or ELO's "Mr. Blue Sky".

Pre-requisites:

To build just the vocoder itself you will need:

Additionally, to run the unit tests and static analysis suite, LLVM 15 + Tools is required. To install this on debian the automatic script from their website can be used.

To build the doxygen documentation, the doxygen and graphviz packages are required.

Getting started:

We recommend the following to get started from scratch (requires 1GB+ of storage):

sudo apt update
sudo apt install wget gpg build-essential cmake libasound2-dev software-properties-common lsb-release gnupg
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 15 all
sudo ln -s /usr/lib/llvm-15/bin/clang{,++,-format,-tidy} /usr/local/bin

Python 3 is required to automatically build and link unit tests. Python 3 comes preinstalled on most Linux distributions, and is available as a package on all others.

Although not essential, to aid performance, we recommend running the OS in the non GUI mode. This can be achieved by running:

sudo raspi-config

Selecting: 1 System Options >> S5 Boot / Auto Login >> B2 Console Autologin. Reboot and enjoy the resource saving.

Hardware setup:

The Codec Zero should be wired up with the microphone on the left input channel and the synth on the right input channel of the auxilliary input. The Headphones or speaker shoudld be wired to either or both channels of the auxilliary output.

Circuit diagram

For testing, a Shure SM58 was chosen as the microphone (using pin 2 and 3 on the XLR connector) and a software synthesizer on a PC was used as the synthesizer. A portable speaker was used as the output device. If a low sensitivity microphone is used it may need to be amplified with an external amplifier. The volume of the microphone can balanced with the synthesizer by changing the microphone gain argument when running the program.

To allow the connected devices to be changed easily, standardised connectors should be used for the inputs and outputs. Following standard convention, an XLR connector should be used for the microphone and a 1/4" TRS jack should be used for the synthesizer in and audio output.

Hardware

Configuring the Codec Zero:

The Codec zero must be set up to be used with alsa. The easiest way is to use the scripts provided on the IQAudio github.

To find which sound card the Codec Zero is showing up as, run the following command and look for the IQAudio device, and note its card number.

aplay --list-devices 

Using your newly found number run the following where 'x' is the card number (probably 2 or 3)

git clone https://github.com/iqaudio/Pi-Codec.git
sudo alsactl restore -f Pi-Codec/IQaudIO_Codec_AUXIN_record_and_HP_playback.state x 

If you would like to test if the Codec Zero is working correctly, a pre recorded test sound can be played using:

aplay -D "hw:x,0,0" test.wav # where x is the card number

For more advanced setup information (including automatic setup and default device) see the guidance on the Raspberry Pi website..

Software setup:

Once you have installed the prerequisites and configured your hardware you should clone the repository and run the setup script.

git clone https://github.com/daft-engineers/vocoder.git
cd vocoder
chmod +x setup.sh
./setup.sh

The project is now ready to be built.

cd build/unit_tests
make
ctest

Running the Vocoder:

The vocoder can be run with:

cd build/src 
./vocoder 

If you need to change the input and ouput devices (default "hw:2,0,0") they can be changed with the -i and -o command respectively.

./vocoder -i "hw:x,0,0" -o "hw:x,0,0" # where 'x' is the card number of the device

If a microphone gain adjustment is required, a gain argument can be added to the command (default 10)

./vocoder -g 10

Running our validation suite:

As well as using the GoogleTest framework to provide unit and integration tests, we also use clang-tidy for static analysis and clang-format to ensure code meets style standards. To run the static analysis and style tests use:

chmod +x checks.sh
./checks.sh

This will run static analysis and return any errors found. It will also reformat the code in-place to meet our style guidelines, which are based on the LLVM guidelines. If you would like to check if the code meet style guideline without it being updated in place, then the flag --formatting can be passed to the script.

Documentation:

Documentation for main can be found here.

If you want to generate the documentation for yourself, the doxygen and graphviz packages are required. These can be installed with the following command on ubuntu:

sudo apt install doxygen graphviz

With all the required dependences, from the root of the project, the command

doxygen Doxyfile

generates the documentation, and then the page can be opened by navigating to docs/html/ and opening index.html

Social Media:

Program Design:

Sequence Diagram

sequence diagram for vocoder

Sequence diagram generated with TikZ-UML library, source is available upon request.

Project management

Regualar scrum meetings were held through the project, notes are available here.

The project uses github's issue system for management. The project board is located here. Image

Contributions

Contributions must be made in the form of a pull request and must pass the unit tests and validation suite. Any contrbutions must be licenceable under the MPL 2.0.

Licence

The project is licenced under the Mozilla Public License Version 2.0. More details can be found in the licence file, and here.

Continuous integration

The project has a fleshed out continuous integration pipeline run on a Raspberry Pi. On every push and pull request, the project is built, the static analysis and formatting is run, and unit tests are run. Only on a successful merge to the main branch, the hosted documentation is updated. The image below shows the workflow for a standard push.

Image

Nightly, a more extensive test suite is run. This suite takes too long to run on every commit, but is valuable for finding threading bugs in particular.

Image

Filter

The project uses Bernd Porr's IIR filter implementation.