Custom Audio Object - update() not called

Status
Not open for further replies.

carlhudson83

New member
Hi,

Apologies if this problem is caused by my fumbling of C++ classes, but I'm trying to create a small custom audio object, and I can't seem to construct it properly..
Here's my custom audio class:

Code:
class AudioBlockPlayer : public AudioStream
{
public:
  AudioBlockPlayer() : AudioStream(0, NULL) { begin(); }
  void begin(void);
  virtual void update(void);
  int onFlag;
  
private:
  audio_block_t *inputQueueArray[1];
};

void AudioBlockPlayer::begin(void)
{
 onFlag = 1;
}

void AudioBlockPlayer::update(void)
{
      testCount++;
      if (testCount > 4) testCount = 0;
}


And I create it in setup() with this:
Code:
AudioBlockPlayer blockPlayer;
blockPlayer.begin();

I'd like it's update() method to modify a wavetable array pointer every 128 samples..
But at the moment, the update() method is not being called by the interrupt.. Have I constructed it wrong?

Thanks,
Carl
 
Your program needs to have one of the special objects with "update responsibility", which are generally the non-USB input & output ones.

This is true for all audio projects. Without any input or outputs, nothing at all runs.

Maybe you're already doing this, maybe not? Can't tell with only a code fragment.
 
Here's the complete code.. I eventually want to use my AudioBlockPlayer class to crossfade between variable-length wavetables, and use bilinear interpolation.
At the moment I'm still trying to figure out how the architecture of the audio library is working..

Could you explain further what a special object with 'update responsibility' is?
According to the custom object help page,
If your object is a playback or synthesis object, or simply doesn't need any inputs, use ": AudioStream(0, NULL)" to create you object without any inputs.
- but it doesn't explain how to make an object with outputs.

Code:
#include "Arduino.h"
#include "AudioStream.h"

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#include "SineTable.h"


IntervalTimer callAudioBlockPlayer;

AudioSynthWaveform       waveformOut;   
AudioOutputI2S           i2s1;           
AudioConnection          patchCord1(waveformOut, 0, i2s1, 0);
AudioConnection          patchCord2(waveformOut, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     


int16_t testBuffer[256];            // Eventually have 16 bins here, of arbitrary size
int16_t testBuffer2[256];
int16_t outputBuffer[256];

int testCount = 0;
int testFlag = 0;
int testFrequency = 0;



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// AUDIO BLOCK PLAYER

class AudioBlockPlayer : public AudioStream
{
public:
  AudioBlockPlayer() : AudioStream(0, NULL) { begin(); }
  void begin(void);
  
  int onFlag;
  int  testCount;
  
  virtual void update(void);
  
private:
  audio_block_t *inputQueueArray[1];
};

void AudioBlockPlayer::begin(void)
{
 onFlag = 1;
}

void AudioBlockPlayer::update(void)
{
      testCount++;
      if (testCount > 4) testCount = 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//////  GLOBAL VARIABLES 


#define MAX_AUDIO_BLOCK_SIZE 1024       // max size of the granular tables
#define SAMPLES_IN_BUFFER 128

AudioBlockPlayer         audioBlockPlayer;


void setup() {

  pinMode(13, OUTPUT);
    
  AudioMemory(10);
  sgtl5000_1.enable();
  sgtl5000_1.volume(1);
  
  for (int i=0; i<256; i++) {                           // copy part of sinewave to output buffer    
    testBuffer[i] = (sineTable[i] + 32768);
    testBuffer2[i] = i * 5;
    outputBuffer[i] = (sineTable[i] + 32768);
  }

  AudioBlockPlayer blockPlayer;
  blockPlayer.begin();

   waveformOut.begin(WAVEFORM_ARBITRARY);
   waveformOut.arbitraryWaveform(testBuffer2, 2000);
   waveformOut.frequency(220);
   waveformOut.amplitude(0.1);             // QUIET VOLUME SET HERE!

}

void loop() {
        
}
 
Last edited:
Ok, I see at least 4 possible problems here:

1: You've created 2 instance of your AudioBlockPlayer class. One is a local variable in setup(), so it will only exist for a very short time while setup() runs. The other with global scope is normal way. You should delete the local scope one.

2: You haven't created any AudioConnection objects to link your audioBlockPlayer instance into the system. It's never going to run unless you connect it.

3: Your update() function doesn't receive or transmit any data.

4: You do have an inputQueueArray array with 1 element, which is normally used for receiving 1 audio stream. But the constructor initializes with "AudioStream(0, NULL)", which means you have no inputs. For inputs, you must initialize for the number your object will support. For outputs, you don't need to do anything special in the constructor. The number of transmit() calls you do in update() determines how many streams you're sending. If you never call transmit(), your object sends no outputs.

This page has all the details.

https://www.pjrc.com/teensy/td_libs_AudioNewObjects.html
 
Great! Thanks Paul..

I fixed it by removing the 2nd instance in setup() - that was a silly mistake.. And also by adding an 'amp' audio object (which will remain unused) and connecting my class to it using a 'patchcord'..

Code:
AudioAmplifier           amp1;
AudioConnection        patchCord3(blockPlayer, 0, amp1, 0);


Since my class is just going to perform some array crunching, it doesn't need any actual outputs -it just needs to be synchronised with update() interrupt.. But I understand it has to be connected to something in order for its own update method to be called.. Hence the unused amp object.
 
Status
Not open for further replies.
Back
Top