|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882 |
-
-
- #include "control_sgtl5000.h"
- #include "Wire.h"
-
- #define CHIP_ID 0x0000
-
-
-
- #define CHIP_DIG_POWER 0x0002
-
-
-
-
-
-
- #define CHIP_CLK_CTRL 0x0004
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_I2S_CTRL 0x0006
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_SSS_CTRL 0x000A
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ADCDAC_CTRL 0x000E
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_DAC_VOL 0x0010
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_PAD_STRENGTH 0x0014
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_ADC_CTRL 0x0020
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_HP_CTRL 0x0022
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_CTRL 0x0024
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_LINREG_CTRL 0x0026
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_REF_CTRL 0x0028
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_MIC_CTRL 0x002A
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_LINE_OUT_CTRL 0x002C
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_LINE_OUT_VOL 0x002E
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_POWER 0x0030
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_PLL_CTRL 0x0032
-
-
-
- #define CHIP_CLK_TOP_CTRL 0x0034
-
-
-
-
-
-
-
-
-
-
-
-
- #define CHIP_ANA_STATUS 0x0036
-
-
-
-
-
-
- #define CHIP_ANA_TEST1 0x0038
- #define CHIP_ANA_TEST2 0x003A
-
- #define CHIP_SHORT_CTRL 0x003C
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #define DAP_CONTROL 0x0100
- #define DAP_PEQ 0x0102
- #define DAP_BASS_ENHANCE 0x0104
- #define DAP_BASS_ENHANCE_CTRL 0x0106
- #define DAP_AUDIO_EQ 0x0108
- #define DAP_SGTL_SURROUND 0x010A
- #define DAP_FILTER_COEF_ACCESS 0x010C
- #define DAP_COEF_WR_B0_MSB 0x010E
- #define DAP_COEF_WR_B0_LSB 0x0110
- #define DAP_AUDIO_EQ_BASS_BAND0 0x0116
- #define DAP_AUDIO_EQ_BAND1 0x0118
- #define DAP_AUDIO_EQ_BAND2 0x011A
- #define DAP_AUDIO_EQ_BAND3 0x011C
- #define DAP_AUDIO_EQ_TREBLE_BAND4 0x011E
- #define DAP_MAIN_CHAN 0x0120
- #define DAP_MIX_CHAN 0x0122
- #define DAP_AVC_CTRL 0x0124
- #define DAP_AVC_THRESHOLD 0x0126
- #define DAP_AVC_ATTACK 0x0128
- #define DAP_AVC_DECAY 0x012A
- #define DAP_COEF_WR_B1_MSB 0x012C
- #define DAP_COEF_WR_B1_LSB 0x012E
- #define DAP_COEF_WR_B2_MSB 0x0130
- #define DAP_COEF_WR_B2_LSB 0x0132
- #define DAP_COEF_WR_A1_MSB 0x0134
- #define DAP_COEF_WR_A1_LSB 0x0136
- #define DAP_COEF_WR_A2_MSB 0x0138
- #define DAP_COEF_WR_A2_LSB 0x013A
-
- #define SGTL5000_I2C_ADDR 0x0A
-
-
-
-
- bool AudioControlSGTL5000::enable(void)
- {
-
-
- muted = true;
- Wire.begin();
- delay(5);
-
-
-
-
-
- write(CHIP_ANA_POWER, 0x4060);
- write(CHIP_LINREG_CTRL, 0x006C);
- write(CHIP_REF_CTRL, 0x01F1);
- write(CHIP_LINE_OUT_CTRL, 0x0322);
- write(CHIP_SHORT_CTRL, 0x4446);
- write(CHIP_ANA_CTRL, 0x0137);
- write(CHIP_ANA_POWER, 0x40FF);
- write(CHIP_DIG_POWER, 0x0073);
- delay(400);
-
- write(CHIP_LINE_OUT_VOL, 0x0505);
- write(CHIP_CLK_CTRL, 0x0004);
- write(CHIP_I2S_CTRL, 0x0130);
-
- write(CHIP_SSS_CTRL, 0x0010);
- write(CHIP_ADCDAC_CTRL, 0x0000);
- write(CHIP_DAC_VOL, 0x3C3C);
- write(CHIP_ANA_HP_CTRL, 0x7F7F);
- write(CHIP_ANA_CTRL, 0x0136);
-
- return true;
- }
-
- unsigned int AudioControlSGTL5000::read(unsigned int reg)
- {
- unsigned int val;
-
- Wire.beginTransmission(SGTL5000_I2C_ADDR);
- Wire.write(reg >> 8);
- Wire.write(reg);
- if (Wire.endTransmission(false) != 0) return 0;
- if (Wire.requestFrom(SGTL5000_I2C_ADDR, 2) < 2) return 0;
- val = Wire.read() << 8;
- val |= Wire.read();
- return val;
- }
-
- bool AudioControlSGTL5000::write(unsigned int reg, unsigned int val)
- {
- if (reg == CHIP_ANA_CTRL) ana_ctrl = val;
- Wire.beginTransmission(SGTL5000_I2C_ADDR);
- Wire.write(reg >> 8);
- Wire.write(reg);
- Wire.write(val >> 8);
- Wire.write(val);
- if (Wire.endTransmission() == 0) return true;
- return false;
- }
-
- unsigned int AudioControlSGTL5000::modify(unsigned int reg, unsigned int val, unsigned int iMask)
- {
- unsigned int val1 = (read(reg)&(~iMask))|val;
- if(!write(reg,val1)) return 0;
- return val1;
- }
-
- bool AudioControlSGTL5000::volumeInteger(unsigned int n)
- {
- if (n == 0) {
- muted = true;
- write(CHIP_ANA_HP_CTRL, 0x7F7F);
- return muteHeadphone();
- } else if (n > 0x80) {
- n = 0;
- } else {
- n = 0x80 - n;
- }
- if (muted) {
- muted = false;
- unmuteHeadphone();
- }
- n = n | (n << 8);
- return write(CHIP_ANA_HP_CTRL, n);
- }
-
- bool AudioControlSGTL5000::volume(float left, float right)
- {
- unsigned short m=((0x7F-calcVol(right,0x7F))<<8)|(0x7F-calcVol(left,0x7F));
- return write(CHIP_ANA_HP_CTRL, m);
- }
-
-
-
- unsigned short AudioControlSGTL5000::lo_lvl(uint8_t n)
- {
- n&=31;
- return modify(CHIP_LINE_OUT_VOL,(n<<8)|n,(31<<8)|31);
- }
-
- unsigned short AudioControlSGTL5000::lo_lvl(uint8_t left, uint8_t right)
- {
- left&=31;
- right&=31;
- return modify(CHIP_LINE_OUT_VOL,(right<<8)|left,(31<<8)|31);
- }
-
- unsigned short AudioControlSGTL5000::dac_vol(float n)
- {
- if(read(CHIP_ADCDAC_CTRL)&(3<<2)!=((n>0 ? 0:3)<<2)) modify(CHIP_ADCDAC_CTRL,(n>0 ? 0:3)<<2,3<<2);
- unsigned char m=calcVol(n,0xC0);
- return modify(CHIP_DAC_VOL,((0xFC-m)<<8)|(0xFC-m),65535);
- }
- unsigned short AudioControlSGTL5000::dac_vol(float left, float right)
- {
- unsigned short adcdac=((right>0 ? 0:2)|(left>0 ? 0:1))<<2;
- if(read(CHIP_ADCDAC_CTRL)&(3<<2)!=adcdac) modify(CHIP_ADCDAC_CTRL,adcdac,1<<2);
- unsigned short m=(0xFC-calcVol(right,0xC0))<<8|(0xFC-calcVol(left,0xC0));
- return modify(CHIP_DAC_VOL,m,65535);
- }
-
-
- unsigned short AudioControlSGTL5000::dap_mix_enable(uint8_t n)
- {
- return modify(DAP_CONTROL,(n&1)<<4,1<<4);
- }
- unsigned short AudioControlSGTL5000::dap_enable(uint8_t n)
- {
- if(n) n=1;
- unsigned char DAC=1+(2*n);
- modify(DAP_CONTROL,n,1);
- return modify(CHIP_SSS_CTRL,(0<<6)|(DAC<<4),(3<<6)|(3<<4));
- }
-
- unsigned short AudioControlSGTL5000::dap_enable(void)
- {
- return dap_enable(1);
- }
-
-
- unsigned short AudioControlSGTL5000::dap_peqs(uint8_t n)
- {
- return modify(DAP_PEQ,(n&7),7);
- }
-
-
- unsigned short AudioControlSGTL5000::dap_audio_eq(uint8_t n)
- {
- return modify(DAP_AUDIO_EQ,n&3,3);
- }
-
-
-
- unsigned short AudioControlSGTL5000::dap_audio_eq_band(uint8_t bandNum, float n)
- {
- n=((n/100)*48)+0.499;
- if(n<-47) n=-47;
- if(n>48) n=48;
- n+=47;
- return modify(DAP_AUDIO_EQ_BASS_BAND0+(bandNum*2),(unsigned int)n,127);
- }
- void AudioControlSGTL5000::dap_audio_eq_geq(float bass, float mid_bass, float midrange, float mid_treble, float treble)
- {
- dap_audio_eq_band(0,bass);
- dap_audio_eq_band(1,mid_bass);
- dap_audio_eq_band(2,midrange);
- dap_audio_eq_band(3,mid_treble);
- dap_audio_eq_band(4,treble);
- }
- void AudioControlSGTL5000::dap_audio_eq_tone(float bass, float treble)
- {
- dap_audio_eq_band(0,bass);
- dap_audio_eq_band(4,treble);
- }
-
-
- void AudioControlSGTL5000::load_peq(uint8_t filterNum, int *filterParameters)
- {
-
-
- write(DAP_COEF_WR_B0_MSB,(*filterParameters>>4)&65535);
- write(DAP_COEF_WR_B0_LSB,(*filterParameters++)&15);
- write(DAP_COEF_WR_B1_MSB,(*filterParameters>>4)&65535);
- write(DAP_COEF_WR_B1_LSB,(*filterParameters++)&15);
- write(DAP_COEF_WR_B2_MSB,(*filterParameters>>4)&65535);
- write(DAP_COEF_WR_B2_LSB,(*filterParameters++)&15);
- write(DAP_COEF_WR_A1_MSB,(*filterParameters>>4)&65535);
- write(DAP_COEF_WR_A1_LSB,(*filterParameters++)&15);
- write(DAP_COEF_WR_A2_MSB,(*filterParameters>>4)&65535);
- write(DAP_COEF_WR_A2_LSB,(*filterParameters++)&15);
- write(DAP_FILTER_COEF_ACCESS,(uint16_t)0x100|filterNum);
- delay(10);
- modify(DAP_FILTER_COEF_ACCESS,(uint16_t)filterNum,15);
- }
-
-
- 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 short AudioControlSGTL5000::dap_bass_enhance(float lr_lev, float bass_lev)
- {
- return modify(DAP_BASS_ENHANCE_CTRL,(0x3F-calcVol(lr_lev,0x3F))<<8|0x7F-calcVol(bass_lev,0x7F),0x3F<<8|0x7F);
- }
- unsigned short AudioControlSGTL5000::dap_bass_enhance(float lr_lev, float bass_lev, uint8_t hpf_bypass, uint8_t cutoff)
- {
- modify(DAP_BASS_ENHANCE,(hpf_bypass&1)<<8|(cutoff&7)<<4,1<<8|7<<4);
- return dap_bass_enhance(lr_lev,bass_lev);
- }
- unsigned short AudioControlSGTL5000::dap_bass_enhance_enable(uint8_t n)
- {
- return modify(DAP_BASS_ENHANCE,n&1,1);
- }
- unsigned short AudioControlSGTL5000::dap_bass_enhance_enable(void)
- {
- return dap_bass_enhance_enable(1);
- }
- unsigned short AudioControlSGTL5000::dap_surround(uint8_t width)
- {
- return modify(DAP_SGTL_SURROUND,(width&7)<<4,7<<4);
- }
- unsigned short AudioControlSGTL5000::dap_surround(uint8_t width, uint8_t select)
- {
- return modify(DAP_SGTL_SURROUND,(width&7)<<4|select&3,7<<4|3);
- }
- unsigned short AudioControlSGTL5000::dap_surround_enable(uint8_t n)
- {
- if(n) n=3;
- return modify(DAP_SGTL_SURROUND,n,3);
- }
- unsigned short AudioControlSGTL5000::dap_surround_enable(void)
- {
- dap_surround_enable(1);
- }
-
-
- unsigned char AudioControlSGTL5000::calcVol(float n, unsigned char range)
- {
- n=(n*(((float)range)/100))+0.499;
- if ((unsigned char)n>range) n=range;
- return (unsigned char)n;
- }
-
-
-
- void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef)
- {
-
-
-
-
-
-
- float A;
- if(filtertype<FILTER_PARAEQ) A=pow(10,dB_Gain/20); else A=pow(10,dB_Gain/40);
- float W0 = 2*3.14159265358979323846*fC/fS;
- float cosw=cos(W0);
- float sinw=sin(W0);
-
-
- float alpha = sinw / (2 * Q);
- float beta = sqrt(A)/Q;
- float b0,b1,b2,a0,a1,a2;
-
- switch(filtertype) {
- case FILTER_LOPASS:
- b0 = (1.0F - cosw) * 0.5F;
- b1 = 1.0F - cosw;
- b2 = (1.0F - cosw) * 0.5F;
- a0 = 1.0F + alpha;
- a1 = 2.0F * cosw;
- a2 = alpha - 1.0F;
- break;
- case FILTER_HIPASS:
- b0 = (1.0F + cosw) * 0.5F;
- b1 = -(cosw + 1.0F);
- b2 = (1.0F + cosw) * 0.5F;
- a0 = 1.0F + alpha;
- a1 = 2.0F * cosw;
- a2 = alpha - 1.0F;
- break;
- case FILTER_BANDPASS:
- b0 = alpha;
- b1 = 0.0F;
- b2 = -alpha;
- a0 = 1.0F + alpha;
- a1 = 2.0F * cosw;
- a2 = alpha - 1.0F;
- break;
- case FILTER_NOTCH:
- b0=1;
- b1=-2*cosw;
- b2=1;
- a0=1+alpha;
- a1=2*cosw;
- a2=-(1-alpha);
- break;
- case FILTER_PARAEQ:
- b0 = 1 + (alpha*A);
- b1 =-2 * cosw;
- b2 = 1 - (alpha*A);
- a0 = 1 + (alpha/A);
- a1 = 2 * cosw;
- a2 =-(1-(alpha/A));
- break;
- case FILTER_LOSHELF:
- b0 = A * ((A+1.0F) - ((A-1.0F)*cosw) + (beta*sinw));
- b1 = 2.0F * A * ((A-1.0F) - ((A+1.0F)*cosw));
- b2 = A * ((A+1.0F) - ((A-1.0F)*cosw) - (beta*sinw));
- a0 = (A+1.0F) + ((A-1.0F)*cosw) + (beta*sinw);
- a1 = 2.0F * ((A-1.0F) + ((A+1.0F)*cosw));
- a2 = -((A+1.0F) + ((A-1.0F)*cosw) - (beta*sinw));
- break;
- case FILTER_HISHELF:
- b0 = A * ((A+1.0F) + ((A-1.0F)*cosw) + (beta*sinw));
- b1 = -2.0F * A * ((A-1.0F) + ((A+1.0F)*cosw));
- b2 = A * ((A+1.0F) + ((A-1.0F)*cosw) - (beta*sinw));
- a0 = (A+1.0F) - ((A-1.0F)*cosw) + (beta*sinw);
- a1 = -2.0F * ((A-1.0F) - ((A+1.0F)*cosw));
- a2 = -((A+1.0F) - ((A-1.0F)*cosw) - (beta*sinw));
- }
-
- a0=(a0*2)/(float)quantization_unit;
- b0/=a0;
- *coef++=(int)(b0+0.499);
- b1/=a0;
- *coef++=(int)(b1+0.499);
- b2/=a0;
- *coef++=(int)(b2+0.499);
- a1/=a0;
- *coef++=(int)(a1+0.499);
- a2/=a0;
- *coef++=(int)(a2+0.499);
- }
-
|