#include <Arduino.h>
#include <Audio.h>
#include <SD.h>
#include <TeensyVariablePlayback.h>
// GUItool: begin automatically generated code
AudioPlaySdResmp playSdWav1; //xy=324,457
AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906
AudioConnection patchCord1(playSdWav1, 0, i2s2, 0);
AudioConnection patchCord2(playSdWav1, 0, i2s2, 1);
AudioControlSGTL5000 audioShield;
// GUItool: end automatically generated code
double getPlaybackRate(int16_t analog);
char* _filename = "SPACE.WAV";
void setup() {
Serial.begin(9600);
if (!(SD.begin(10))) {
// stop here if no SD card, but print a message
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
AudioMemory(24);
audioShield.enable();
audioShield.volume(0.5);
playSdWav1.enableInterpolation(true);
playSdWav1.setPlaybackRate(1.0);
playSdWav1.playWav(_filename);
playSdWav1.setLoopType(looptype_repeat);
// Sound sample isn't seamless, so pick some loop points
playSdWav1.setLoopStart(19374);
playSdWav1.setLoopFinish(643346);
// Extra stuff to mask glitches at loop point
playSdWav1.setUseDualPlaybackHead(true);
playSdWav1.setCrossfadeDurationInSamples(1000);
}
float rate=1.0f, factor = 1.001f;
uint32_t next;
bool increasing;
void loop() {
int newsensorValue = analogRead(A0);
// I don't have a sensor, so just ramp rate up and down
if (millis() >= next)
{
next = millis() + 3; // every 3ms, i.e. roughly every audio update
if (increasing)
{
rate *= factor;
increasing = rate < 2.0f;
}
else
{
rate /= factor;
increasing = rate < 0.5f;
}
playSdWav1.setPlaybackRate(rate);
}
if(!playSdWav1.isPlaying()) {
Serial.println("Restarted playback"); // This Never Happens
playSdWav1.playWav(_filename);
}
}
// map analog input 0-1023 to 0.5-3.0 pitch
double getPlaybackRate(int16_t analog) { //analog: 0..1023
return ((analog / 1023) * 2.5) + 0.5;
}
Just wanted to report back that the code works. Thanks!Slightly surprised that you're surprised by the "audible interruptions", given that your audio file fades in at the start and out at the end, so there's about 0.5s of near-silence if it's looped without setting start and finish points.
Here's an edit of your code which works, as far as I can tell:
C++:#include <Arduino.h> #include <Audio.h> #include <SD.h> #include <TeensyVariablePlayback.h> // GUItool: begin automatically generated code AudioPlaySdResmp playSdWav1; //xy=324,457 AudioOutputI2S i2s2; //xy=840.8571472167969,445.5714416503906 AudioConnection patchCord1(playSdWav1, 0, i2s2, 0); AudioConnection patchCord2(playSdWav1, 0, i2s2, 1); AudioControlSGTL5000 audioShield; // GUItool: end automatically generated code double getPlaybackRate(int16_t analog); char* _filename = "SPACE.WAV"; void setup() { Serial.begin(9600); if (!(SD.begin(10))) { // stop here if no SD card, but print a message while (1) { Serial.println("Unable to access the SD card"); delay(500); } } AudioMemory(24); audioShield.enable(); audioShield.volume(0.5); playSdWav1.enableInterpolation(true); playSdWav1.setPlaybackRate(1.0); playSdWav1.playWav(_filename); playSdWav1.setLoopType(looptype_repeat); // Sound sample isn't seamless, so pick some loop points playSdWav1.setLoopStart(19374); playSdWav1.setLoopFinish(643346); // Extra stuff to mask glitches at loop point playSdWav1.setUseDualPlaybackHead(true); playSdWav1.setCrossfadeDurationInSamples(1000); } float rate=1.0f, factor = 1.001f; uint32_t next; bool increasing; void loop() { int newsensorValue = analogRead(A0); // I don't have a sensor, so just ramp rate up and down if (millis() >= next) { next = millis() + 3; // every 3ms, i.e. roughly every audio update if (increasing) { rate *= factor; increasing = rate < 2.0f; } else { rate /= factor; increasing = rate < 0.5f; } playSdWav1.setPlaybackRate(rate); } if(!playSdWav1.isPlaying()) { Serial.println("Restarted playback"); // This Never Happens playSdWav1.playWav(_filename); } } // map analog input 0-1023 to 0.5-3.0 pitch double getPlaybackRate(int16_t analog) { //analog: 0..1023 return ((analog / 1023) * 2.5) + 0.5; }
setLoopStart()
and setLoopFinish()
aswell.