VS1053 Breakout board - MIDI Patch Code

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
carlw
 
Posts: 26
Joined: Mon Apr 09, 2012 9:10 am

VS1053 Breakout board - MIDI Patch Code

Post by carlw »

I'm using the Adafruit VS1053 breakout board and an Arduino MEGA.

For the MIDI mode - I'm using hardware serial port 2 TX on the MEGA (pin 16) and pin 14 on the MEGA attached to RST on the breakout. All the other pin assignments are per the breakout board documentation.

I'd like to switch between MIDI and MP3 player without unhooking the GPIO0 and GPIO1 pins on the breakout board.
A reset of the MEGA would be ok. The user would have an option of using the MIDI sound or a sound stored in MP3 format on the micro SD card. I'd store the selection in EEPROM and start up in the appropriate mode (if this is possible)

Page 59 on the VS1053 datasheet states "Real-Time MIDI can also be started with a small patch code using SCI."
This I don't understand.

:?: Is it possible to boot up in MIDI mode without using the GPIO0 and GPIO1 pins on the breakout board?

Thanks,

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: VS1053 Breakout board - MIDI Patch Code

Post by adafruit_support_bill »

Page 59 on the VS1053 datasheet states "Real-Time MIDI can also be started with a small patch code using SCI."
Check this page for available patches: http://www.vlsi.fi/en/support/software/ ... tches.html
VS1053b Realtime MIDI Start code

Starts the real-time MIDI mode with a few SCI writes.
Version: 1.0
Modified: 2009-01-12
Devices: VS1053b
Download: vs1053b-rtmidistart.zip

User avatar
carlw
 
Posts: 26
Joined: Mon Apr 09, 2012 9:10 am

Re: VS1053 Breakout board - MIDI Patch Code

Post by carlw »

Thanks Bill, I was able to download the file.

:D

Is it a stretch to ask for how to implement this function?

I'm just not that good at converting generic C code from VLSI into arduino code using the adafruit library.
I'm guessing the way to accomplish this has something to do with class Adafruit_VS1053 "uint16_t lo adPlugin(char *fn) - Load the specified plug-in."

The following code seemed to compile ok, at the top of my program, for the plugin from VLSI

Code: Select all

#ifndef SKIP_PLUGIN_VARNAME
#define PLUGIN_SIZE 28
const unsigned short plugin[28] = { /* Compressed plugin */
#endif
  0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080, /*    0 */
  0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890, /*    8 */
  0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030, /*   10 */
  0x0200, 0x000a, 0x0001, 0x0050,
#ifndef SKIP_PLUGIN_VARNAME
};
#endif

User avatar
carlw
 
Posts: 26
Joined: Mon Apr 09, 2012 9:10 am

Re: VS1053 Breakout board - MIDI Patch Code

Post by carlw »

I took my best guess at appropriate code for the plug in.
Tried a few different ways and think I'm missing something basic.

This is a modified library example.

Code: Select all

/*************************************************** 
 * This is an example for the Adafruit VS1053 Codec Breakout
 * 
 * Designed specifically to work with the Adafruit VS1053 Codec Breakout 
 * ----> https://www.adafruit.com/products/1381
 * 
 * Adafruit invests time and resources providing this open source code, 
 * please support Adafruit and open-source hardware by purchasing 
 * products from Adafruit!
 * 
 * Written by Limor Fried/Ladyada for Adafruit Industries.  
 * BSD license, all text above must be included in any redistribution
 ****************************************************/

#include <SoftwareSerial.h>

// define the pins used
#define VS1053_RX  2 // This is the pin that connects to the RX pin on VS1053
#define VS1053_RESET 9 // This is the pin that connects to the RESET pin on VS1053
// Don't forget to connect the GPIO #0 to GROUND and GPIO #1 pin to 3.3V

// See http://www.vlsi.fi/fileadmin/datasheets/vs1053.pdf Pg 31
#define VS1053_BANK_DEFAULT 0x00
#define VS1053_BANK_DRUMS1 0x78
#define VS1053_BANK_DRUMS2 0x7F
#define VS1053_BANK_MELODY 0x79

// See http://www.vlsi.fi/fileadmin/datasheets/vs1053.pdf Pg 32 for more!
#define VS1053_GM1_OCARINA 80

#define MIDI_NOTE_ON  0x90
#define MIDI_NOTE_OFF 0x80
#define MIDI_CHAN_MSG 0xB0
#define MIDI_CHAN_BANK 0x00
#define MIDI_CHAN_VOLUME 0x07
#define MIDI_CHAN_PROGRAM 0xC0


SoftwareSerial VS1053_MIDI(0, 2); // TX only, do not use the 'rx' side
// on a Mega/Leonardo you may have to change the pin to one that 
// software serial support uses OR use a hardware serial port!

// plugin to start up MIDI - not sure if this should be global or local
#ifndef SKIP_PLUGIN_VARNAME
#define PLUGIN_SIZE 28
const unsigned short plugin[28] = { /* Compressed plugin */
#endif
  0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080, /*    0 */
  0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890, /*    8 */
  0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030, /*   10 */
  0x0200, 0x000a, 0x0001, 0x0050,
#ifndef SKIP_PLUGIN_VARNAME
};
#endif

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used
//#define CLK 13       // SPI Clock, shared with SD card
//#define MISO 12      // Input data, from VS1053/SD card
//#define MOSI 11      // Output data, to VS1053/SD card
#define RESET 9      // VS1053 reset pin (output)
#define CS 10        // VS1053 chip select pin (output)
#define DCS 8        // VS1053 Data/command select pin (output)
#define DREQ 3       // VS1053 Data request pin (into Arduino)
#define CARDCS 4     // Card chip select pin


Adafruit_VS1053 CWPlayer = Adafruit_VS1053 (RESET, CS, DCS, DREQ);

void setup() {
  Serial.begin(9600);
  Serial.println("VS1053 MIDI test");

  VS1053_MIDI.begin(31250); // MIDI uses a 'strange baud rate'
  LoadUserCode();
  pinMode(VS1053_RESET, OUTPUT);
  digitalWrite(VS1053_RESET, LOW);
  delay(10);
  digitalWrite(VS1053_RESET, HIGH);
  delay(10);

  midiSetChannelBank(0, VS1053_BANK_MELODY);
  midiSetInstrument(0, VS1053_GM1_OCARINA);
  midiSetChannelVolume(0, 127);
}

void loop() {  
  for (uint8_t i=60; i<69; i++) {
    midiNoteOn(0, i, 127);
    delay(100);
    midiNoteOff(0, i, 127);
  }

  delay(1000);
}

void midiSetInstrument(uint8_t chan, uint8_t inst) {
  if (chan > 15) return;
  inst --; // page 32 has instruments starting with 1 not 0 :(
  if (inst > 127) return;

  VS1053_MIDI.write(MIDI_CHAN_PROGRAM | chan);  
  VS1053_MIDI.write(inst);
}


void midiSetChannelVolume(uint8_t chan, uint8_t vol) {
  if (chan > 15) return;
  if (vol > 127) return;

  VS1053_MIDI.write(MIDI_CHAN_MSG | chan);
  VS1053_MIDI.write(MIDI_CHAN_VOLUME);
  VS1053_MIDI.write(vol);
}

void midiSetChannelBank(uint8_t chan, uint8_t bank) {
  if (chan > 15) return;
  if (bank > 127) return;

  VS1053_MIDI.write(MIDI_CHAN_MSG | chan);
  VS1053_MIDI.write((uint8_t)MIDI_CHAN_BANK);
  VS1053_MIDI.write(bank);
}

void midiNoteOn(uint8_t chan, uint8_t n, uint8_t vel) {
  if (chan > 15) return;
  if (n > 127) return;
  if (vel > 127) return;

  VS1053_MIDI.write(MIDI_NOTE_ON);
  VS1053_MIDI.write(n);
  VS1053_MIDI.write(vel);
}

void midiNoteOff(uint8_t chan, uint8_t n, uint8_t vel) {
  if (chan > 15) return;
  if (n > 127) return;
  if (vel > 127) return;

  VS1053_MIDI.write(MIDI_NOTE_OFF | chan);
  VS1053_MIDI.write(n);
  VS1053_MIDI.write(vel);
}

void LoadUserCode(void) {
  // User application code loading tables for VS10xx
  // See http://www.vlsi.fi/en/support/software/vs10xxpatches.html Download: vs1053b-rtmidistart.zip

  //#ifndef SKIP_PLUGIN_VARNAME
  //#define PLUGIN_SIZE 28
  //  const unsigned short plugin[28] = { /* Compressed plugin */
  //#endif
  //    0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080, /*    0 */
  //    0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890, /*    8 */
  //    0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030, /*   10 */
  //    0x0200, 0x000a, 0x0001, 0x0050,
  //#ifndef SKIP_PLUGIN_VARNAME
  //  };
  //#endif
  
  int i = 0;
  while (i<sizeof(plugin)/sizeof(plugin[0])) {
    unsigned short addr, n, val;
    addr = plugin[i++];
    n = plugin[i++];
    if (n & 0x8000U) { /* RLE run, replicate n samples */
      n &= 0x7FFF;
      val = plugin[i++];
      while (n--) {
        CWPlayer.sciWrite (addr, val);
      }
    } 
    else {           /* Copy run, copy n samples */
      while (n--) {
        val = plugin[i++];
        CWPlayer.sciWrite (addr, val);
      }
    }
  }
  return;
}



User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: VS1053 Breakout board - MIDI Patch Code

Post by adafruit_support_bill »

I took my best guess at appropriate code for the plug in.
Tried a few different ways and think I'm missing something basic.
What happens when you try to compile & run it?

User avatar
carlw
 
Posts: 26
Joined: Mon Apr 09, 2012 9:10 am

Re: VS1053 Breakout board - MIDI Patch Code

Post by carlw »

adafruit_support_bill wrote: What happens when you try to compile & run it?
Not much happened, the board did not go into MIDI mode.

I'm going to try some very small switches on a breadboard as a hardwire "work around" to unplugging GP0 and GP1.

User avatar
carlw
 
Posts: 26
Joined: Mon Apr 09, 2012 9:10 am

Solution

Post by carlw »

:D :D :D :shock:

With assistance from VLSI, I did get this code to work.

Please note the pin assignments and use of hardware serial is different from the Library Examples...

Code: Select all

/*************************************************** 
 * This is an example for the Adafruit VS1053 Codec Breakout
 * 
 * Designed specifically to work with the Adafruit VS1053 Codec Breakout 
 * ----> https://www.adafruit.com/products/1381
 * 
 * Adafruit invests time and resources providing this open source code, 
 * please support Adafruit and open-source hardware by purchasing 
 * products from Adafruit!
 * 
 * Written by Limor Fried/Ladyada for Adafruit Industries.  
 * BSD license, all text above must be included in any redistribution
 ****************************************************/

// define the pins used
#define VS1053_RESET 4 // This is the pin that connects to the RESET pin on VS1053
// *** Different than Library Examples ***

// See http://www.vlsi.fi/fileadmin/datasheets/vs1053.pdf Pg 31
#define VS1053_BANK_DEFAULT 0x00
#define VS1053_BANK_DRUMS1 0x78
#define VS1053_BANK_DRUMS2 0x7F
#define VS1053_BANK_MELODY 0x79

// See http://www.vlsi.fi/fileadmin/datasheets/vs1053.pdf Pg 32 for more!
#define VS1053_GM1_OCARINA 80

#define MIDI_NOTE_ON  0x90
#define MIDI_NOTE_OFF 0x80
#define MIDI_CHAN_MSG 0xB0
#define MIDI_CHAN_BANK 0x00
#define MIDI_CHAN_VOLUME 0x07
#define MIDI_CHAN_PROGRAM 0xC0

// include SPI, Adafruit_VS1053 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used *** Different than Library Examples ***
#define RESET 4     // VS1053 reset pin (RST) (output)
#define CS 5        // VS1053 chip select pin (CS) (output)
#define DCS 7       // VS1053 Data/command select pin (XDCS) (output)
#define DREQ 20     // VS1053 Data request pin (DREQ) (into Arduino)
#define CARDCS 6    // VS1053 Card chip select pin (SDCS)
// using ICSP header pins on Arduino MEGA for MISO (50), MOSI (51), SCLK (52)

Adafruit_VS1053 CWPlayer = Adafruit_VS1053_FilePlayer (RESET, CS, DCS, DREQ, CARDCS);

int onceonly = 0;

void setup() {
  Serial2.begin(31250); // MIDI uses a 'strange baud rate'
  // Using Hardware Serial 2 on Arduino MEGA - pin 16 *** Different than Library Examples ***

  CWPlayer.begin(); // This should also reset board
  
  LoadUserCode(); // This will start MIDI mode
  
  CWPlayer.setVolume(1,1); // Turn up volume a lot
  
  midiSetChannelBank(0, VS1053_BANK_MELODY);
  midiSetInstrument(0, VS1053_GM1_OCARINA);
  midiSetChannelVolume(0, 127);
}

void loop() {  
  if ( onceonly == 0 ) { // Play ascending notes once

    for (uint8_t i=60; i<100; i++) {
      midiNoteOn(0, i, 127);
      delay(100);
      midiNoteOff(0, i, 127);
    }
    delay(1000);
    onceonly ++;
  }
}

void midiSetInstrument(uint8_t chan, uint8_t inst) {
  if (chan > 15) return;
  inst --; // page 32 has instruments starting with 1 not 0 :(
  if (inst > 127) return;

  Serial2.write(MIDI_CHAN_PROGRAM | chan);  
  Serial2.write(inst);
}

void midiSetChannelVolume(uint8_t chan, uint8_t vol) {
  if (chan > 15) return;
  if (vol > 127) return;

  Serial2.write(MIDI_CHAN_MSG | chan);
  Serial2.write(MIDI_CHAN_VOLUME);
  Serial2.write(vol);
}

void midiSetChannelBank(uint8_t chan, uint8_t bank) {
  if (chan > 15) return;
  if (bank > 127) return;

  Serial2.write(MIDI_CHAN_MSG | chan);
  Serial2.write((uint8_t)MIDI_CHAN_BANK);
  Serial2.write(bank);
}

void midiNoteOn(uint8_t chan, uint8_t n, uint8_t vel) {
  if (chan > 15) return;
  if (n > 127) return;
  if (vel > 127) return;

  Serial2.write(MIDI_NOTE_ON);
  Serial2.write(n);
  Serial2.write(vel);
}

void midiNoteOff(uint8_t chan, uint8_t n, uint8_t vel) {
  if (chan > 15) return;
  if (n > 127) return;
  if (vel > 127) return;

  Serial2.write(MIDI_NOTE_OFF | chan);
  Serial2.write(n);
  Serial2.write(vel);
}

void LoadUserCode(void) {
  // User application code loading tables for VS10xx
  // See http://www.vlsi.fi/en/support/software/vs10xxpatches.html Download: vs1053b-rtmidistart.zip

#ifndef SKIP_PLUGIN_VARNAME
#define PLUGIN_SIZE 28
  const unsigned short plugin[28] = { /* Compressed plugin */
#endif
    0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080, /*    0 */
    0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890, /*    8 */
    0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030, /*   10 */
    0x0200, 0x000a, 0x0001, 0x0050,
#ifndef SKIP_PLUGIN_VARNAME
  };
#endif

  int i = 0;
  while (i< PLUGIN_SIZE) {
    unsigned short addr, n, val;
    addr = plugin[i++];
    n = plugin[i++];
    if (n & 0x8000U) { /* RLE run, replicate n samples */
      n &= 0x7FFF;
      val = plugin[i++];
      while (n--) {
        CWPlayer.sciWrite (addr , val);       
      }
    } 
    else {           /* Copy run, copy n samples */
      while (n--) {
        val = plugin[i++];
        CWPlayer.sciWrite (addr , val);        
      }
    }
  }
  return;
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”