Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AudioPlayQueue stalls internally #415

Closed
h4yn0nnym0u5e opened this issue Nov 20, 2021 · 1 comment
Closed

AudioPlayQueue stalls internally #415

h4yn0nnym0u5e opened this issue Nov 20, 2021 · 1 comment

Comments

@h4yn0nnym0u5e
Copy link
Contributor

Description

AudioPlayQueue::getBuffer() and ::playBuffer() can stall internally, dramatically impacting user code throughput. Teensyduino 1.56 beta 3 has a new ::play() function, which uses both these functions, and thus suffers the same issue.

This behaviour is undocumented, and appears to be hard (impossible?) to work around in the user's application.

Steps To Reproduce Problem

Run the example sketch, and note that loop() iterates very slowly.

Hardware & Software

Board: any
Shields / modules used: any
Arduino IDE version: any
Teensyduino version: 1.56 beta 3
Operating system & version: any
Any other software or hardware?: no

Arduino Sketch

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

// GUItool: begin automatically generated code
AudioPlayQueue           queue1;         //xy=917,329
AudioOutputI2S           i2s2;           //xy=1121,330
AudioConnection          patchCord1(queue1, 0, i2s2, 0);
AudioConnection          patchCord2(queue1, 0, i2s2, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=1131,379
// GUItool: end automatically generated code


uint32_t next;
void setup() {
  pinMode(13,OUTPUT);
  
  Serial.begin(115200);
  while (!Serial)
    ;

  if (CrashReport) 
  {
    Serial.println(CrashReport);
    CrashReport.clear();
  }

  AudioMemory(10);
  
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  next = millis();
}

int loops;
int nulls;
float phas;
void loop() {
  int16_t* buf = queue1.getBuffer();
  
  if (NULL == buf)
    nulls++;
  else
  {
    for (int i=0;i<AUDIO_BLOCK_SAMPLES;i++)
    {
      buf[i] = (int16_t) (sin(phas)*8000.);
      phas += 220./AUDIO_SAMPLE_RATE_EXACT*TWO_PI;
      if (phas > TWO_PI)
        phas -= TWO_PI;
    }
    queue1.playBuffer();
  }

  loops++;
  if (millis() > next)
  {
    next += 100;
    Serial.printf("millis = %d, loops = %d, nulls = %d\n",millis(),loops,nulls);
  }
}

Errors or Incorrect Output

Program output from running on Teensy 4.1. Note that we achieve about 345 iterations of loop() per second, because NULL is never returned from getBuffer()

millis = 736, loops = 2, nulls = 0
millis = 837, loops = 44, nulls = 0
millis = 936, loops = 78, nulls = 0
millis = 1037, loops = 113, nulls = 0
millis = 1136, loops = 147, nulls = 0
millis = 1237, loops = 182, nulls = 0
millis = 1336, loops = 216, nulls = 0
millis = 1438, loops = 251, nulls = 0
millis = 1536, loops = 285, nulls = 0
millis = 1638, loops = 320, nulls = 0
millis = 1737, loops = 354, nulls = 0
millis = 1838, loops = 389, nulls = 0
millis = 1937, loops = 423, nulls = 0
millis = 2036, loops = 457, nulls = 0
millis = 2137, loops = 492, nulls = 0
millis = 2236, loops = 526, nulls = 0
millis = 2338, loops = 561, nulls = 0
millis = 2436, loops = 595, nulls = 0
millis = 2538, loops = 630, nulls = 0
millis = 2636, loops = 664, nulls = 0
millis = 2738, loops = 699, nulls = 0
millis = 2837, loops = 733, nulls = 0

@h4yn0nnym0u5e
Copy link
Contributor Author

Fixed by PR #417, which has been merged. But see PR #459 - demo is broken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant