MIDI Synth Unit (SAM2695) - assigning different voices to different channels.



  • I just got my hands on the M5 SAM2695 unit, which I think is super fun.

    I've stumbled upon an issue which I'd hope the community could help me with.
    Namely, I would expect the following sequence of MIDI events:

    ProgramChange(patch=<instrument A>, channel=0)
    ProgramChange(patch=<instrument B>, channel=1)
    NoteOn(channel=0, note=60)
    NoteOn(channel=1, note=64)
    

    To play the first note using instrument A and the second using instrument B. Instead, however, it seems to play both notes using whatever instrument was used in the most recent call to ProgramChange, irrespectively of any channel numbers.

    Am I misunderstanding the MIDI API, do I need to set some configuration setting for SAM2695 specifically, or is it a bug in the API implementation of the SAM2695?

    I am using CircuitPython (on an AtomS3 Lite) with Adafruit's MIDI library (which seems to send the right commands). Here's an actual code example:

    import board
    import busio
    import time
    
    import adafruit_midi
    from adafruit_midi.note_on import NoteOn
    from adafruit_midi.note_off import NoteOff
    from adafruit_midi.program_change import ProgramChange
    from adafruit_midi.system_exclusive import SystemExclusive
    
    uart = busio.UART(tx=board.D2, baudrate=31250, bits=8, parity=None, stop=1)
    midi = adafruit_midi.MIDI(midi_out=uart, out_channel=0)
    
    midi.send(SystemExclusive([0x7e, 0x7f], [0x09, 0x01])) # Reset
    midi.send(SystemExclusive([0x7f, 0x7f, 0x04], [0x01, 0x00, 123 & 0x7f])) # Volume 123
    
    midi.send(ProgramChange(patch=108, channel=0)) # Kalimba
    midi.send(ProgramChange(patch=0, channel=1)) # Piano
    # I'd expect to hear first Kalimba then Piano
    # but both notes are played using Piano
    midi.send(NoteOn(channel=0, note=60))
    time.sleep(0.5)
    midi.send(NoteOn(channel=1, note=64))
    time.sleep(1)
    
    # Same PC events, just in different order
    midi.send(ProgramChange(patch=0, channel=1)) # Piano
    midi.send(ProgramChange(patch=108, channel=0)) # Kalimba
    # Now both are played using Kalimba
    midi.send(NoteOn(channel=0, note=60))
    time.sleep(0.5)
    midi.send(NoteOn(channel=1, note=64))
    

    I went through the datasheet as well as I could but did not find anything helpful yet.



  • OK, I figured it out, the problem was due to Adafruit's library strange decision to overwrite the channel field of the message in the send method by its own parameter.

    So,

    midi.send(SomeMessage(..., channel=X))
    

    should always be used as

    midi.send(SomeMessage(...), channel=X)
    

    instead. Then everything works as intended.



  • Thanks for working it out and sharing your results