I have come across a piece of code on NXP website (ZIP file attched) which has been written for an LPC1700 micro controllers.
the software is very simple and aims to generate Audible medical alarms.
These micros family have a 10 bit DAC which means data buffer is 10 bit wide and can't take any value greater than 0x400.
looking at the code, file multi_tone_gen.c --> GenerateMultiTone (struct wave *t) ;
DAC->DACR = ((output >> 10) & 0xFFC0) + 0x8000; // make unsigned and output to DAC
When I run the code the input to DAC buffer is always greater than 0x400.
what am I missing here, am I just supposed to scale it down?
Note that I have ported this code into a PIC32 micro with 10 bit DAC module. it sounds the right melodies but it is not smooth. there is a roughness in the sound. when I scale down the input to the DAC buffer and lower it down to less than 0x400, the sounds get improved but still has that roughness in it.
Any idea what I am doing wrong?
regards,
even after that line of complex shifting the final input to the DAC buffer is still larger than 0x400
when I divide that value by 0x64 then the sound gets much smoother. However, still there is slight roughness in it
DAC->DACR = ( (((output >> 10) & 0xFFC0) + 0x8000) / 0x64 );
Hi,
As the following void GenerateMultiTone (struct wave *t), there is complex shifting operation, I suppose that the long output variable has 25 valid bits, that is why there is 10 bits right shift operation so that it matches with the DAC format:
DAC->DACR = ((output >> 10) & 0xFFC0) + 0x8000; // make unsigned and output to DAC
Pls debug the code step by step so that you can see the valid bits of the variables.
Hope it can help you
BR
XiangJun Rong
void GenerateMultiTone (struct wave *t)
{
long y;
unsigned char i;
unsigned char env_weights;
output = 0; // clear output accumulator
for (i=0;i<5;i++) // cycle through the 5 structures in the array
{
y = ((t->coef *(long long)(t->y1)>>14)) - t->y2; // Goertzel Calculation
t->y2 = t->y1; // store for next time
t->y1 = y; // store for next time
env_weights = envelope * ToneWeights[i]>>8;
output += ((t->y1* env_weights)>>8); // sum fundamental and harmonics
t++; // increment structure pointer
}
DAC->DACR = ((output >> 10) & 0xFFC0) + 0x8000; // make unsigned and output to DAC
if ((output >= 0)&& (output_old <= 0)) // zero crossing detect
{
if (envelope_off && (note_on==0))
{
envelope_on = 0; // sychronizes turn off with zero cross
envelope_off = 0; // reset envelope flag
}
}
output_old = output;
}