Dionysus
Active member
Good evening! Quickly, I should say how blown away I am by the software and the hardware with the teensy 4—this is just incredible. I've also been spending a lot of time in the forums, and I'm also incredibly impressed by how nice everyone is here! So much so, that it encouraged me to post what is possibly a very silly question, indeed!
I'm writing a drum machine, reading samples form the SD card and playing them. Each sample is an object, which works really well right up until it's time to play the wave file. AudioPlaySdWav playSdWav1 (for example) needs to be declared globally, but I can't figure out how to pass it to the Sample object. My incredibly kludgey "solution" was to have each object call a "playSample()" function, which calls the correct AudioPlaySdWav. That can't be right, right!?
Also, when I have more than 3 files running it will often freeze up and just play that horrible hum. Sometimes I'm able to get four files working, but no more than that. I strongly suspect that this is because I'm reading them all from the SD card, and I plan to write a second question here about alternatives to that. But I did think I should check to see if something about the janky way I'm calling AudioPlaySdWav is also responsible.
I'm attaching my code here, apologies for the mess! Thank you all so much!
I'm writing a drum machine, reading samples form the SD card and playing them. Each sample is an object, which works really well right up until it's time to play the wave file. AudioPlaySdWav playSdWav1 (for example) needs to be declared globally, but I can't figure out how to pass it to the Sample object. My incredibly kludgey "solution" was to have each object call a "playSample()" function, which calls the correct AudioPlaySdWav. That can't be right, right!?
Also, when I have more than 3 files running it will often freeze up and just play that horrible hum. Sometimes I'm able to get four files working, but no more than that. I strongly suspect that this is because I'm reading them all from the SD card, and I plan to write a second question here about alternatives to that. But I did think I should check to see if something about the janky way I'm calling AudioPlaySdWav is also responsible.
I'm attaching my code here, apologies for the mess! Thank you all so much!
Code:
///////////////////////////////////
// copy the Design Tool code here
///////////////////////////////////
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioPlaySdWav playSdWav5; //xy=151,254
AudioPlaySdWav playSdWav8; //xy=155,389
AudioPlaySdWav playSdWav6; //xy=161,302
AudioPlaySdWav playSdWav1; //xy=162,63
AudioPlaySdWav playSdWav3; //xy=169,162
AudioPlaySdWav playSdWav2; //xy=173,112
AudioPlaySdWav playSdWav7; //xy=180,342
AudioPlaySdWav playSdWav4; //xy=181,202
AudioMixer4 mixer4; //xy=355,332
AudioMixer4 mixer3; //xy=375,270
AudioMixer4 mixer1; //xy=397,150
AudioMixer4 mixer2; //xy=404,209
AudioMixer4 mixer5; //xy=611,206
AudioAnalyzePeak peak3; //xy=690,427
AudioAnalyzePeak peak1; //xy=693,312
AudioAnalyzePeak peak2; //xy=716,376
AudioAnalyzePeak peak4; //xy=720,480
AudioOutputI2S i2s1; //xy=878,201
AudioConnection patchCord1(playSdWav5, 0, mixer3, 0);
AudioConnection patchCord2(playSdWav5, 1, mixer3, 1);
AudioConnection patchCord3(playSdWav8, 0, mixer4, 2);
AudioConnection patchCord4(playSdWav8, 1, mixer4, 3);
AudioConnection patchCord5(playSdWav6, 0, mixer3, 2);
AudioConnection patchCord6(playSdWav6, 1, mixer3, 3);
AudioConnection patchCord7(playSdWav1, 0, mixer1, 0);
AudioConnection patchCord8(playSdWav1, 1, mixer1, 1);
AudioConnection patchCord9(playSdWav3, 0, mixer2, 0);
AudioConnection patchCord10(playSdWav3, 1, mixer2, 1);
AudioConnection patchCord11(playSdWav2, 0, mixer1, 2);
AudioConnection patchCord12(playSdWav2, 1, mixer1, 3);
AudioConnection patchCord13(playSdWav7, 0, mixer4, 0);
AudioConnection patchCord14(playSdWav7, 1, mixer4, 1);
AudioConnection patchCord15(playSdWav4, 0, mixer2, 2);
AudioConnection patchCord16(playSdWav4, 1, mixer2, 3);
AudioConnection patchCord17(mixer4, 0, mixer5, 3);
AudioConnection patchCord18(mixer4, peak4);
AudioConnection patchCord19(mixer3, 0, mixer5, 2);
AudioConnection patchCord20(mixer3, peak3);
AudioConnection patchCord21(mixer1, 0, mixer5, 0);
AudioConnection patchCord22(mixer1, peak1);
AudioConnection patchCord23(mixer2, 0, mixer5, 1);
AudioConnection patchCord24(mixer2, peak2);
AudioConnection patchCord25(mixer5, 0, i2s1, 0);
AudioConnection patchCord26(mixer5, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=346,435
// GUItool: end automatically generated code
// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
int bpm=120;
int sampleObjects=0;
#define WHOLENOTE 4
#define HALFNOTE 2
#define QUARTERNOTE 1
#define EIGHTHNOTE .5
#define SIXTEENTHNOTE .25
class Sample{
float noteType; // i.e., what percentage of bpm is this note (e.g., a quarternote is 1 bpm, an eigthnote is .5)
int oldTime=0;
const char *sampleName;
File currentDir;
File currentSample;
char fullSamplePath[50];
int id;
elapsedMillis change;
public:
void setup(const char *dn,const char *sn,float n, int beats, int rests){
sampleName=sn;
noteType=n;
currentDir=loadDir(dn);
currentSample=loadSample(sn);
sampleObjects++;
id=sampleObjects;
}
void playSample(int id, char *fullSamplePath){
switch(id){
case 1:
playSdWav1.play(fullSamplePath);
break;
case 2:
playSdWav2.play(fullSamplePath);
break;
case 3:
playSdWav3.play(fullSamplePath);
break;
case 4:
playSdWav4.play(fullSamplePath);
break;
case 5:
playSdWav5.play(fullSamplePath);
break;
case 6:
playSdWav6.play(fullSamplePath);
break;
case 7:
playSdWav7.play(fullSamplePath);
break;
case 8:
playSdWav8.play(fullSamplePath);
break;
}
delay(50);
}
/************************************************************************************************************************************
* loadDir()
************************************************************************************************************************************/
File loadDir(const char* dir){
Serial.println(dir);
File myFile;
myFile=SD.open(dir);
Serial.print("Directory: ");Serial.println(myFile.name());
return myFile;
}
/************************************************************************************************************************************
* loadSample()
************************************************************************************************************************************/
File loadSample(const char* sampleName){
File myFile;
//char fullSamplePath[50];
sprintf(fullSamplePath, "/%s/%s",currentDir.name(),sampleName);
Serial.print("Name 1: ");Serial.println(fullSamplePath);
myFile=SD.open(fullSamplePath);
if(! myFile){
Serial.println("Can't open file");
return myFile;
}
else{
return myFile;
}
}
//*******************************************************************************************************************
// Main Sample Loop
//*******************************************************************************************************************
void loop(){
if(change>=(noteType*(60000/bpm))){
// e.g., an eighthnote at 120 bpm should play every 250 milliseconds, which is 4 times a second or 240 times a minute
change=0;
playSample(id,fullSamplePath);
}
}
};
Sample sample1;
Sample sample2;
Sample sample3;
Sample sample4;
Sample sample5;
Sample sample6;
Sample sample7;
Sample sample8;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
AudioMemory(8);
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
delay(1000);
float vol=.15;
mixer1.gain(0, vol);
mixer1.gain(1, vol);
mixer2.gain(0, vol);
mixer2.gain(1, vol);
mixer3.gain(0, vol);
mixer3.gain(1, vol);
mixer4.gain(0, vol);
mixer4.gain(1, vol);
mixer5.gain(0, .5);
mixer5.gain(1, .5);
sample1.setup("D_808", "classic.wav", SIXTEENTHNOTE,1,2);
sample2.setup("D_808", "break.wav", EIGHTHNOTE,1,2);
sample3.setup("D_808", "bitch.wav", QUARTERNOTE,2,1);
sample4.setup("D_organc", "clakclak.wav", WHOLENOTE,2,2);
sample5.setup("D_organc", "lanaDah.wav", QUARTERNOTE,7,3);
sample6.setup("D_organc", "lanaDah2.wav", QUARTERNOTE,3,7);
sample7.setup("D_organc", "meaty.wav", QUARTERNOTE,1,7);
}
void loop() {
sample1.loop();
sample2.loop();
sample3.loop();
// sample4.loop();
// sample5.loop();
//sample6.loop();
// sample7.loop();
}