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

Thread: Simple audio object which acquires an audio block - what's wrong with this code?

  1. #1
    Junior Member
    Join Date
    Jun 2020
    Posts
    2

    Simple audio object which acquires an audio block - what's wrong with this code?

    Hi all,

    I'm writing a simple audio object but something weird is happening...

    I need to store audio blocks in my object, thus I am doing something really similar to the effect_delay object.

    I've done this before and everything worked fine, but today something's wrong: as far as I try to acquire the input buffer pointer into my private audio_block_t * the audio output is muted (and the Teensy freezes) - see the comment in the code.

    The code:


    Code:
    ///////////////////////////////////////////////////////////////////////////////
    // header:
    
    #include "AudioStream.h"
    #include "utility/dspinst.h"
    
    #define NUM_MEMORY_BLOCKS 100
    
    class MyModule : public AudioStream
    {
        
    public:
        
        MyModule() : AudioStream( 1, mInputQueueArray )
        {
            memset( mpbuf, 0, sizeof(mpbuf) );
        }
        
        virtual void update(void);
        
    private:
    
        audio_block_t *mpbuf[1];
        audio_block_t *mInputQueueArray[1]; 
    };
    
    
    ///////////////////////////////////////////////////////////////////////////////
    // cpp:
    
    #include <Arduino.h>
    #include <MyModule.h>
    
     void MyModule::update(void)
     {
      
         audio_block_t *blockin;
         
          // As far as I comment the line below, everything works fine ( I've tried also with receiveReadOnly() )
          if ( !( mpbuf[0] = receiveWritable() ) ) return;
          
          if ( mpbuf[0] != NULL ) release( mpbuf[0]);
          mpbuf[0] = NULL;
          
          if ( !( blockin = receiveWritable() ) ) return;
     
          transmit( blockin );
          release( blockin );
     }
    
    ///////////////////////////////////////////////////////////////////////////////
    /// .ino
    
    #include "Arduino.h"
    #include <Audio.h>
    #include "MyModule.h"
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    MyModule module;
    AudioControlSGTL5000  sgtl5000_1;
    AudioInputI2S            input;
    AudioOutputI2S           output;
    
    AudioConnection          patchCord1(input, 0, module, 0);
    AudioConnection          patchCord3(module, 0, output, 0);
    
    void setup()
    {
        AudioMemory(NUM_MEMORY_BLOCKS);
        sgtl5000_1.enable();
        sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
        sgtl5000_1.volume(1);
    }
    
    void loop()
    {
      }
    Any help appreciated... thanks!

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,082
    Calling receiveWritable() more than once (per input) is not allowed. If you uncomment that first line, you must remove that other line which also calls receiveWritable().

    You probably also need code to actually do something useful. If you uncomment that first line and remove the 3 last lines, this becomes a data sink that just discards all incoming audio. If you want to implement a delay, you also need to transmit the audio you previously received.

  3. #3
    Junior Member
    Join Date
    Jun 2020
    Posts
    2
    Hi Paul,

    thanks for your kind reply.

    Calling receiveWritable() more than once (per input) is not allowed.
    Ok this makes sense.

    Also receiveReadOnly() is not allowed more than once in an update()? (Or a combination of receiveWritable() and receiveReadOnly()? )

    Because also the code below does not work (as before, this is just a passthrough for testing purposes):

    Code:
     void MyModule::update(void)
     {
         audio_block_t *blockout;
         
         if ( !( mpbuf[0] = receiveReadOnly() ) ) return;
    
         if ( !( blockout = receiveReadOnly() ) ) return;
         
         transmit( blockout );
         release( blockout );
     }

    Thanks

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,354
    You can only call receiveReadOnly once in an update. When you call it a second time, it will return NULL. This will cause your code to always return from the update function on the second call to receiveReadOnly.
    Your code should do this:
    Code:
         if ( !( mpbuf[0] = receiveReadOnly() ) ) return;
         blockout = mpbuf[0];
    However, you should be aware that once you call release(blockout), the pointer in mpbuf[0] is no longer valid and should not be used.

    Pete

Posting Permissions

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