Generical question about "audio_block_t" for new audio objects

Status
Not open for further replies.

Sandro

Well-known member
Hi all,
in my new object "player-with-pitch" I need to read "many" samples (e.g.: 10*AUDIO_BLOCK_SAMPLES) from flash memory and, after some elaborations, send to the output the usual amount of "AUDIO_BLOCK_SAMPLES" samples.
First, i tried this strategy:

Code:
...
...

void MyObjct::update(void)
{
audio_block_t *block; // used to read and send samples
...
...
...
block= allocate();
if (block==NULL ) return;
...
...
...
n = rawfile.read(block->data, 10*AUDIO_BLOCK_SAMPLES);
...
...
transmit(block);
...
...
release(block);

}

And this was a disaster... I partially solved the problem with multiple reading cycles of of "AUDIO_BLOCK_SAMPLES" samples per time; it works but requires a lot of time.. I'd like to read with a single request!
I tried something like this, defining 2 audio_block_t objects, one for reading, one for sending:

Code:
void MyObjct::update(void)
{
audio_block_t *block_temp; // used to read samples
audio_block_t *block; // used to send samples
...
...
...
block_temp= allocate();
block= allocate();
if (block_temp == NULL || block==NULL ) return;
...
...
...
n = rawfile.read(block_temp->data, 10*AUDIO_BLOCK_SAMPLES);
...
...
<my code calculate block->data[i] >
...
...
transmit(block);
...
...
release(block);
release(block_temp);
}

but this doesnt't work...
Any tip to go on experimenting?
Thanks a lot!
 
Last edited:
Sandro,
maybe something like this

Code:
int16_t temp_buffer[10*AUDIO_BLOCK_SAMPLES];

rawfile.read(temp_buffer, 10*AUDIO_BLOCK_SAMPLES*2); // I assume 2nd parameter in read are bytes

for(int ii=0; ii < 10; ii++) 
{ audio_block_t *out_block;
  out_block=allocate();
  memcpy(out_block,&temp_buffer[ii*AUDIO_BLOCK_SAMPLES], AUDIO_BLOCK_SAMPLES*2);
  transmit(out_block, ii); release(out_block);
}
 
Hi WMXZ,
thank you for your answer, I have been able to do what I needed!
One question: instead of using memcpy:
Code:
memcpy(out_block,&temp_buffer[ii*AUDIO_BLOCK_SAMPLES], AUDIO_BLOCK_SAMPLES*2);

one can write this?
Code:
for(j=0, j<AUDIO_BLOCK_SAMPLES, j++)
{
out_block->data[j] = temp_buffer [ii*AUDIO_BLOCK_SAMPLES+j] ;
}

Is there any drawback?
Thank you again!
 
Hi WMXZ,
thank you for your answer, I have been able to do what I needed!
One question: instead of using memcpy:
Code:
memcpy(out_block,&temp_buffer[ii*AUDIO_BLOCK_SAMPLES], AUDIO_BLOCK_SAMPLES*2);

one can write this?
Code:
for(j=0, j<AUDIO_BLOCK_SAMPLES, j++)
{
out_block->data[j] = temp_buffer [ii*AUDIO_BLOCK_SAMPLES+j] ;
}

Is there any drawback?
Thank you again!
sure you can, it may only a little bit slower depending on implementation of memcpy
 
There are lots of ways to do memory-to-memory copies. If you care about performance, make sure both input and output buffers are aligned to 32 bit boundaries (which is always true with audio blocks). Then copy the data using 32 bit read & write. If you do 4 or 8 consecutive reads & writes, Cortex-M4 hardware has a special memory burst where the other 3 or 7 are done in a single cycle. That also reduces loop overhead by a factor of 4 or 8.

But if your project has only a single instance of the memory copy, that sort of optimization work probably isn't worth the effort.
 
Thank you Paul; in my object there is only one operation like this each time "update()" is called, so maybe it doesn't require an optimization.
Anyway... this is an opportunity for me to go a bit deeper in C++ :) : both source and destination in this case (ie: temp_buffer and out_block->data) are declared as 16 bit (int16_t), what does "32 bit boundaries" refers to?
 
I got it! I found that "The data[] array is always 32 bit aligned in memory" so I can read pairs of samples :)
 
Status
Not open for further replies.
Back
Top