Add AVC control to control_sgtl5000.* and exampledds
unsigned short m=(0xFC-calcVol(right,0xC0))<<8|(0xFC-calcVol(left,0xC0)); | unsigned short m=(0xFC-calcVol(right,0xC0))<<8|(0xFC-calcVol(left,0xC0)); | ||||
return modify(CHIP_DAC_VOL,m,65535); | return modify(CHIP_DAC_VOL,m,65535); | ||||
} | } | ||||
// DAP_CONTROL | // DAP_CONTROL | ||||
unsigned short AudioControlSGTL5000::dap_mix_enable(uint8_t n) | unsigned short AudioControlSGTL5000::dap_mix_enable(uint8_t n) | ||||
{ | { | ||||
modify(DAP_FILTER_COEF_ACCESS,(uint16_t)filterNum,15); | 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) | unsigned char AudioControlSGTL5000::calcVol(float n, unsigned char range) | ||||
{ | { | ||||
n=(n*(((float)range)/100))+0.499; | n=(n*(((float)range)/100))+0.499; | ||||
return (unsigned char)n; | return (unsigned char)n; | ||||
} | } | ||||
// if(SGTL5000_PEQ) quantization_unit=524288; if(AudioFilterBiquad) quantization_unit=2147483648; | // 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) | void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef) | ||||
{ | { |
void dap_audio_eq_geq(float bass, float mid_bass, float midrange, float mid_treble, float treble); | 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 dap_audio_eq_tone(float bass, float treble); | ||||
void load_peq(uint8_t filterNum, int *filterParameters); | 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 muted; | ||||
bool volumeInteger(unsigned int n); // range: 0x00 to 0x80 | bool volumeInteger(unsigned int n); // range: 0x00 to 0x80 | ||||
uint16_t ana_ctrl; | uint16_t ana_ctrl; |
// 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 <Audio.h> | ||||
#include <Wire.h> | #include <Wire.h> |
// 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 <Audio.h> | ||||
#include <Wire.h> | #include <Wire.h> | ||||
#include <SD.h> | #include <SD.h> |
// 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 <Audio.h> | ||||
#include <Wire.h> | #include <Wire.h> |
// 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 <Audio.h> | ||||
#include <Wire.h> | #include <Wire.h> |
/* 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; | |||||
} | |||||
} | |||||