Add AVC control to control_sgtl5000.* and exampledds
@@ -621,6 +621,7 @@ unsigned short AudioControlSGTL5000::dac_vol(float left, float right) | |||
unsigned short m=(0xFC-calcVol(right,0xC0))<<8|(0xFC-calcVol(left,0xC0)); | |||
return modify(CHIP_DAC_VOL,m,65535); | |||
} | |||
// DAP_CONTROL | |||
unsigned short AudioControlSGTL5000::dap_mix_enable(uint8_t n) | |||
{ | |||
@@ -695,6 +696,55 @@ void AudioControlSGTL5000::load_peq(uint8_t filterNum, int *filterParameters) | |||
modify(DAP_FILTER_COEF_ACCESS,(uint16_t)filterNum,15); | |||
} | |||
/* Valid values for dap_avc parameters | |||
maxGain; Maximum gain that can be applied | |||
0 - 0 dB | |||
1 - 6.0 dB | |||
2 - 12 dB | |||
lbiResponse; Integrator Response | |||
0 - 0 mS | |||
1 - 25 mS | |||
2 - 50 mS | |||
3 - 100 mS | |||
hardLimit | |||
0 - Hard limit disabled. AVC Compressor/Expander enabled. | |||
1 - Hard limit enabled. The signal is limited to the programmed threshold (signal saturates at the threshold) | |||
threshold | |||
floating point in range 0 to -96 dB | |||
attack | |||
floating point figure is dB/s rate at which gain is increased | |||
decay | |||
floating point figure is dB/s rate at which gain is reduced | |||
*/ | |||
unsigned short AudioControlSGTL5000::dap_avc(uint8_t maxGain, uint8_t lbiResponse, uint8_t hardLimit, float threshold, float attack, float decay) | |||
{ | |||
if(maxGain>2) maxGain=2; | |||
lbiResponse&=3; | |||
hardLimit&=1; | |||
uint8_t thresh=(pow(10,threshold/20)*0.636)*pow(2,15); | |||
uint8_t att=(1-pow(10,-(attack/(20*44100))))*pow(2,19); | |||
uint8_t dec=(1-pow(10,-(decay/(20*44100))))*pow(2,23); | |||
write(DAP_AVC_THRESHOLD,thresh); | |||
write(DAP_AVC_ATTACK,att); | |||
write(DAP_AVC_DECAY,dec); | |||
return modify(DAP_AVC_CTRL,maxGain<<12|lbiResponse<<8|hardLimit<<5,3<<12|3<<8|1<<5); | |||
} | |||
unsigned short AudioControlSGTL5000::dap_avc_enable(uint8_t n) | |||
{ | |||
n&=1; | |||
return modify(DAP_AVC_CTRL,n,1); | |||
} | |||
unsigned short AudioControlSGTL5000::dap_avc_enable(void) | |||
{ | |||
return modify(DAP_AVC_CTRL,1,1); | |||
} | |||
unsigned char AudioControlSGTL5000::calcVol(float n, unsigned char range) | |||
{ | |||
n=(n*(((float)range)/100))+0.499; | |||
@@ -702,6 +752,7 @@ unsigned char AudioControlSGTL5000::calcVol(float n, unsigned char range) | |||
return (unsigned char)n; | |||
} | |||
// if(SGTL5000_PEQ) quantization_unit=524288; if(AudioFilterBiquad) quantization_unit=2147483648; | |||
void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef) | |||
{ |
@@ -68,9 +68,11 @@ public: | |||
void dap_audio_eq_geq(float bass, float mid_bass, float midrange, float mid_treble, float treble); | |||
void dap_audio_eq_tone(float bass, float treble); | |||
void load_peq(uint8_t filterNum, int *filterParameters); | |||
protected: | |||
unsigned short dap_avc(uint8_t maxGain, uint8_t lbiResponse, uint8_t hardLimit, float threshold, float attack, float decay); | |||
unsigned short dap_avc_enable(uint8_t n); | |||
unsigned short dap_avc_enable(void); | |||
protected: | |||
bool muted; | |||
bool volumeInteger(unsigned int n); // range: 0x00 to 0x80 | |||
uint16_t ana_ctrl; |
@@ -1,4 +1,7 @@ | |||
// Tone example using AudioFilterBiquad object and calcBiquad filter calculator routine. | |||
/* Tone example using AudioFilterBiquad object and calcBiquad filter calculator routine. | |||
This example code is in the public domain | |||
*/ | |||
#include <Audio.h> | |||
#include <Wire.h> |
@@ -1,5 +1,7 @@ | |||
// Tone example using SGTL5000 DAP PEQ filters and calcBiquad filter calculator routine. | |||
/* Tone example using SGTL5000 DAP PEQ filters and calcBiquad filter calculator routine. | |||
This example code is in the public domain | |||
*/ | |||
#include <Audio.h> | |||
#include <Wire.h> | |||
#include <SD.h> |
@@ -1,4 +1,7 @@ | |||
// DAC balance example: Will influence both HP & LO outputs. | |||
/* DAC balance example: Will influence both HP & LO outputs. | |||
This example code is in the public domain | |||
*/ | |||
#include <Audio.h> | |||
#include <Wire.h> |
@@ -1,4 +1,7 @@ | |||
// HP balance example: Will influence only HP output. | |||
/* HP balance example: Will influence only HP output. | |||
This example code is in the public domain | |||
*/ | |||
#include <Audio.h> | |||
#include <Wire.h> |
@@ -0,0 +1,63 @@ | |||
/* DAP AVC example; AVC is SGTL5000 equiv of AGC | |||
This example code is in the public domain | |||
*/ | |||
#include <Audio.h> | |||
#include <Wire.h> | |||
#include <SD.h> | |||
const int myInput = AUDIO_INPUT_LINEIN; | |||
// const int myInput = AUDIO_INPUT_MIC; | |||
// Create the Audio components. These should be created in the | |||
// order data flows, inputs/sources -> processing -> outputs | |||
// | |||
AudioInputI2S audioInput; // audio shield: mic or line-in | |||
AudioOutputI2S audioOutput; // audio shield: headphones & line-out | |||
// Create Audio connections between the components | |||
// | |||
AudioConnection c1(audioInput, 0, audioOutput, 0); // left passing through | |||
AudioConnection c2(audioInput, 1, audioOutput, 1); // right passing through | |||
// Create an object to control the audio shield. | |||
// | |||
AudioControlSGTL5000 audioShield; | |||
void setup() { | |||
// Audio connections require memory to work. For more | |||
// detailed information, see the MemoryAndCpuUsage example | |||
AudioMemory(4); | |||
// Enable the audio shield and set the output volume. | |||
audioShield.enable(); | |||
audioShield.inputSelect(myInput); | |||
audioShield.volume(75); | |||
audioShield.unmuteLineout(); | |||
// have to enable DAP to use AVC | |||
audioShield.dap_enable(); | |||
// here are some settings for AVC that have a fairly obvious effect | |||
audioShield.dap_avc(2,1,0,-5,0.5,0.5); // see comments starting line #699 of control_sgtl5000.cpp in ./libraries/audio/ | |||
// AVC has its own enable/disable bit | |||
audioShield.dap_avc_enable(); // you can use audioShield.dap_avc_enable(0); to turn off AVC | |||
} | |||
elapsedMillis chgMsec=0; | |||
float lastVol=1024; | |||
void loop() { | |||
// every 10 ms, check for adjustment the balance & vol | |||
if (chgMsec > 10) { // more regular updates for actual changes seems better. | |||
float vol1=analogRead(15)/10.23; | |||
vol1=(int)vol1; | |||
if(lastVol!=vol1) | |||
{ | |||
audioShield.volume(vol1); | |||
lastVol=vol1; | |||
} | |||
chgMsec = 0; | |||
} | |||
} | |||