routing data stream to audio objects of audio lib

Status
Not open for further replies.

emmanuel63

Well-known member
Hello,

I try to make an audio envelope detector.
I read the audio signal through an analog input. I add a DC voltage to audio signal to read both positives and negatives values. I use square function to transform negatives values to positives, then I do a susbstraction to remove DC.

Now I need to use a low pass filter to get the envelope. I would like to use the filter object from the audio lib , but I can't figure out how to route my data stream into it. Is there a way to stream data into audio objects ?

Thanks for any help.
Emmanuel
 
You could use the 'AudioPlayQueue' class or implement your envelope detector as a Audio Library class.
 
Franck,
Would you give please a piece of code. I am new with tis function and I don't have any clue how to use it.
Emmanuel
 
Franck,
Would you give please a piece of code. I am new with tis function and I don't have any clue how to use it.
Emmanuel

Maybe this evening.. have to write it first. I'm in home office, and the weather is so great.. I'll take the chance and will spend some time in the garden later.
 
Here it is :)

It plays a 8bit 11025 hz audio file (included, from starship enterprise) - only 33k data

I hope it shows how the queue can be used.


Edit: If you want to use the audioshield,
add
Code:
[COLOR=#ffa500]AudioControlSGTL5000     sgtl5000_1; [/COLOR]

void setup()
...
[COLOR=#ffa500]  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);[/COLOR]
...
 

Attachments

  • AudioExample_playQueue-200327b.zip
    33 KB · Views: 58
Last edited:
Wow... I feel very humble. I must admit I don't understand all of it. I am going do dig it to understand.
Many thanks
Emmanuel
 
You don't need the filter.

The important thing is this:
Code:
  int16_t * p = queue1.getBuffer();
  if (p != nullptr) {

    for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {

      int16_t sample = your sample

      *p++ = sample;

    }
    queue1.playBuffer();
  }

1. get the buffer,
2. check if it is valid
3. if yes fill it, and
4. play it.

I've updated the example "sample player" - the data were not "const".
 
That was just the explanation I needed. I think I get it now. Thanks for sharing your knowledge. I really need now to refresh my memory about pointers.
 
You might have an easier path to create a custom audio processing object within the library, rather than go to the trouble of using the queues to transfer streaming data to your program. To do this, you'd copy any of the existing analysis objects, like peak detect or RMS level, and replace their update() function with your own code. Each time the library has another 128 samples, it calls that function. You do whatever work needs to be done for those 128 samples, store the result (so your program can read it when needed), and return from update() as quickly as possible. No queues or buffering, just run your code every 128 samples.

More info here.

https://www.pjrc.com/teensy/td_libs_AudioNewObjects.html
 
Thanks Paul. I'll try both path. I think I understand now Franck's code. I am going to try it. It seems pretty straight forward. Then I really have to work in depth the subject of creating audio objects. Looks like I have a lot to do during my confinement !
 
Hello,
I tried both ways : using the queue object, and editing an existing audio object.
First method works, but it is quite difficult for me to use (I am still at the beginning of my learning curve).
Second method is easier, since I use pre-existing code.

I used Paul's code to get my audio samples rectified (negative samples are turned into positives). I would appreciate very much a few explanations. Here is the audio object code :

Code:
#include "effect_abs.h"

void AudioEffectAbs::update(void){
    int16_t *p, *end;
    audio_block_t *block;

    block = receiveReadOnly(0);
    if (block == NULL) return;
    p = block->data;
    end = p + AUDIO_BLOCK_SAMPLES;
    while (p < end){
        int16_t s = *p;
        if (s < 0) {
            if (s == -32768){
                s = 32767;
            } else {
                s *= -1;
            }
            *p = s;
        }
        p++;
    }
    transmit(block);
    release(block);
}

I don't understand the following statements :

block = receiveReadOnly(0);
"block" is a pointer. What is the result of assigning "receiveReadOnly(0)" to a pointer ?

p = block->data;
I also need details for this line.

Thanks for any help.

Emmanuel
 
Last edited by a moderator:
The answers to both of your questions are contained in the page Paul linked above:
 

Attachments

  • AudioBlock.jpg
    AudioBlock.jpg
    30.8 KB · Views: 94
I have read this page many times, but it is still confusing for me. These concepts behind the code are very new to me and I admit I can be slow too...
 
Status
Not open for further replies.
Back
Top