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

Thread: Method of 'polling' audio objects?

  1. #1
    Junior Member
    Join Date
    Oct 2016
    Posts
    13

    Method of 'polling' audio objects?

    I'm looking for a way to essentially 'poll' certain Teensy audio objects (FFT, Peak, etc) ~60 times a second to update a strip of LEDs, meaning I'd like a way for these audio objects to be inactive until about the time I need to display a visualization of the incoming signal. The thought here is to reduce the load on the CPU while the program is doing other things during the time in between updates. I considered connecting / disconnecting the components programmatically when I need to poll them, but haven't yet tested this for performance implications.

    This question could probably be filed under "Premature Optimizations" for my use case as it stands now, but I've been curious about it for a while and would love to get others' opinions. Freeing up some CPU time in between the visual updates would leave a bit more headroom for other tasks like receiving & sending messages over Serial. Currently testing on Teensy 3.6, but I'm aiming to support all 3.x devices.

    There may be some incorrect assumptions about how the Audio objects work in the background, but I'm thankful for any corrections & opinions.
    Thanks!

  2. #2
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,528
    Maybe there is only a semantic issue with the term 'polling'.
    but polling is nothing else than sampling, sampling at 60 Hz means you have a signal with does not change 30 times per second.

    You were talking about FFT and peak, that is processed (or filtered data)

    Given that the audio library samples at 44.1 kHz, a 1024 point FFT gives you new information 43 times per second (44100/1024)
    the peak object gives you new values 344 times per second (44100/128)

    both FFT and peak are polling only, However, if you are not poll fast enough you are aliasing the information flow.

    BTW, as the audio library runs data and interrupt driven in the background, there is plenty of time for doing foreground jobs, being at the loop(), or proper selected interrupt level.

  3. #3
    Junior Member
    Join Date
    Oct 2016
    Posts
    13
    Yes, you're correct about my misuse of polling. I couldn't find the right word, which is why I put 'polling' in quotes in my original post. I'm asking if there is a way to eliminate those extraneous processed updates. Using the peak object, for example, you mention it updates once every 128 samples, processing ~284 extra results per second if I'm only looking for 60 updates per second. Perhaps the overhead of such a system (especially for the Peak object) isn't worth the performance gain it would give, but I worry about performance when it comes to running 2 FFT1024 objects, for example. I also did not realize the 1024-sample FFT would actually update slower than my desired FPS, but that makes sense.

    I appreciate the insight = especially into how the audio library works under the hood, and about my terminology.

  4. #4
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,528
    talking about FFT
    in order to obtain the 43 Hz update rate of a 1024 point FFT, the audio library must run all the time.
    the same is with the peak function.
    now if you only wanted to have an update rate of 60 Hz (57.4 Hz) then you have to "filter" the 344 Hz peak data sequence.
    that is, in the loop you poll the peak function, if nothing available you continue,
    if new peak value available, then you take the max between new and stored value an keep the new max, and continue

    after you have done this 6 times you update your display or what you wanted to do with the peak value, clear the stored value and reset the counter

    you could start with a code like this (which is written without testing)
    Code:
    void loop()
    {
    .
    static float maxPeak=0.0f;
    static int count=0;
    if (peak1.available())
    { count++;
      float val=peak1.read();
      if(count<6)
      { if( val>maxPeak) maxPeak=val;
        count++
      }
      if(count==6)
      { // call display using maxPeak as parameter
        // reset now accumulator
        count=0;
        maxPeak=0.0f;
      }
    ..
    }
    }

Posting Permissions

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