Missing something while using the Audio library in a class?

rmills

Active member
Trying to create a class to handle some audio thats running on a teensy 4.1 with the PT8211 chip, however I'm missing something. If I run the waveform example in github everything works. I tried to wrap the waveform example into a C++ class but I can't get any output. Also the SD card test wav's won't play either. I'm guessing I'm missing something with the implementation of the AudioConnection when used inside a class. It does not crash or throw errors, just no playback. Did I miss something in the patchcords again?



SolarAudio.h
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <Sdfat.h>

class SolarAudio {    
  private:
    AudioPlaySdWav           playSdWav1;
    AudioPlaySdWav           playSdWav2;
    AudioPlaySdWav           playSdWav3;

    AudioMixer4              mixer1;
    AudioOutputPT8211        pt8211_1;
    AudioSynthWaveform       waveform1;

  public:
    void begin();
    void testTone(int duration);
    void play1();
    void play2();
    void play3();
};


SolarAudio.cpp
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <Sdfat.h>

#include "Pins.h"
#include "SolarAudio.h"

void SolarAudio::begin(){
    AudioConnection          patchCord1(waveform1, 0, mixer1, 0);
    AudioConnection          patchCord2(playSdWav1, 0, mixer1, 1);
    AudioConnection          patchCord3(playSdWav2, 0, mixer1, 2);
    AudioConnection          patchCord4(playSdWav3, 0, mixer1, 3);
    AudioConnection          patchCord5(mixer1, 0, pt8211_1, 0);
    AudioConnection          patchCord6(mixer1, 0, pt8211_1, 1);

    mixer1.gain(0, 0.99);
    mixer1.gain(1, 0.99);
    mixer1.gain(2, 0.99);
    mixer1.gain(3, 0.99);

    SPI.setMOSI(SDCARD_MOSI_PIN);
    SPI.setSCK(SDCARD_SCK_PIN);
    if (!(SD.begin(BUILTIN_SDCARD))) {
      while (1) {
        Serial.println("Unable to access the SD card");
        delay(500);
      }
    }
    Serial.println("PT8211 Init Complete");
}

void SolarAudio::play1(){
  Serial.println("Play1()");
  playSdWav1.play("SDTEST1.WAV");
}

void SolarAudio::play2(){
  Serial.println("Play2()");
  playSdWav2.play("SDTEST2.WAV");
}

void SolarAudio::play3(){
  Serial.println("Play3()");
  playSdWav3.play("SDTEST3.WAV");
}

void SolarAudio::testTone(int duration){
  Serial.println("Playing Test Tone");
  waveform1.begin(WAVEFORM_SINE);
  waveform1.frequency(440);
  waveform1.amplitude(0.99);
  delay(duration);
  waveform1.amplitude(0);
}


main.cpp
Code:
#include <Arduino.h>
#include <SPI.h>

#include "Pins.h"
#include "SolarAudio.h"

SolarAudio audio;

void setup()
{	
	Serial.begin(9600);
	while (!Serial) {
		;
	}
	Serial.println("Starting");
	AudioMemory(40);
	audio.begin();
}

void loop()
{


	Serial.println("loop");
	audio.testTone(5000);
	delay(2000);
	audio.play1();
	delay(2000);
	audio.play2();
	delay(2000);
	audio.play3();
	delay(2000);

}
 
You've thrown away the AudioConnection objects immediately after creating them in begin(), undoing the flowgraph.

If you declare a local variable of a class type it is constructed when the function runs and the variable comes into
scope, but destructed on function exit (when the variable goes out of scope).

So all those patchCords live for a very short time only.

The Audio lib wasn't really designed for dynamic use like this, but its getting better, there's a thread somewhere on
this. Its designed that you create objects and connections just like the Audio tool does, at top level, and in a
particular order dictated by a the signal flowgraph.

Because some of the classes use interrupts to drive the audio processing, there are issues with trying to manipulate
the objects dynamically which may not be obvious, which I think is one of the reasons it is used as it is.
 
One way of doing it

in SolarAudio.h
Code:
AudioConnection *patchCords[6];

then in SolarAudio.c
Code:
void SolarAudio::begin(){
    int pci=0;
    
    patchCords[pci++] = new AudioConnection(waveform1, 0, mixer1, 0);
    patchCords[pci++] = new AudioConnection(playSdWav1, 0, mixer1, 1);
    patchCords[pci++] = new AudioConnection(playSdWav2, 0, mixer1, 2);
    patchCords[pci++] = new AudioConnection(playSdWav3, 0, mixer1, 3);
    patchCords[pci++] = new AudioConnection(mixer1, 0, pt8211_1, 0);
    patchCords[pci++] = new AudioConnection(mixer1, 0, pt8211_1, 1);

    //.......
}
 
Back
Top