- Notifications
You must be signed in to change notification settings - Fork 124
Development
This page contains information relevant for developers.
This is the quickest way to start coding without having to set up software locally. Click on

Paste (Command-SHIFT-V) the following:
git checkout i2c # if you want to edit a particular branch git submodule update --init --recursive sh -ex submod.sh # Get particular git commits of the submodules wget -q https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz tar xf *-aarch64-none-elf.tar.xz # wget -q https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi.tar.xz # tar xf *-arm-none-eabi.tar.xz export PATH=$(readlink -f ./gcc-*aarch64-none*/bin/):$PATH RPI=3 bash -ex build.sh # To rebuild cd src/ make -j4 Normal users do not need to build the source code, as compiled versions are provided for download. If you are a developer and want to build the source code yourself, you can use the following example, e.g., to build for Raspberry Pi 4 on a Ubuntu 20.04 build system. See build.yml for complete build steps that create versions for Raspberry Pi 1, 2, 3,and 4 in 32-bit and 64-bit as required.
# Choose your RPi export RPI=4 git clone https://github.com/probonopd/MiniDexed cd MiniDexed mkdir -p kernels sdcard # Recursively pull git submodules git submodule update --init --recursive # Get particular git commits of the submodules sh -ex submod.sh # Install toolchain if [ "${RPI}" -gt 2 ] then wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz else wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi.tar.xz fi tar xvf gcc-arm-*-*.tar.xz export PATH=$(readlink -f ./gcc-*/bin/):$PATH # Build dependencies and MiniDexed ./build.sh cp ./src/kernel*.img ./kernels/ # Get Raspberry Pi boot files cd ./circle-stdlib/libs/circle/boot make if [ "${RPI}" -gt 2 ] then make armstub64 fi cd - # Make zip that contains Raspberry Pi 4 boot files. The contents can be copied to a FAT32 formatted partition on a microSD card cd sdcard ../getsysex.sh cd .. cp -r ./circle-stdlib/libs/circle/boot/* sdcard rm -rf sdcard/config*.txt sdcard/README sdcard/Makefile sdcard/armstub sdcard/COPYING.linux cp ./src/config.txt ./src/minidexed.ini ./src/*img ./src/performance.ini sdcard/ echo "usbspeed=full" > sdcard/cmdline.txt cd sdcard cp ../kernels/* . || true zip -r ../MiniDexed_$GITHUB_RUN_NUMBER_$(date +%Y-%m-%d).zip * cd - # Optionally, create a RPi image. This can be written to a microSD card using tools like Etcher or dd sudo apt install --yes mount parted IMG="`date +%Y-%m-%d`_minidexed-RPi${RPI}.img" dd of="${IMG}" seek=50MiB bs=1 count=0 sudo parted "${IMG}" mktable msdos sudo parted "${IMG}" mkpart primary fat32 2048s 100% DEV=`sudo losetup --find --partscan --show "${IMG}"` sudo mkfs.vfat -F 32 -n BOOT "${DEV}p1" mkdir boot sudo mount "${DEV}p1" boot sudo cp -R sdcard/* boot sudo umount boot sudo losetup -d "${DEV}" rm -r boot # Write to SD card sudo dd if="${IMG}" of=/dev/mmcblk0 bs=512k status=progress && sync During development, it can be very beneficial to update over the network, like this:
make -j && ../updater.py --ip 192.168.xxx.xxx --version 3 && ../syslogserver.py An alternative way is to boot the kernel directly over the network. For this, the MiniDexed does not even need to have networking enabled.
https://github.com/probonopd/CircleNetboot can be used to boot images over the network without the need to swap SD cards for each build.
Use mLogger.Write() like in this example to output diagnostic messages to the HDMI screen during development:
Don't output debug messages during normal operation, as this can negatively impact the sound quality on some Raspberry Pi models.
HINT: to better debug early events, place only one "sysex voice" to have more messages printed.
Different log levels can be used. There is an option loglevel= in the file cmdline.txt on the SD card which controls the amount of generated log messages. Please note that in MiniDexed, log messages will not be displayed from IRQ_LEVEL by default, because it uses the REALTIME option. For debugging purpose you may have to disable this option in build.sh before build if you want to see messages from IRQ handlers.
MiniDexed is based on Circle, a C++ bare metal environment for Raspberry Pi with USB (32 and 64 bit). Thanks to @rsta2 and contributors for this useful framework, without which MiniDexed would not exist.
The following naming conventions are used:
- Identifiers for types and variables will be written this way: "MyExampleIdentifier" (each word starts with an uppercase letter).
- Class names start with a "C", other types (struct, enum) with a "T".
- Member variable names of a class start with a "m_", static variables in a class definition with a "s_".
- Variable names get a prefix, which specify its (simple) standard type. This prefix follows the "m_" or "s_", if it is used. Variables of complex types do not have such prefix (except a "p" for pointer). Only one of these prefixes is used (i.e. "puch" for a pointer to an unsigned char is not used, use only "p" instead):
uch unsigned char, u8, uint8_t us unsigned short u16, uint16_t ul unsigned long ch signed char, s8, int8_t s signed short, s16, int16_t l signed long n unsigned, int, u32, s32, uint32_t, int32_t, or any other (non-float) numeric variable f float, double b bool, boolean p Pointer to a simple or complex type MiniDexed is calling into Synth_Dexed for the actual synthesizer functionality. Thanks to @dcoredump and contributors for this useful library, without which MiniDexed would not exist.
From time to time, developers need to update a git submodule, such as Synth_Dexed. If the submodule should be updated on an incoming pull request, then one actually needs to do the change in the respository and on the branch from which the pull request originates (example: a pull request came from https://github.com/rsta2/MiniDexed/, branch enable-filter and we want to update the Synth_Dexed git submodule to c58ac7c):
git clone https://github.com/rsta2/MiniDexed/ cd MiniDexed git checkout enable-filter git submodule update --init --recursive cd Synth_Dexed git fetch git checkout c58ac7c cd .. git add Synth_Dexed git commit -m "Update Synth_Dexed" git push origin enable-filter On a V1 Raspberry Pi (single core) naturally all functions have to be run from within the same core process, but on a multi-core Raspberry Pi, the cores are used as follows:
- Core 0: Initalization; IO (MIDI, buttons, encoders, etc) and user interface handling.
- Core 1: Two tone generators; mixing; effects; audio output
- Core 2: Three tone generators
- Core 3: Three tone generators
The following are the main code modules and classes to make all this happen:
- main.cpp: starts the Circle kernel.
- kernel.cpp: the main boot initialization code and the main Run process.
- minidexed.cpp: the main synthesizer logic: key functions being Initialize(), Process(), Run() (if on a multi-core Raspberry Pi), and ProcessSound().
- userinterface.cpp: handles the main UI IO and display: key functions being Initialize(), Process(), DisplayWrite() and event handlers for the encoder and buttons.
- uimenu.cpp: the main UI event handler that either acts on menu events from the UI code; navigates through the user interface menus; or acts on menu items Handler() functions.
The main threads of execution and linkage are shown semi-graphically below.
