Don't use the dspinst.h stuff on your first attempt! Write your first try the simplest way, even if inefficient, even if you have to use floating point math. Get that working well before you try to optimize.
For average value, you can probably just create a 32 bit variable and add all the 16 bit samples to it. Maybe check if the number is negative before adding, if you want to average to be the average of the magnitude.
Well I follow to advice, change analyze-rms.cpp in a bit and add "float readAvr(void);" to analyze-rms.h.
I'm always on Teensy 3 so I just exclude #else and define new variables (text in Italics).
Now result is I have expected - average of samples value.
But I'm sure that isn't optimal code...
Below are changed analyze-rms.cpp
void AudioAnalyzeRMS::update(void)
{
audio_block_t *block = receiveReadOnly();
if (!block) {
count++;
return;
}
#if defined(KINETISK)
uint32_t *p = (uint32_t *)(block->data);
uint32_t *end = p + AUDIO_BLOCK_SAMPLES/2;
int64_t sum = accum;
do {
uint32_t n1 = *p++;
uint32_t n2 = *p++;
uint32_t n3 = *p++;
uint32_t n4 = *p++;
sum = multiply_accumulate_16tx16t_add_16bx16b(sum, n1, n1);
sum = multiply_accumulate_16tx16t_add_16bx16b(sum, n2, n2);
sum = multiply_accumulate_16tx16t_add_16bx16b(sum, n3, n3);
sum = multiply_accumulate_16tx16t_add_16bx16b(sum, n4, n4);
} while (p < end);
accum = sum;
count++;
//#else
int16_t *q = block->data;
int16_t *fin = q + AUDIO_BLOCK_SAMPLES;
int64_t sumA = accumA;
do {
int32_t nA = *q++;
sumA += nA;
} while (q < fin);
accumA = sumA;
countA++;
#endif
release(block);
}
float AudioAnalyzeRMS::read(void)
{
__disable_irq();
int64_t sum = accum;
accum = 0;
uint32_t num = count;
count = 0;
__enable_irq();
float meansq = sum / (num * AUDIO_BLOCK_SAMPLES);
return sqrtf(meansq) / 32767.0;
}
float AudioAnalyzeRMS::readAvr(void)
{
__disable_irq();
int64_t sumA = accumA;
accumA = 0;
uint32_t numA = countA;
countA = 0;
__enable_irq();
float average = sumA / (numA * AUDIO_BLOCK_SAMPLES);
return average / 32767.0;
}