Does anyone have any example code for this?
- I'm using Adafruit's vs1053b breakout board with SD card (https://www.adafruit.com/product/1381)
- I'm controlling it with an Arduino Uno, using the Adafruit VS1053 Library (https://github.com/adafruit/Adafruit_VS1053_Library)
- I have connected everything according to the Adafruit tutorial (https://learn.adafruit.com/adafruit-vs1 ... l?view=all)
- And I'm trying to use the vs1053 patch for tempo shifting (https://www.vlsi.fi/en/support/software ... tches.html). Using the plugin file called "vs1053-patches-pitch.plg".
First, to check that I loaded the .plg file properly, here's how I did it. I simply used the loadPlugin() function from the Adafruit VS1053 Library. The .plg file in on the SD card on the vs1053 breakout board, since that's where the loadPlugin() function looks for the plugin.
Code: Select all
// load plugin/patch file
if (! musicPlayer.loadPlugin("pitch.plg")) {
Serial.println("Couldn't load plugin!");
while (1);
}
This is Adafruit's loadPlugin() function:
Code: Select all
uint16_t Adafruit_VS1053::loadPlugin(char *plugname) {
File plugin = SD.open(plugname);
if (!plugin) {
Serial.println("Couldn't open the plugin file");
Serial.println(plugin);
return 0xFFFF;
}
if ((plugin.read() != 'P') || (plugin.read() != '&') ||
(plugin.read() != 'H'))
return 0xFFFF;
uint16_t type;
// Serial.print("Patch size: "); Serial.println(patchsize);
while ((type = plugin.read()) >= 0) {
uint16_t offsets[] = {0x8000UL, 0x0, 0x4000UL};
uint16_t addr, len;
// Serial.print("type: "); Serial.println(type, HEX);
if (type >= 4) {
plugin.close();
return 0xFFFF;
}
len = plugin.read();
len <<= 8;
len |= plugin.read() & ~1;
addr = plugin.read();
addr <<= 8;
addr |= plugin.read();
// Serial.print("len: "); Serial.print(len);
// Serial.print(" addr: $"); Serial.println(addr, HEX);
if (type == 3) {
// execute rec!
plugin.close();
return addr;
}
// set address
sciWrite(VS1053_REG_WRAMADDR, addr + offsets[type]);
// write data
do {
uint16_t data;
data = plugin.read();
data <<= 8;
data |= plugin.read();
sciWrite(VS1053_REG_WRAM, data);
} while ((len -= 2));
}
plugin.close();
return 0xFFFF;
}
Then to code the tempo shift, I tried following the document that comes with the vs1053b patches zip file (https://www.vlsi.fi/fileadmin/software/ ... atches.pdf, page 19)
It says that to enable to the pitch tempo shifter, write the pitch/tempo value to AICTRL0 and then write 0x51 to AIADDR. (except this other document https://www.vlsi.fi/fileadmin/software/ ... hifter.pdf says to write 0x50 ? neither one worked)
So I try writing this in my Arduino script, after loading the plugin, using Adafruit's sciWrite() function:
Code: Select all
musicPlayer.sciWrite(VS1053_SCI_AICTRL0, 16384);
musicPlayer.sciWrite(VS1053_SCI_AIADDR, 0x50);
Can't figure out if there's more code that needs to accompany this, or any connections I'm missing..
Does anyone have any example code for using the pitch/tempo shifter?
Here is more of my arduino script as a whole:
Code: Select all
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
#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 BREAKOUT_RESET 9 // VS1053 reset pin (output)
#define BREAKOUT_CS 10 // VS1053 chip select pin (output)
#define BREAKOUT_DCS 8 // VS1053 Data/command select pin (output)
#define SHIELD_RESET -1 // VS1053 reset pin (unused)
#define SHIELD_CS 7 // VS1053 chip select pin (output)
#define SHIELD_DCS 6 // VS1053 Data/command select pin (output)
#define CARDCS A0 // Card chip select pin
#define DREQ 3
Adafruit_VS1053_FilePlayer musicPlayer =
// create breakout-example object
Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
// define variables used...
// ...
void setup() {
Serial.begin(9600);
Serial.println("Adafruit VS1053 Simple Test");
if (! musicPlayer.begin()) { // initialise the music player
Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
while (1);
}
Serial.println(F("VS1053 found"));
if (!SD.begin(CARDCS)) {
Serial.println(F("SD failed, or not present"));
while (1); // don't do anything more
}
Serial.println(F("SD found"));
//set volume
musicPlayer.setVolume(20, 20);
// load plugin/patch file //<------------- LOAD PLUGIN
if (! musicPlayer.loadPlugin("pitch.plg")) {
Serial.println("Couldn't load plugin!");
while (1);
}
// enable pitch/tempo shifter //<------------- ENABLE PITCH/TEMPO SHIFTER
// write pitch/tempo value to AICTRL0, write 0x50 to AIADDR (https://www.vlsi.fi/fileadmin/software/VS10XX/vs1053b-patches.pdf, pg 19)
musicplayer.sciWrite(VS1053_SCI_AICTRL0, -16384);
musicPlayer.sciWrite(VS1053_SCI_AIADDR, 0x50);
// enable interrupt
musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT); // DREQ int
// start playing file
musicPlayer.startPlayingFile("/track001.wav");
} // end void setup()
void loop () {
// change tempo with a potentiometer
potTempo = analogRead(tempoPin);
ratio = mapfloat(potTempo, 0, 1023, 0.7, 1.5); // Mapping the pot values to ratio values
tempo = round(-16384 / ratio);
musicPlayer.sciWrite(VS1053_SCI_AICTRL0, tempo); //<------------- WRITE TEMPO TO SCI AICTRL0
} // end void loop
// map function that does floats instead of just integers
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}