cancel
Showing results for 
Search instead for 
Did you mean: 

Using double precision in a DMA callback seems to block it?

RAdam.1
Associate III

I am using a BlueNRG-LP and started with the CCA01M1 I2S project. I changed the callback so that it applies a volume to the stream in real time. But this seems to block the code if I use a double (which id like to do to see some precision - and I want to add a tone generator in there too). If I use a int16_t then it is fine and doesnt block,

If variable c is double then it blocks. If c is int then it works

anyone know why?

 /*Copy song fragment to Audio Output buffer*/

for(i=0; i< DMA_BUFFER_SIZE/2; i++)

{  

if (Amplifier.State == AMP_PLAYING)

{

c = *Amplifier.PlayPtr;

c /= 10;

c *= Amplifier.Volume;

d = (int16_t) c;

Amplifier.DMABuffer[i*2]= d; 

Amplifier.DMABuffer[i*2+1]= d; 

Amplifier.PlayPtr++;

1 ACCEPTED SOLUTION

Accepted Solutions
berendi
Principal

It has a CPU with no hardware floating point operations, all floating point calculations are computed by a software library. It takes a lot of time.

Use integer multiplications and bit shifts only.

View solution in original post

4 REPLIES 4
berendi
Principal

It has a CPU with no hardware floating point operations, all floating point calculations are computed by a software library. It takes a lot of time.

Use integer multiplications and bit shifts only.

Thanks berendi... your response is probably correct. Although simply changing the order of the math seems to make it work or not.

c = Fragment1[song_position];

mult = vol/10;

c *= (double) mult;

works ok. But ...

c = Fragment1[song_position];

c /= 10;

c *= (double) vol;

blocks it...

As you say maybe it is just the way the optimizer works or something to make it faster or slower.

Shame I cant create a tone or sweep on the fly (it uses the sin function) - I'll need to create it offline and just have it copied in from Flash which is a waste of storage

mult = vol/10; is a constant expression that the optimizer can move outside the loop, so it has to be calculated only once. In the original code, the division is performed on the sample in every loop iteration, so there are only half as many floating operations to calculate.

Using float instead of double should be even faster. You don't need double precision if the result is converted to 16 bits.

RAdam.1
Associate III

That makes absolute sense! Thanks so much for your kind help and clarity!