The VS1053 and VS1003 audio codecs support real time MIDI. While the VS1003 only provides a few instruments, the VS1053 has 128 melodic instruments and quite a few additional percussion instruments!

When GPIO0 is low and GPIO1 is high during boot, real-time MIDI mode is activated. Unfortunately these pins are not available on most breakout boards. In this case a patch can be used to activate it.

When real time MIDI is active, you can send MIDI messages directly to the serial VS1003 input pin, but this is not available most of the time either. Fortunately you can also send the data via SPI, you just need to make sure that each MIDI byte is received as 2 byte word. I have extended my driver library to perform this conversion automatically. So with this we can use any MIDI Library that supports the output to Arduino Streams. Fortunately I have implemented such a library quite some time ago.

Example

Here is a simple example

#include "AudioTools.h"
#include "AudioLibs/VS1053Stream.h"
#include "Midi.h"


VS1053Stream vs1053; // final output
MidiStreamOut midi_out(vs1053);
uint8_t note = 65; // 0 to 128
uint8_t amplitude = 128; // 0 to 128
uint8_t instrument = 0;

void selectInstrument(uint8_t instrument, uint8_t bank=0x00){
  midi_out.controlChange(BANK_SELECT, bank);
  // Patch change, select instrument
  midi_out.programChange(instrument);
}

void setup() {
    Serial.begin(115200);
    AudioLogger::instance().begin(Serial, AudioLogger::Info);  

 // setup vs1053
  auto cfg = vs1053.defaultConfig();
  cfg.is_midi = true; // vs1053 is accepting streaming midi data
  // Use your custom pins or define in AudioCodnfig.h
  //cfg.cs_pin = VS1053_CS; 
  //cfg.dcs_pin = VS1053_DCS;
  //cfg.dreq_pin = VS1053_DREQ;
  //cfg.reset_pin = VS1053_RESET;
  vs1053.begin(cfg);
  vs1053.setVolume(1.0);

}

void loop() {
    Serial.println();
    Serial.print("playing ");
    Serial.println(++note);

    midi_out.noteOn(note, amplitude );
    delay(900);
    midi_out.noteOff(note, 20 );
    delay(200);
    if (note>=90) {
      note = 64;
      Serial.println();
      Serial.print("selecting Instrument ");
      Serial.println(++instrument);
      selectInstrument(instrument);
    }
}

As you can see we just need to give a VS1053Stream object as argument to a MidiStreamOut object!
This and further vs1053 examples can be found on Github.

Dependencies

You need to install the following libraries:

Final Comments

So far I could only test this on a VS1003 since I don’t have any working VS1053 yet.


10 Comments

sr · 5. December 2022 at 22:13

Hi!

I am trying to set up this example in my project, but I am unable to make it work. I included all the above libraries in Arduino IDE, but when I try to compile the sketch, I get this error messages from the arduino-audio-tools library:

/Arduino/libraries/arduino-audio-tools-main/src/AudioBasic/Collections/List.h:111:35: error: expected ')' before '<' token
List(std::initializer_list<T> iniList) {

and

/Arduino/libraries/arduino-audio-tools-main/src/AudioTools/AudioStreams.h:59:18: error: 'virtual size_t audio_tools::AudioStream::readBytes(uint8_t*, size_t)' marked 'override', but does not override
virtual size_t readBytes(uint8_t *buffer, size_t length) override = 0;

I am using ARM Macbook. I also had some issues with arduino-midi library, where #include <sys/time.h> (https://github.com/pschatzmann/arduino-midi/blob/main/src/apple-midi/applemidi.c) is not valid on macos, But I managed to fix this by changing it to #include <time.h>.

Do you have any suggestions what I might be doing wrong? What the issues might be and how to fix it?

Any advice would be appreciated!

    pschatzmann · 5. December 2022 at 22:34

    If it is an ESP32 make sure that you selected the latest version in the Board Manager.
    If this did not help, please file an issue on Github….

      sr · 5. December 2022 at 22:47

      No its the Arduino UNO.. I tried now also with the ESP8266 and get a different error https://drive.google.com/file/d/13G8CuBZBWEZ-cA2qZdwGX05407Vil4iu/view?usp=sharing. I currently don’t have any ESP32’s by hand to test it also there.

      sr · 5. December 2022 at 22:51

      No I am using Arduino UNO. I also tested it on ESP8266 now, but get a different error message (https://drive.google.com/file/d/13G8CuBZBWEZ-cA2qZdwGX05407Vil4iu/view?usp=share_link). I currently don’y have any ESP32’s by hand to test it also there…

        pschatzmann · 6. December 2022 at 1:07

        I just committed some corrections to address your issues…

          sr · 6. December 2022 at 9:47

          The above issues are now resolved yes! But I still get some errors, now inside the WiFi library that you are using inside your lib. I think the problem is that I am using ESP8266 which demands its own ESP8266WiFi library. I will first wait till I get my ESP32 and test it there, and if I will encounter problems, I will make a fork and try to fix it myself. Thanks for now!

          pschatzmann · 6. December 2022 at 10:27

          You need to update the Midi library as well…

          sr · 6. December 2022 at 13:35

          Yes, it compiles now! Thanks!

Den · 8. November 2022 at 20:52

Compiling errors, missing libs etc

    pschatzmann · 8. November 2022 at 20:54

    It wount work if you don’t install all libraries that are indicated in the section dependencies!

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *