Use AudioPlaySdWav as reference class

balthasar

Member
I have an issue I was not able to wrap my head around. I'm writing some code for a drum machine using the teensy 4.1 with the audio adapter board. I would like to have multiple objects of the same class for the different voices like the kick drum or the snare drum. Currently this class and an example object look something like this:
Code:
class Voice{
  public:
    String filename;
    AudioPlaySdWav sdPlayer = kickPlayer;
    uint16_t pattern = 0b0000000000000000;
    float volume = 0;

    Voice(String soundFile, AudioPlaySdWav soundPlayer){
      filename = soundFile;
      sdPlayer = soundPlayer;
    }
};
//...
Voice kick("KICK.WAV", kickPlayer);
I have declared the audio routing at the start of the file like this:
Code:
AudioPlaySdWav           kickPlayer;     //xy=374,225
AudioMixer4              mixer1;         //xy=538,272
AudioOutputI2S           AudioOut;           //xy=705,273
AudioConnection          patchCord4(kickPlayer, 0, mixer1, 0);
AudioConnection          patchCord5(mixer1, 0, AudioOut, 0);
AudioConnection          patchCord6(mixer1, 0, AudioOut, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=391,160
I have already figured out that i cannot declare an empty AudioPlaySdWav Object and then later assign it in the constructor or my teensy will just stop executing the code without an error. That is why i just set it to the kickPlayer already and then overwrite it in the constructor. However when I try playing a file over the AudioPlaySdWav object from my kick object, like in the following code, the isPlaying() function keeps returning 0.
Code:
void playSound(){
  kick.sdPlayer.play("KICK.WAV");
  delay(50);
  Serial.println(kick.sdPlayer.isPlaying());
}
I think this has to be because the AudioPlaySdWav object is not properly patched to an output via an AudioConnection Object since directly playing sound over the kickPlayer object works. In my head setting the sdPlayer of my kick object to the kickPlayer would reference it and therefore use the existing patchCord object but it seems like it doesnt behave like that.

I would very much appreciate if someone could help me figuring out where my thought error lies.

Here is the full code for reference, of course this is not the way i would do it in the final version but it works for debugging :
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav           kickPlayer;     //xy=374,225
AudioMixer4              mixer1;         //xy=538,272
AudioOutputI2S           AudioOut;           //xy=705,273
AudioConnection          patchCord4(kickPlayer, 0, mixer1, 0);
AudioConnection          patchCord5(mixer1, 0, AudioOut, 0);
AudioConnection          patchCord6(mixer1, 0, AudioOut, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=391,160

#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7   // Teensy 4 ignores this, uses pin 11
#define SDCARD_SCK_PIN   14  // Teensy 4 ignores this, uses pin 13

class Voice{
  public:
    String filename;
    AudioPlaySdWav sdPlayer = kickPlayer;
    uint16_t pattern = 0b0000000000000000;
    float volume = 0;
    Voice(String soundFile, AudioPlaySdWav soundPlayer){
      filename = soundFile;
      sdPlayer = soundPlayer;
    }
};

Voice kick("KICK.WAV", kickPlayer);

void setup() {
  Serial.begin(115200);
  
  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))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}

void loop() {
  playSound();
}

void playSound(){
  kick.sdPlayer.play("KICK.WAV");
  delay(50);
  Serial.println(kick.sdPlayer.isPlaying());
}

Im happy to answer further questions in the responses:)) also if you have a better title suggestion for the thread post I'm happy to change it
 
I think you want something like this:
C++:
class Voice{
  public:
    String filename;
    AudioPlaySdWav& sdPlayer;
    uint16_t pattern = 0b0000000000000000;
    float volume = 0;

    Voice(String soundFile, AudioPlaySdWav& soundPlayer)
    : sdPlayer(soundPlayer) // sdPlayer is a reference, can only be set at construction time
    {
      filename = soundFile;
    }
};
//...
Voice kick("KICK.WAV", kickPlayer);
That initialises Voice::sdPlayer with a reference to kickPlayer, not a copy of its value (which doesn't work because of Audio-library-related reasons...).

I'm not 100% sure what your intention was with Voice::filename, as your playSound() function is not using it...
 
Back
Top