Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Custom Audio Object - update() not called

  1. #1

    Custom Audio Object - update() not called

    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

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,734
    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.

  3. #3
    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 by carlhudson83; 02-05-2019 at 10:58 AM.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,734
    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_...ewObjects.html

  5. #5
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •