Skip to content

Instantly share code, notes, and snippets.

@rwinscot
Created December 18, 2011 05:12
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rwinscot/1492432 to your computer and use it in GitHub Desktop.
Save rwinscot/1492432 to your computer and use it in GitHub Desktop.
Sketch to drive the SparkFun Music Instrument Shield (VS1053 MP3 and MIDI codec IC) from an Arduino UNO.
/**
* Author: Rick Winscot, Nathan Seidle
* Copyright: PUBLIC DOMAIN ( Beerware License )
*
* Hardware: Arduino UNO R3
* SparkFun Musical Instrument Shield ( http://www.sparkfun.com/products/10587 )
*
* IDE: Arduino 1.0 ( http://arduino.cc/en/Main/Software )
*
* Original sketch by Nathan Seidle on 2-12-2011. Transmogrified by Rick Winscot on 17-12-2011
* in hopes of improving re-usability on future projects. Keep to the above hardware/ide specs
* and you'll be able to slap the shield on an UNO, copy the sketch into the ide, and compile.
*/
#include <SoftwareSerial.h>
// Connect to the VS1053 on TX pin 3. RX pin 2 is not used.
SoftwareSerial midi( 2, 3 );
// Sound-banks available on the VS1053.
// 0x00 : GM1 (default)
// 0x78 : Drums
// 0x79 : GM2
byte SOUND_BANK = 0x00;
// Constant used to control channel volume.
// Range : 0 - 127
int VOLUME = 90;
// Constant used to control attack and sustain velocity.
// Range : 0 - 127
int ATK_VELOCITY = 60;
int REL_VELOCITY = 60;
// Constants used to start or stop note playback.
byte PLAY = 0x90;
byte STOP = 0x80;
// Constant used to map Arduino pin to VS1053 reset.
int VS1053_RESET = 4;
// Constant used to supress serial debugging.
boolean DEBUG = true;
// Variable used to navigate instrument selection.
int instrument = 0;
// Variable used to control note playback.
byte note = 0;
/**
* Initialize debugging, connect to the VS1053, init the VS1053, and
* set initial sound-bank and volume.
*/
void setup()
{
Serial.begin( 57600 ); // For debug messages
midi.begin( 31250 ); // MIDI control via SoftwareSerial
pinMode( VS1053_RESET, OUTPUT ); // Reset VS1053
digitalWrite( VS1053_RESET, LOW ); // ..
delay( 100 ); // ..
digitalWrite( VS1053_RESET, HIGH ); // ..
delay( 100 ); // ..
setBank( SOUND_BANK ); // Set sound-bank via constant
setVolume( VOLUME ); // Set channel volume via constant
}
/**
* Some applications run forever.
*/
void loop()
{
for ( instrument = 0 ; instrument < 127 ; instrument++ )
{
setInstrument( instrument );
for ( note = 30 ; note < 42 ; note++ )
{
setNote( note, PLAY ); // Play specified note by ATK_VELOCITY
delay(50); // ..
setNote( note, STOP ); // Stop specified note by REL_VELOCITY
delay(50); // ..
}
}
}
/**
* Set the sound-bank to one of the three available.
*/
void setBank( byte bank )
{
if ( DEBUG )
Serial.print( "Bank: " + (String)bank );
midi.write( 0xB0 );
midi.write( (byte)0 );
midi.write( bank );
}
/**
* Set channel volume to a value between 0 and 127.
*/
void setVolume( int vol )
{
if ( vol < 0 )
vol = 0;
if ( vol > 127 )
vol = 127;
if ( DEBUG )
Serial.print( "Volume: " + (String)vol );
midi.write( 0xB0 );
midi.write( 0x07 );
midi.write( (byte)vol );
}
/**
* Set the sound-bank instrument to a value between 0 - 127.
*/
void setInstrument( byte inst )
{
if ( inst < 0 )
inst = 0;
if ( inst > 127 )
inst = 127;
if ( DEBUG )
Serial.print( "Instrument: " + (String)inst );
midi.write( 0xC0 );
midi.write( inst );
}
/**
* Play or stop the specified note.
*
* Example : setNote( 30, PLAY ); // Plays F# 0
* setNote( 30, STOP ); // Stops F# 0
*
* Range: 0 - 127
*/
void setNote( byte note, byte cmd )
{
if ( note < 0 )
note = 0;
if ( note > 127 )
note = 127;
if ( DEBUG )
Serial.println( "Note: " + (String)note + " Play:" + ( cmd == PLAY ? "play" : "stop" ) );
midi.write( cmd );
midi.write( note );
midi.write( ( cmd == PLAY ? ATK_VELOCITY : REL_VELOCITY ) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment