/m8c-piboy

Cross-platform M8 tracker headless client, modified to run on PiBoy DMG (and Waveshare Game HAT, and other Raspberry Pi / Retropie setups)

Primary LanguageCOtherNOASSERTION

m8c-piboy

Changes (hacks) to the m8c M8 tracker client for use on

  • PiBoy DMG
    • Tested on Raspberry Pi 3 B+ with RetroPie v4.7.1
    • Tested on Raspberry Pi 4 B with the official PiBoy DMG Image.
  • WaveShare Game HAT
    • Tested on Raspberry Pi 3 B+ with RetroPie v4.8.
  • a plain old Raspberry Pi 3 B+ with RetroPie v4.8.

Let's all enjoy the M8 software in a LSDJ/GameBoy style, while we wait for the official M8 hardware (support Dirtywave, go pre-order one)!

See it in action here https://www.youtube.com/watch?v=wgCUPZheRhA

Introduction (from laamaa)

The Dirtywave M8 Tracker is a portable sequencer and synthesizer, featuring 8 tracks of assignable instruments such as FM, waveform synthesis, virtual analog, sample playback, and MIDI output. It is powered by a Teensy micro-controller and inspired by the Gameboy tracker Little Sound DJ.

While Dirtywave makes new batches of units available on a regular basis, M8 is sometimes sold out due to the worldwide chip shortage and high demand of the unit. To fill this gap and and to allow users to freely test this wonderful tracker, Timothy Lamb was kind enough to make the M8 Headless available to everyone.

If you like the M8 and you gel with the tracker workflow, please support Dirtywave by purchasing the actual unit. You can check its availability here. Meanwhile, you can also subscribe to Timothy Lamb's Patreon.

m8c is a client for Dirtywave M8 tracker's headless mode. m8c-piboy is a fork of m8c for running on PiBoy-DMG, WaveShare Game HAT, and other hardware configurations running RetroPie.

Notable changes

Thanks to

Requirements

  • A working m8 headless setup on a Teensy 4.1
  • A working Raspberry Pi / Retropie setup on one of the following handheld hardware:
    • PiBoy DMG, see the PiBoy DMG Getting Started guide
    • Waveshare Game HAT, see the Game HAT Wiki and manual
    • a plain old Raspberry Pi 3 B+
    • other systems may work but will need additional support, e.g. you get it working and share your findings with us, or you can send me some hardware so I might get is working =]

Installation

building from source

These instructions are tested with Raspberry Pi 3 B+ and the official RetroPie distribution.

The instructions assume that you already have a working Retropie installation with an internet connection.

Open Terminal or SSH into you Pi and run the following commands:

Install required packages

sudo apt update && sudo apt install -y git gcc make libsdl2-dev

Build and install libserialport from source

Required since the libserialport-dev apt package is out of date

follow the README at https://github.com/sigrokproject/libserialport

then run

sudo ldconfig

to ensure the library is found when building m8c

Download source code

mkdir ~/code && cd ~/code
git clone https://github.com/rasprague/m8c-piboy.git

Build the program

cd m8c-piboy
make

Make shell scripts user executable

chmod u+x m8c*.sh

Start m8c once to generate config files

/home/pi/code/m8c-piboy/m8c-nojack.sh

then Ctrl-C to quit

Enable built-in controller support

A line to make the PiBoy (and Game Hat) built-in controller visible to SDL has been added to gamecontrollerdb.txt, we just need to point m8c to it.

cd ~/.local/share/m8c
rm gamecontrollerdb.txt
ln -s ~/code/m8c-piboy/gamecontrollerdb.txt .

Optional: swap A and B buttons

in ~/.local/share/m8c/config.ini

change

gamepad_opt=1
gamepad_edit=0

to

gamepad_opt=0
gamepad_edit=1

Optional: fix cursor movement

if your cursor movement is messed up, set these two entries in ~/.local/share/m8c/config.ini

gamepad_analog_axis_select=-1
gamepad_analog_axis_start=-1

Optional: disable mouse cursor

in ~/.local/share/m8c/config.ini

under the [graphics] section, add disable_cursor=true

Install JACK for audio routing

See AUDIOGUIDE.md for the details

sudo apt install jackd2
sudo usermod -a -G audio pi

Optional: allow JACKD to use realtime scheduling

sudo mv /etc/security/limits.d/audio.conf.disabled /etc/security/limits.d/audio.conf

then restart your system

Try it out!

/home/pi/code/m8c-piboy/m8c.sh

Adding m8c to EmulationStation

Install m8c 'ROMs'

mkdir -p /home/pi/RetroPie/roms/m8 && cd /home/pi/RetroPie/roms/m8
ln -s /home/pi/code/m8c-piboy/*.sh .

Add m8 system entry

  • go to /home/pi/.emulationstation/
  • append the contents of this repo's file es_systems.cfg.m8c.paste.txt to the bottom of es_systems.cfg (just before the </systemList> line) in that folder (/home/pi/.emulationstation/es_systems.cfg)

If you don't already have an es_systems.cfg file in /home/pi/.emulationstation/, first copy the es_systems.cfg file that's in /etc/emulationstation/ into /home/pi/.emulationstation/.

  • restart EmulationStation

This adds "m8" to your EmulationStation game console selection menu.

Using a different audio output device (e.g. external USB sounds card)

You have a couple of options

Choose audio interface at startup

run m8c-choose.sh and choose you audio interface options from the dialogs

Make a custom startup script

  • find your audio device number with aplay -l
pi@retropie:~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 1: CODEC [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0
card 2: M8 [M8], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

here we'll use card 1 as an example

  • in the m8 roms folder, make a copy of m8c-custom.sh.example, e.g.
cd ~/RetroPie/roms/m8
cp ~/code/m8c-piboy/m8c-custom.sh.example ./m8c-usbaudio.sh
  • edit your new .sh file (e.g. m8c-usbaudio.sh), and at the top change e.g. HWAUDIODEVICE=0 to HWAUDIODEVICE=1
  • Optioinal: enable audio input (if your audio interface supports it) by changning ENABLEINPUT=0 to ENABLEINPUT=1
  • make your new .sh file (e.g. m8c-usbaudio.sh) executable with chmod u+x m8c-usbaudio.sh
  • restart EmulationStation

orignal m8c README below

m8c

Introduction

The Dirtywave M8 Tracker is a portable sequencer and synthesizer, featuring 8 tracks of assignable instruments such as FM, waveform synthesis, virtual analog, sample playback, and MIDI output. It is powered by a Teensy micro-controller and inspired by the Gameboy tracker Little Sound DJ.

While Dirtywave makes new batches of units available on a regular basis, M8 is sometimes sold out due to the worldwide chip shortage and high demand of the unit. To fill this gap and and to allow users to freely test this wonderful tracker, Timothy Lamb was kind enough to make the M8 Headless available to everyone.

If you like the M8 and you gel with the tracker workflow, please support Dirtywave by purchasing the actual unit. You can check its availability here. Meanwhile, you can also subscribe to Timothy Lamb's Patreon.

m8c is a client for Dirtywave M8 tracker's headless mode. The application should be cross-platform ready and can be built in Linux, Windows (with MSYS2/MINGW64) and Mac OS.

Please note that routing the headless M8 USB audio isn't in the scope of this program -- if this is needed, it can be achieved with tools like Pipewire, Pulseaudio, Jack w/ alsa_in and alsa_out just to name a few. The file AUDIOGUIDE.md contains some examples for routing the audio.

If you want to route audio with the headless client you could try https://github.com/booss/rm8 which is a great native client with audio support (among other user features)!

Many thanks to:

  • Trash80 for the great M8 hardware and the original font (stealth57.ttf) that was converted to a bitmap for use in the progam.
  • driedfruit for a wonderful little routine to blit inline bitmap fonts, https://github.com/driedfruit/SDL_inprint/
  • marcinbor85 for the slip handling routine, https://github.com/marcinbor85/slip
  • turbolent for the great Golang-based g0m8 application, which I used as reference on how the M8 serial protocol works.
  • Everyone who's contributed to m8c!

Disclaimer: I'm not a coder and hardly understand C, use at your own risk :)


Installation

Windows / MacOS

There are prebuilt binaries available in the releases section for Windows and recent versions of MacOS.

Linux / MacOS (building from source)

These instructions are tested with Raspberry Pi 3 B+ and Raspberry Pi OS with desktop (March 4 2021 release), but should apply for other Debian/Ubuntu flavors as well. The begining on the build process on OSX is slightly different at the start, and then the same once packages are installed.

The instructions assume that you already have a working Linux desktop installation with an internet connection.

Open Terminal and run the following commands:

Install required packages (Raspberry Pi, Linux)

sudo apt update && sudo apt install -y git gcc make libsdl2-dev libserialport-dev

Install required packages (OSX)

This assumes you have installed brew

brew update && brew install git gcc make sdl2 libserialport pkg-config

Download source code (All)

mkdir code && cd code
git clone https://github.com/laamaa/m8c.git

Build the program

cd m8c
make

Start the program

Connect the M8 or Teensy (with headless firmware) to your computer and start the program. It should automatically detect your device.

./m8c

If the stars are aligned correctly, you should see the M8 screen.


Keyboard mappings

Keys for controlling the progam:

  • Up arrow = up
  • Down arrow = down
  • Left arrow = left
  • Right arrow = right
  • a / left shift = select
  • s / space = start
  • z / left alt = opt
  • x / left ctrl = edit

Additional controls:

  • Alt + enter = toggle full screen / windowed
  • Alt + F4 = quit program
  • Delete = opt+edit (deletes a row)
  • Esc = toggle keyjazz on/off
  • r / select+start+opt+edit = reset display (if glitches appear on the screen, use this)

Keyjazz

Keyjazz allows to enter notes with keyboard, oldschool tracker-style. The layout is two octaves, starting from keys Z and Q. When keyjazz is active, regular a/s/z/x keys are disabled. The base octave can be adjusted with numpad star/divide keys and the velocity can be set

  • Numpad asterisk (*): increase base octave
  • Numpad divide (/): decrease base ooctave
  • Numpad plus (+): increase velocity
  • Numpad minus (-): decrease velocity

Gamepads

The program uses SDL's game controller system, which should make it work automagically with most gamepads. On startup, the program tries to load a SDL game controller database named gamecontrollerdb.txt from the same directory as the config file. If your joypad doesn't work out of the box, you might need to create custom bindings to this file, for example with SDL2 Gamepad Tool.

Config

Keyboard and game controller bindings can be configured via config.ini.

If not found, the file will be created in one of these locations:

  • Windows: C:\Users\<username>\AppData\Roaming\m8c\config.ini
  • Linux: /home/<username>/.local/share/m8c/config.ini
  • MacOS: /Users/<username>/Library/Application Support/m8c/config.ini

See the config.ini.sample file to see the available options.

Enjoy making some nice music!


FAQ

  • When starting the program, something like the following appears and the program does not start:
$ ./m8c
INFO: Looking for USB serial devices.
INFO: Found M8 in /dev/ttyACM1.
INFO: Opening port.
ERROR: Error: Failed: Permission denied

This is likely caused because the user running m8c does not have permission to use the serial port. The eaiest way to fix this is to add the current user to a group with permission to use the serial port.

On Linux systems, look at the permissions on the serial port shown on the line that says "Found M8 in":

$ ls -la /dev/ttyACM1
crw-rw---- 1 root dialout 166, 0 Jan  8 14:51 /dev/ttyACM0

This shows that the serial port is owned by the user 'root' and the group 'dialout'. Both the user and the group have read/write permissions. To add a user to the group, run this command, replacing 'dialout' with the group shown on your own system:

sudo adduser $USER dialout

You may need to log out and back in or even fully reboot the system for this change to take effect, but this will hopefully fix the problem. Please see this issue for more details.


Bonus content: quickly install m8c locally with nix

nix-env -iA m8c-stable -f https://github.com/laamaa/m8c/archive/refs/heads/main.tar.gz