Created
December 18, 2011 05:12
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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