thejohncotton

thejohncotton

I’ve been having a lot of discussions around using MIDI on a nerves device and wanted to start a thread to discuss some of it in the open so that it is easier to help others in the same discussion.

I have midi 1.0 working in nerves with Circuits.UART and some diy hardware. I need to publish a public repo with the UART Framing (will be sharing soon).

Some of the more interesting discussions and my current interest are around working with USB midi.

GitHub - haubie/midiex: Cross platform Midi library in Elixir. Powered by midir, a Rust midi library and Rustler. · GitHub looks like it could be really close to what we would want in terms of portability but I’m having issues getting it to run on my nerves system (raspberry pi4 but slightly modified)
I’ve got some debugging to do on that test but wanted to consider other options too. Particularly anything lightweight.

Showing Posts 1 to 10

octetta

octetta

I’m just starting to look at “official” MIDI on Linux because like you, I’ve just always rolled my own UART implementation and avoided USB altogether.

That being said, without having looked at midiex (which looks pretty nice on via my desktop+Elixir), I wonder if there are missing pieces in your Nerves system that it’s looking for…

It appears ALSA and MIDI depend on kernel modules that aren’t part of a basic Nerves system, notably snd_usbmidi_lib.

Can you get to the iex shell on your Nerves system and type:

cmd "lsmod"

…and see if that module is loaded?

Also, try running “dmesg” to see if your USB MIDI module is detected when it’s plugged in.

Oh, and another question… what USB/MIDI interface are you using?

octetta

octetta

As I fumble with ALSA and MIDI, this doc is useful, at least on my Raspbian system where aconnect and aseqdump work.

Since I’ve yet to build a Nerves system from scratch, I do wonder where the options to include this ALSA stuff lives. The basic audio stuff is loaded on the Nerves fleet distro on the boxes I’ve set up for Lars…

entone

entone

It hasn’t seen any development in a long time, but the Firmata protocol is based on MIDI so maybe can get some insight here GitHub - entone/firmata: Firmata protocol in Elixir · GitHub

It does support USB MIDI. EDIT… yeah this is just using UART, so probably not what you’re looking for.

entone

entone

fhunleth

fhunleth

Co-author of Nerves

In addition to the other options, there’s the Sonic Pi MIDI library at GitHub - sonic-pi-net/sp_midi: MIDI functionality for Sonic Pi for use as Erlang module · GitHub. It looks self-contained and lightweight, but would need a little modification to build with mix and be easier to use with an Elixir/Nerves project.

octetta

octetta

Just pulling this code now… it looks like it wraps RtMidi, which in turn (under Linux at least) links with ALSA and/or JACK libraries.

For simple and non-portable stuff, I think this is possible with much less code using ALSA directly, but I bet it’ll still depend on a Linux build with ALSA MIDI stuff included.

ChatGPT gave me a very simple snip of code to enumerate the visible MIDI ports which I built and ran on my Raspbian RPi3 device to show my Arturia Beatstep pads:

pi@co2:~ $ ./listmidi 
MIDI Device: Midi Through
Port: Midi Through Port-0
MIDI Device: Arturia BeatStep
Port: Arturia BeatStep MIDI 1

Code courtesy ChatGPT (build via gcc listmidi.c -o listmidi -lasound … you might need to sudo apt install libasound2-dev to build) :

#include <stdio.h>
#include <alsa/asoundlib.h>

int main() {
    int status;
    snd_seq_t *seq_handle;
    snd_seq_client_info_t *cinfo;
    snd_seq_port_info_t *pinfo;

    // Open ALSA sequencer
    status = snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_DUPLEX, 0);
    if (status < 0) {
        printf("Error opening ALSA sequencer.\n");
        return 1;
    }

    // Allocate space for client and port info
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_port_info_alloca(&pinfo);

    // Iterate over all clients (devices)
    snd_seq_client_info_set_client(cinfo, -1);
    while (snd_seq_query_next_client(seq_handle, cinfo) >= 0) {
        int client = snd_seq_client_info_get_client(cinfo);

        // Iterate over all ports for the client
        snd_seq_port_info_set_client(pinfo, client);
        snd_seq_port_info_set_port(pinfo, -1);
        while (snd_seq_query_next_port(seq_handle, pinfo) >= 0) {
            if (snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_SUBS_WRITE) {
                printf("MIDI Device: %s\n", snd_seq_client_info_get_name(cinfo));
                printf("Port: %s\n", snd_seq_port_info_get_name(pinfo));
            }
        }
    }

    snd_seq_close(seq_handle);
    return 0;
}

On my unmodified “Lars fleet RPi3”, this binary isn’t able to find the symbol snd_seq_open so I suspect buildroot/??? left pieces of ALSA out.

One of these days I should actually build a system from scratch instead of hoping someone else will do it for me, :slight_smile:

octetta

octetta

I’m questioning my sanity regarding USB/MIDI devices on Linux.

However I have evidence (old Python scripts) that indicate at one time my Arturia BeatStep USB/MIDI device showed up as both a serial device (under a /dev/ttyUSB# scheme) and under /dev/midi#.

The world seems to be changing under my feet and I have no knowledge of udev and friends, so could it be possible that the /dev/ttyUSB# device could still be available with some fiddling of configuration?

I’ll wander off and do my own research, but thought I’d mention it here, since dealing with these devices as UART drags a lot less baggage than ALSA and / or libusb (which I’ve already spent way more time on than I thought I would, LOL).

octetta

octetta

There’s evidence that udev can map USB MIDI devices to serial ports… just need to see if it’s more work than ALSA or libusb. Stay tuned…

thejohncotton

thejohncotton OP

Interestingly enough my problem with getting the rustler deps to load was related to this thread:

@octetta It did end up being an issue related to buildroot but also an operator error. (I’ll push up some code this afternoon after work to show the specifics)

@fhunleth when I included the extra alsa packages and blew my system away and rebuilt it I was able to get the midiex dependency to work on the firmware. I’ll run some more tests and confirm it actually works later but this is pretty cool.

Would you want some of these extra deps included in the official system? I’m going to publish my fork for audio/midi but could also just contribute back if you think it would be useful.

BR2_PACKAGE_ALSA_UTILS=y
BR2_PACKAGE_ALSA_UTILS_ALSACONF=y
BR2_PACKAGE_ALSA_UTILS_ACONNECT=y
BR2_PACKAGE_ALSA_UTILS_ALSALOOP=y
BR2_PACKAGE_ALSA_UTILS_ALSAUCM=y
BR2_PACKAGE_ALSA_UTILS_ALSATPLG=y
BR2_PACKAGE_ALSA_UTILS_AMIDI=y
BR2_PACKAGE_ALSA_UTILS_AMIXER=y
BR2_PACKAGE_ALSA_UTILS_APLAY=y
BR2_PACKAGE_ALSA_UTILS_APLAYMIDI=y
BR2_PACKAGE_ALSA_UTILS_ARECORDMIDI=y
BR2_PACKAGE_ALSA_UTILS_ASEQDUMP=y
BR2_PACKAGE_ALSA_UTILS_ASEQNET=y
BR2_PACKAGE_ALSA_UTILS_BAT=y
BR2_PACKAGE_ALSA_UTILS_IECSET=y
BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST=y
octetta

octetta

@thejohncotton I really like that more of ALSA stuff is possible… and I’ll probably pursue something in the vein of an Erlang port driver for MIDI stuff. I have a half-baked POC port driver for audio sampling and playback that I hope to share soon (targeting the Nerves meetup in November).

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews