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

Thread: Working Audio output queue example

  1. #1
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,936

    Working Audio output queue example

    While trying to rough out some functionality around using the audio queue output object had a fair bit of trouble getting a basic example to work.

    For anybody else looking at generating audio from code without going into the audio library itself to make a custom object and wanting a place to start

    WARNING this produces a test waveform where the DAC is referencing various code values and will sound horrible and be possibly damaging connected to a speaker, it is intended to be plugged into a scope to see what the various values are doing

    Specifically it sets pin 13 high to sync the scope, then loads 30 blocks of memory with 128 values each with a high start pulse, then a negative counter marker, then a positive memory used marker (at the time data was written, not outputed) and a positive, max memory allocated marker (40)


    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    //AudioInputAnalog         adc1;           //xy=189,311
    //AudioRecordQueue         queue2;         //xy=319,326
    AudioPlayQueue           queueOut;         //xy=352,226
    AudioOutputAnalog        dac1;           //xy=494,223
    //AudioConnection          patchCord1(adc1, queue2);
    AudioConnection          patchCord2(queueOut, dac1);
    // GUItool: end automatically generated code
    
    int16_t buffer[128];
    elapsedMicros usec = 0;
    uint32_t tempval =0;
    uint32_t loopcount =0;
    
    
    void setup() {
        AudioMemory(40);
        pinMode(13,OUTPUT);
        dac1.analogReference(EXTERNAL); //3.3V p-p vs default 1.2
      Serial.begin(9600);
    
    }
    
    void updateBuffer()
    {
      int16_t memoryused AudioMemoryUsage();
        for (int i=0;i<128;i++) {
          int16_t  cellvalue=0;
          if (i>4&&i<12) cellvalue = 32767;
          if (i>32&&i<64) cellvalue = -32767+loopcount*256*3;
          if (i>64&&i<96) cellvalue = memoryused*256*3;
           if (i>96&&i<128) cellvalue = 40*256*3;
           buffer[i]=cellvalue;
        }
         int16_t *p = queueOut.getBuffer();
          memcpy(p, buffer, 128);
          queueOut.playBuffer();
    }
    
    void loop() {
    //  if (loopcount<20||(loopcount<30&&usec>5*2900)){ //writing while playing test
        if (loopcount<30){
          digitalWrite(13,HIGH);
          updateBuffer();
          loopcount++;      
          digitalWrite(13,LOW);    
      }
      if (usec>35*2900+1000&&AudioMemoryUsage()<2) {
          loopcount=0;
          usec=0;
          Serial.println(AudioMemoryUsageMax());
      }   
    }
    At time of writing (Aug 2017) the behavior observed was that you load multiple blocks in, and they are then played back in order, and you can add more in FIFO during playback (see commented line) but not overwrite them, each block needs a playbuffer call. The only way I could find to check if queue is still playing (aka needed topping up) was to monitor memory usage, hence why the last if in the loop checks both elapsed time and free memory before adding data again.

    Unsure with the memcpy line if it should be 128 or 256 (number of bytes or number of int16s), both seem to work which isn't what I expected.

  2. #2
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,593
    Quote Originally Posted by GremlinWrangler View Post
    Unsure with the memcpy line if it should be 128 or 256 (number of bytes or number of int16s), both seem to work which isn't what I expected.
    memcpy() should use 256

Posting Permissions

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