Modify audio samples


#1

Hi I just got the board and been doing some test. It’s awesome!

I understand it uses I2S to play audio. I wonder if there is a way to modify the samples before sending them out to the speaker as i want to apply a phaser effect to them.

thankjs


#2

Hello @fido,

Thanks! I’m glad you liked the board.

What you ask is definitely doable. You have to use some advanced Audio module functions that are not (yet) documented.

You have to define a function like this:

void modifySamples(OUTPUT_BUFFER* buffer)
{
}

Then you have to set this function as the analyze function of the Audio module.

Audio.begin();
Audio.setAnalyzeCallback(modifySamples);

This analyze function was though as callback that allows you to analyze samples for doing things like vu-meters, but it also allows you to modify the I2S buffer contents.

This function is called after mixing all the audio sources (the different WAV files playing), and is call every ~1ms from the interrupt that sends (DMA) audio to the codec through I2S. Remember that it’s called from an interrupt context.

You will be working with a OUTPUT_BUFFER structure that’s defined like this:

typedef struct _output_buffer
{
	uint32_t* buffer;
	uint32_t buffer_samples;
	uint32_t mixed_samples;
	volatile bool ready;

} OUTPUT_BUFFER;
  • buffer is an array of 32 bit wide samples (16-bits for the left channel and 16-bit for the right channel).
  • buffer_samples is the maximum quantity of samples that can possibly be in the buffer array. If you are using the default Audio module values (22050 @ 16 bps) you’ll get 22 samples in every call.
  • mixed_samples is the actual quantity of mixed samples in the buffer array.
  • ready is a boolean that is used by the Audio module to flag the buffer as ready-to-be-played. It should be true if mixed_samples > 0.

You can modify the contents of the buffer buffer to apply an effect. Remember that your function now makes part of the audio processing and is time-critical: don’t do delays or intensively heavy math in here.


#3

So I receive a buffer with a max lenght of buffer_samples and have to iterate mixed_samples?
can you point out in the code where my function is called?\


#4

That’s right!

This is the line: https://github.com/Artekit/propboard-core/blob/master/cores/propboard/PropAudio.cpp#L392


#5

got it. thank you :+1: