Audio designer SGTL5000 autoVolumeControl function: error in code- Solution found

bmillier

Well-known member
Teensyduino vers: 1.29

The SGTL5000 AutoVolumeControl function does not work as described. There are 3 incorrect lines in the code which result in the Threshold (16-bit), Attack(12-bit) and Decay(12-bit) registers of the SCTL5000 being loaded incorrectly.

In the file "control_sgtl5000.cpp" the following 3 lines

Line#
844 uint8_t thresh = (pow(10, threshold / 20)*0.636)*pow(2, 15);
845 uint8_t att=(1-pow(10,-(attack/(20*44100))))*pow(2,19);
846 uint8_t dec=(1-pow(10,-(decay/(20*44100))))*pow(2,23);

should be replaced with
uint16_t thresh = (pow(10, threshold / 20)*0.636)*pow(2, 15);
uint16_t att=(1-pow(10,-(attack/(20*44100))))*pow(2,19);
uint16_t dec=(1-pow(10,-(decay/(20*44100))))*pow(2,23);

This loads the registers with the proper 16, 12-bit values, and when I tested it out on the Audioshield, the AVC now works properly.
 
Teensyduino vers: 1.29

The SGTL5000 AutoVolumeControl function does not work as described. There are 3 incorrect lines in the code which result in the Threshold (16-bit), Attack(12-bit) and Decay(12-bit) registers of the SCTL5000 being loaded incorrectly.

In the file "control_sgtl5000.cpp" the following 3 lines

Line#
844 uint8_t thresh = (pow(10, threshold / 20)*0.636)*pow(2, 15);
845 uint8_t att=(1-pow(10,-(attack/(20*44100))))*pow(2,19);
846 uint8_t dec=(1-pow(10,-(decay/(20*44100))))*pow(2,23);

should be replaced with
uint16_t thresh = (pow(10, threshold / 20)*0.636)*pow(2, 15);
uint16_t att=(1-pow(10,-(attack/(20*44100))))*pow(2,19);
uint16_t dec=(1-pow(10,-(decay/(20*44100))))*pow(2,23);

This loads the registers with the proper 16, 12-bit values, and when I tested it out on the Audioshield, the AVC now works properly.

Though for the 3.5/3.6, perhaps powf should be used:

Code:
	uint16_t thresh = (powf(10f, threshold / 20.0f)*0.636f)*powf(2.0f, 15.0f);  
	uint16_t att=(1-powf(10f,-(attack/(20.0f*44100.0f))))*powf(2.0f,19.0f);    
	uint16_t dec=(1-powf(10.0f,-(decay/(20.f*44100.0f))))*pow(2.0f,23.0f);

The reason is powf is done in single precision floating point, which the machine supports directly, while pow is done in double precision, which is simulated on the Teensys.
 
Though for the 3.5/3.6, perhaps powf should be used:

Code:
	uint16_t thresh = (powf(10f, threshold / 20.0f)*0.636f)*powf(2.0f, 15.0f);  
	uint16_t att=(1-powf(10f,-(attack/(20.0f*44100.0f))))*powf(2.0f,19.0f);    
	uint16_t dec=(1-powf(10.0f,-(decay/(20.f*44100.0f))))*pow(2.0f,23.0f);

The reason is powf is done in single precision floating point, which the machine supports directly, while pow is done in double precision, which is simulated on the Teensys.

I expect you are right. I have a kickstarter T3.5 coming whenever they get shipped, but for now I am still using T3.2 & TD v1.29 and the big problem is the improperly cast variables, as I mentioned.
 
Back
Top