Semi automated routing, SGTL members renamed & gain/volume set around 1dds
| #include "analyze_peakdetect.h" | #include "analyze_peakdetect.h" | ||||
| // #define PEAKREPORTVERBS | |||||
| void AudioPeak::update(void) | void AudioPeak::update(void) | ||||
| { | { | ||||
| audio_block_t *block; | audio_block_t *block; | ||||
| const int16_t *p, *end; | const int16_t *p, *end; | ||||
| block = receiveReadOnly(); | block = receiveReadOnly(); | ||||
| if (!block) { | if (!block) { | ||||
| #ifdef PEAKREPORTVERBS | |||||
| Serial.println("AudioPeak !block"); | |||||
| #endif | |||||
| return; | return; | ||||
| } | } | ||||
| if (!m_enabled) { | if (!m_enabled) { | ||||
| if(d<min) min=d; | if(d<min) min=d; | ||||
| if(d>max) max=d; | if(d>max) max=d; | ||||
| } while (p < end); | } while (p < end); | ||||
| #ifdef PEAKREPORTVERBS | |||||
| Serial.println("AudioPeak ran"); | |||||
| #endif | |||||
| release(block); | release(block); | ||||
| } | } | ||||
| { | { | ||||
| if(!noReset) | if(!noReset) | ||||
| { | { | ||||
| min=0; | |||||
| max=0; | |||||
| min=32767; | |||||
| max=-32767; | |||||
| } | } | ||||
| m_enabled=true; | m_enabled=true; | ||||
| } | } | ||||
| uint16_t AudioPeak::Dpp(void) | uint16_t AudioPeak::Dpp(void) | ||||
| { | { | ||||
| return max-min; | |||||
| if(max>min) return max-min; else return 0; | |||||
| } | } | ||||
| write(CHIP_ANA_HP_CTRL, 0x7F7F); // set volume (lowest level) | write(CHIP_ANA_HP_CTRL, 0x7F7F); // set volume (lowest level) | ||||
| write(CHIP_ANA_CTRL, 0x0136); // enable zero cross detectors | write(CHIP_ANA_CTRL, 0x0136); // enable zero cross detectors | ||||
| //mute = false; | //mute = false; | ||||
| semi_automated = true; | |||||
| return true; | return true; | ||||
| } | } | ||||
| unsigned int AudioControlSGTL5000::read(unsigned int reg) | unsigned int AudioControlSGTL5000::read(unsigned int reg) | ||||
| { | { | ||||
| unsigned int val; | unsigned int val; | ||||
| Wire.beginTransmission(SGTL5000_I2C_ADDR); | Wire.beginTransmission(SGTL5000_I2C_ADDR); | ||||
| Wire.write(reg >> 8); | Wire.write(reg >> 8); | ||||
| Wire.write(reg); | Wire.write(reg); | ||||
| return val1; | return val1; | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::route(uint8_t i2s_out, uint8_t dac, uint8_t dap, uint8_t dap_mix) | |||||
| { | |||||
| i2s_out&=3; | |||||
| dac&=3; | |||||
| dap&=3; | |||||
| dap_mix&=3; | |||||
| if((i2s_out==SGTL_AUDIO_PROCESSOR)||(dac==SGTL_AUDIO_PROCESSOR)) modify(DAP_CONTROL,1,1); // enable DAP | |||||
| return modify(CHIP_SSS_CTRL,(dap_mix<<8)|(dap<<6)|(dac<<4)|i2s_out,(3<<8)|(3<<6)|(3<<4)|3); | |||||
| } | |||||
| bool AudioControlSGTL5000::volumeInteger(unsigned int n) | bool AudioControlSGTL5000::volumeInteger(unsigned int n) | ||||
| { | { | ||||
| if (n == 0) { | if (n == 0) { | ||||
| // CHIP_LINE_OUT_VOL | // CHIP_LINE_OUT_VOL | ||||
| unsigned short AudioControlSGTL5000::lo_lvl(uint8_t n) | |||||
| unsigned short AudioControlSGTL5000::lineOutLevel(uint8_t n) | |||||
| { | { | ||||
| n&=31; | n&=31; | ||||
| return modify(CHIP_LINE_OUT_VOL,(n<<8)|n,(31<<8)|31); | return modify(CHIP_LINE_OUT_VOL,(n<<8)|n,(31<<8)|31); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::lo_lvl(uint8_t left, uint8_t right) | |||||
| unsigned short AudioControlSGTL5000::lineOutLevel(uint8_t left, uint8_t right) | |||||
| { | { | ||||
| left&=31; | left&=31; | ||||
| right&=31; | right&=31; | ||||
| return modify(CHIP_LINE_OUT_VOL,(right<<8)|left,(31<<8)|31); | return modify(CHIP_LINE_OUT_VOL,(right<<8)|left,(31<<8)|31); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dac_vol(float n) // set both directly | |||||
| unsigned short AudioControlSGTL5000::dacVolume(float n) // set both directly | |||||
| { | { | ||||
| if(read(CHIP_ADCDAC_CTRL)&(3<<2)!=((n>0 ? 0:3)<<2)) modify(CHIP_ADCDAC_CTRL,(n>0 ? 0:3)<<2,3<<2); | 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); | unsigned char m=calcVol(n,0xC0); | ||||
| return modify(CHIP_DAC_VOL,((0xFC-m)<<8)|(0xFC-m),65535); | return modify(CHIP_DAC_VOL,((0xFC-m)<<8)|(0xFC-m),65535); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dac_vol(float left, float right) | |||||
| unsigned short AudioControlSGTL5000::dacVolume(float left, float right) | |||||
| { | { | ||||
| unsigned short adcdac=((right>0 ? 0:2)|(left>0 ? 0:1))<<2; | 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); | if(read(CHIP_ADCDAC_CTRL)&(3<<2)!=adcdac) modify(CHIP_ADCDAC_CTRL,adcdac,1<<2); | ||||
| return modify(CHIP_DAC_VOL,m,65535); | return modify(CHIP_DAC_VOL,m,65535); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::adc_hpf(uint8_t bypass, uint8_t freeze) | |||||
| unsigned short AudioControlSGTL5000::adcHighPassFilterControl(uint8_t bypass, uint8_t freeze) | |||||
| { | { | ||||
| return modify(CHIP_ADCDAC_CTRL, (freeze&1)<<1|bypass&1,3); | return modify(CHIP_ADCDAC_CTRL, (freeze&1)<<1|bypass&1,3); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::adc_hpf(uint8_t bypass) | |||||
| unsigned short AudioControlSGTL5000::adcHighPassFilterControl(uint8_t bypass) | |||||
| { | { | ||||
| return modify(CHIP_ADCDAC_CTRL, bypass&1,1); | return modify(CHIP_ADCDAC_CTRL, bypass&1,1); | ||||
| } | } | ||||
| // DAP_CONTROL | // DAP_CONTROL | ||||
| unsigned short AudioControlSGTL5000::dap_mix_enable(uint8_t n) | |||||
| unsigned short AudioControlSGTL5000::audioMixerEnable(uint8_t n) | |||||
| { | { | ||||
| return modify(DAP_CONTROL,(n&1)<<4,1<<4); | return modify(DAP_CONTROL,(n&1)<<4,1<<4); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_enable(uint8_t n) | |||||
| unsigned short AudioControlSGTL5000::audioProcessorEnable(uint8_t n) | |||||
| { | { | ||||
| if(n) n=1; | if(n) n=1; | ||||
| unsigned char DAC=1+(2*n); // I2S_IN if n==0 else DAP | |||||
| unsigned char i2s_sel=3*n; // ADC if n==0 else DAP | |||||
| modify(DAP_CONTROL,n,1); | modify(DAP_CONTROL,n,1); | ||||
| return modify(CHIP_SSS_CTRL,(0<<6)|(DAC<<4),(3<<6)|(3<<4)); | |||||
| return route(i2s_sel,SGTL_I2S_TEENSY,SGTL_ADC); | |||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_enable(void) | |||||
| unsigned short AudioControlSGTL5000::audioProcessorEnable(void) | |||||
| { | { | ||||
| return dap_enable(1); | |||||
| return audioProcessorEnable(1); | |||||
| } | } | ||||
| // DAP_PEQ | // DAP_PEQ | ||||
| unsigned short AudioControlSGTL5000::dap_peqs(uint8_t n) // valid to n&7, 0 thru 7 filters enabled. | |||||
| unsigned short AudioControlSGTL5000::eqFilterCount(uint8_t n) // valid to n&7, 0 thru 7 filters enabled. | |||||
| { | { | ||||
| return modify(DAP_PEQ,(n&7),7); | return modify(DAP_PEQ,(n&7),7); | ||||
| } | } | ||||
| // DAP_AUDIO_EQ | // DAP_AUDIO_EQ | ||||
| unsigned short AudioControlSGTL5000::dap_audio_eq(uint8_t n) // 0=NONE, 1=PEQ (7 IIR Biquad filters), 2=TONE (tone), 3=GEQ (5 band EQ) | |||||
| unsigned short AudioControlSGTL5000::eqSelect(uint8_t n) // 0=NONE, 1=PEQ (7 IIR Biquad filters), 2=TONE (tone), 3=GEQ (5 band EQ) | |||||
| { | { | ||||
| return modify(DAP_AUDIO_EQ,n&3,3); | return modify(DAP_AUDIO_EQ,n&3,3); | ||||
| } | } | ||||
| // DAP_AUDIO_EQ_BASS_BAND0 & DAP_AUDIO_EQ_BAND1 & DAP_AUDIO_EQ_BAND2 etc etc | |||||
| unsigned short AudioControlSGTL5000::dap_audio_eq_band(uint8_t bandNum, float n) // by signed percentage -100/+100; dap_audio_eq(3); | |||||
| { // 0x00==-12dB, 0x2F==0dB, 0x5F==12dB | |||||
| 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); | |||||
| unsigned short AudioControlSGTL5000::eqBand(uint8_t bandNum, float n) | |||||
| { | |||||
| if(semi_automated) automate(1,3); | |||||
| return dap_audio_eq_band(bandNum, n); | |||||
| } | } | ||||
| void AudioControlSGTL5000::dap_audio_eq_geq(float bass, float mid_bass, float midrange, float mid_treble, float treble) | |||||
| void AudioControlSGTL5000::eqBands(float bass, float mid_bass, float midrange, float mid_treble, float treble) | |||||
| { | { | ||||
| if(semi_automated) automate(1,3); | |||||
| dap_audio_eq_band(0,bass); | dap_audio_eq_band(0,bass); | ||||
| dap_audio_eq_band(1,mid_bass); | dap_audio_eq_band(1,mid_bass); | ||||
| dap_audio_eq_band(2,midrange); | dap_audio_eq_band(2,midrange); | ||||
| dap_audio_eq_band(3,mid_treble); | dap_audio_eq_band(3,mid_treble); | ||||
| dap_audio_eq_band(4,treble); | dap_audio_eq_band(4,treble); | ||||
| } | } | ||||
| void AudioControlSGTL5000::dap_audio_eq_tone(float bass, float treble) // dap_audio_eq(2); | |||||
| void AudioControlSGTL5000::eqBands(float bass, float treble) // dap_audio_eq(2); | |||||
| { | { | ||||
| if(semi_automated) automate(1,2); | |||||
| dap_audio_eq_band(0,bass); | dap_audio_eq_band(0,bass); | ||||
| dap_audio_eq_band(4,treble); | dap_audio_eq_band(4,treble); | ||||
| } | } | ||||
| // SGTL5000 PEQ Coefficient loader | // SGTL5000 PEQ Coefficient loader | ||||
| void AudioControlSGTL5000::load_peq(uint8_t filterNum, int *filterParameters) | |||||
| void AudioControlSGTL5000::eqFilter(uint8_t filterNum, int *filterParameters) | |||||
| { | { | ||||
| // 1111 11111111 11111111 | |||||
| // TODO: add the part that selects 7 PEQ filters. | |||||
| if(semi_automated) automate(1,1,filterNum+1); | |||||
| modify(DAP_FILTER_COEF_ACCESS,(uint16_t)filterNum,15); | |||||
| write(DAP_COEF_WR_B0_MSB,(*filterParameters>>4)&65535); | write(DAP_COEF_WR_B0_MSB,(*filterParameters>>4)&65535); | ||||
| write(DAP_COEF_WR_B0_LSB,(*filterParameters++)&15); | write(DAP_COEF_WR_B0_LSB,(*filterParameters++)&15); | ||||
| write(DAP_COEF_WR_B1_MSB,(*filterParameters>>4)&65535); | write(DAP_COEF_WR_B1_MSB,(*filterParameters>>4)&65535); | ||||
| write(DAP_COEF_WR_A2_MSB,(*filterParameters>>4)&65535); | write(DAP_COEF_WR_A2_MSB,(*filterParameters>>4)&65535); | ||||
| write(DAP_COEF_WR_A2_LSB,(*filterParameters++)&15); | write(DAP_COEF_WR_A2_LSB,(*filterParameters++)&15); | ||||
| write(DAP_FILTER_COEF_ACCESS,(uint16_t)0x100|filterNum); | write(DAP_FILTER_COEF_ACCESS,(uint16_t)0x100|filterNum); | ||||
| delay(10); // seems necessary, didn't work for 1ms. | |||||
| modify(DAP_FILTER_COEF_ACCESS,(uint16_t)filterNum,15); | |||||
| } | } | ||||
| /* Valid values for dap_avc parameters | /* Valid values for dap_avc parameters | ||||
| decay | decay | ||||
| floating point figure is dB/s rate at which gain is reduced | 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) | |||||
| unsigned short AudioControlSGTL5000::autoVolumeControl(uint8_t maxGain, uint8_t lbiResponse, uint8_t hardLimit, float threshold, float attack, float decay) | |||||
| { | { | ||||
| if(semi_automated&&(!read(DAP_CONTROL)&1)) audioProcessorEnable(1); | |||||
| if(maxGain>2) maxGain=2; | if(maxGain>2) maxGain=2; | ||||
| lbiResponse&=3; | lbiResponse&=3; | ||||
| hardLimit&=1; | hardLimit&=1; | ||||
| write(DAP_AVC_DECAY,dec); | write(DAP_AVC_DECAY,dec); | ||||
| return modify(DAP_AVC_CTRL,maxGain<<12|lbiResponse<<8|hardLimit<<5,3<<12|3<<8|1<<5); | 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) | |||||
| unsigned short AudioControlSGTL5000::autoVolumeEnable(uint8_t n) | |||||
| { | { | ||||
| n&=1; | n&=1; | ||||
| return modify(DAP_AVC_CTRL,n,1); | return modify(DAP_AVC_CTRL,n,1); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_avc_enable(void) | |||||
| unsigned short AudioControlSGTL5000::autoVolumeEnable(void) | |||||
| { | { | ||||
| return modify(DAP_AVC_CTRL,1,1); | return modify(DAP_AVC_CTRL,1,1); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_bass_enhance(float lr_lev, float bass_lev) | |||||
| unsigned short AudioControlSGTL5000::enhanceBass(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); | 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) | |||||
| unsigned short AudioControlSGTL5000::enhanceBass(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); | modify(DAP_BASS_ENHANCE,(hpf_bypass&1)<<8|(cutoff&7)<<4,1<<8|7<<4); | ||||
| return dap_bass_enhance(lr_lev,bass_lev); | |||||
| return enhanceBass(lr_lev,bass_lev); | |||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_bass_enhance_enable(uint8_t n) | |||||
| unsigned short AudioControlSGTL5000::enhanceBassEnable(uint8_t n) | |||||
| { | { | ||||
| return modify(DAP_BASS_ENHANCE,n&1,1); | return modify(DAP_BASS_ENHANCE,n&1,1); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_bass_enhance_enable(void) | |||||
| unsigned short AudioControlSGTL5000::enhanceBassEnable(void) | |||||
| { | { | ||||
| return dap_bass_enhance_enable(1); | |||||
| return enhanceBassEnable(1); | |||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_surround(uint8_t width) | |||||
| unsigned short AudioControlSGTL5000::surroundSound(uint8_t width) | |||||
| { | { | ||||
| return modify(DAP_SGTL_SURROUND,(width&7)<<4,7<<4); | return modify(DAP_SGTL_SURROUND,(width&7)<<4,7<<4); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_surround(uint8_t width, uint8_t select) | |||||
| unsigned short AudioControlSGTL5000::surroundSound(uint8_t width, uint8_t select) | |||||
| { | { | ||||
| return modify(DAP_SGTL_SURROUND,(width&7)<<4|select&3,7<<4|3); | return modify(DAP_SGTL_SURROUND,(width&7)<<4|select&3,7<<4|3); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_surround_enable(uint8_t n) | |||||
| unsigned short AudioControlSGTL5000::surroundSoundEnable(uint8_t n) | |||||
| { | { | ||||
| if(n) n=3; | if(n) n=3; | ||||
| return modify(DAP_SGTL_SURROUND,n,3); | return modify(DAP_SGTL_SURROUND,n,3); | ||||
| } | } | ||||
| unsigned short AudioControlSGTL5000::dap_surround_enable(void) | |||||
| unsigned short AudioControlSGTL5000::surroundSoundEnable(void) | |||||
| { | { | ||||
| dap_surround_enable(1); | |||||
| surroundSoundEnable(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; | |||||
| n=(n*(float)range)+0.499; | |||||
| if ((unsigned char)n>range) n=range; | if ((unsigned char)n>range) n=range; | ||||
| return (unsigned char)n; | return (unsigned char)n; | ||||
| } | } | ||||
| // DAP_AUDIO_EQ_BASS_BAND0 & DAP_AUDIO_EQ_BAND1 & DAP_AUDIO_EQ_BAND2 etc etc | |||||
| unsigned short AudioControlSGTL5000::dap_audio_eq_band(uint8_t bandNum, float n) // by signed percentage -100/+100; dap_audio_eq(3); | |||||
| { | |||||
| n=(n*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::automate(uint8_t dap, uint8_t eq) | |||||
| { | |||||
| if((dap!=0)&&(!read(DAP_CONTROL)&1)) audioProcessorEnable(1); | |||||
| if(read(DAP_AUDIO_EQ)&3!=eq) eqSelect(eq); | |||||
| } | |||||
| void AudioControlSGTL5000::automate(uint8_t dap, uint8_t eq, uint8_t filterCount) | |||||
| { | |||||
| automate(dap,eq); | |||||
| if(filterCount>read(DAP_PEQ)&7) eqFilterCount(filterCount); | |||||
| } | |||||
| // 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) |
| #include "AudioControl.h" | #include "AudioControl.h" | ||||
| #define SGTL_ADC 0 | |||||
| #define SGTL_I2S_TEENSY 1 | |||||
| #define SGTL_AUDIO_PROCESSOR 3 | |||||
| class AudioControlSGTL5000 : public AudioControl | class AudioControlSGTL5000 : public AudioControl | ||||
| { | { | ||||
| public: | public: | ||||
| bool enable(void); | bool enable(void); | ||||
| bool disable(void) { return false; } | bool disable(void) { return false; } | ||||
| bool volume(float n) { return volumeInteger(n * 1.29 + 0.499); } | |||||
| bool volume(float n) { return volumeInteger(n * 129 + 0.499); } | |||||
| bool inputLevel(float n) {return false;} | bool inputLevel(float n) {return false;} | ||||
| bool muteHeadphone(void) { return write(0x0024, ana_ctrl | (1<<4)); } | bool muteHeadphone(void) { return write(0x0024, ana_ctrl | (1<<4)); } | ||||
| bool unmuteHeadphone(void) { return write(0x0024, ana_ctrl & ~(1<<4)); } | bool unmuteHeadphone(void) { return write(0x0024, ana_ctrl & ~(1<<4)); } | ||||
| //bool inputLinein(void) { return write(0x0024, ana_ctrl | (1<<2)); } | //bool inputLinein(void) { return write(0x0024, ana_ctrl | (1<<2)); } | ||||
| //bool inputMic(void) { return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2)); } | //bool inputMic(void) { return write(0x002A, 0x0172) && write(0x0024, ana_ctrl & ~(1<<2)); } | ||||
| unsigned short route(uint8_t i2s_out, uint8_t dac, uint8_t dap, uint8_t dap_mix); | |||||
| unsigned short route(uint8_t i2s_out, uint8_t dac, uint8_t dap) { return route(i2s_out,dac,dap,0); } | |||||
| bool volume(float left, float right); | bool volume(float left, float right); | ||||
| unsigned short micGain(unsigned int n) { return modify(0x002A, n&3, 3); } | unsigned short micGain(unsigned int n) { return modify(0x002A, n&3, 3); } | ||||
| unsigned short lo_lvl(uint8_t n); | |||||
| unsigned short lo_lvl(uint8_t left, uint8_t right); | |||||
| unsigned short dac_vol(float n); | |||||
| unsigned short dac_vol(float left, float right); | |||||
| unsigned short adc_hpf(uint8_t bypass, uint8_t freeze); | |||||
| unsigned short adc_hpf(uint8_t bypass); | |||||
| unsigned short dap_mix_enable(uint8_t n); | |||||
| unsigned short dap_enable(uint8_t n); | |||||
| unsigned short dap_enable(void); | |||||
| unsigned short dap_peqs(uint8_t n); | |||||
| unsigned short dap_audio_eq(uint8_t n); | |||||
| unsigned short dap_audio_eq_band(uint8_t bandNum, float n); | |||||
| 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); | |||||
| 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); | |||||
| unsigned short dap_bass_enhance(float lr_lev, float bass_lev); | |||||
| unsigned short dap_bass_enhance(float lr_lev, float bass_lev, uint8_t hpf_bypass, uint8_t cutoff); | |||||
| unsigned short dap_bass_enhance_enable(uint8_t n); | |||||
| unsigned short dap_bass_enhance_enable(void); | |||||
| unsigned short dap_surround(uint8_t width); | |||||
| unsigned short dap_surround(uint8_t width, uint8_t select); | |||||
| unsigned short dap_surround_enable(uint8_t n); | |||||
| unsigned short dap_surround_enable(void); | |||||
| unsigned short lineOutLevel(uint8_t n); | |||||
| unsigned short lineOutLevel(uint8_t left, uint8_t right); | |||||
| unsigned short dacVolume(float n); | |||||
| unsigned short dacVolume(float left, float right); | |||||
| unsigned short adcHighPassFilterControl(uint8_t bypass, uint8_t freeze); | |||||
| unsigned short adcHighPassFilterControl(uint8_t bypass); | |||||
| unsigned short audioMixerEnable(uint8_t n); | |||||
| unsigned short audioProcessorEnable(uint8_t n); | |||||
| unsigned short audioProcessorEnable(void); | |||||
| unsigned short eqFilterCount(uint8_t n); | |||||
| unsigned short eqSelect(uint8_t n); | |||||
| unsigned short eqBand(uint8_t bandNum, float n); | |||||
| void eqBands(float bass, float mid_bass, float midrange, float mid_treble, float treble); | |||||
| void eqBands(float bass, float treble); | |||||
| void eqFilter(uint8_t filterNum, int *filterParameters); | |||||
| unsigned short autoVolumeControl(uint8_t maxGain, uint8_t lbiResponse, uint8_t hardLimit, float threshold, float attack, float decay); | |||||
| unsigned short autoVolumeEnable(uint8_t n); | |||||
| unsigned short autoVolumeEnable(void); | |||||
| unsigned short enhanceBass(float lr_lev, float bass_lev); | |||||
| unsigned short enhanceBass(float lr_lev, float bass_lev, uint8_t hpf_bypass, uint8_t cutoff); | |||||
| unsigned short enhanceBassEnable(uint8_t n); | |||||
| unsigned short enhanceBassEnable(void); | |||||
| unsigned short surroundSound(uint8_t width); | |||||
| unsigned short surroundSound(uint8_t width, uint8_t select); | |||||
| unsigned short surroundSoundEnable(uint8_t n); | |||||
| unsigned short surroundSoundEnable(void); | |||||
| void killAutomation(void) { semi_automated=false; } | |||||
| protected: | |||||
| 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; | ||||
| unsigned int read(unsigned int reg); | unsigned int read(unsigned int reg); | ||||
| bool write(unsigned int reg, unsigned int val); | bool write(unsigned int reg, unsigned int val); | ||||
| unsigned int modify(unsigned int reg, unsigned int val, unsigned int iMask); | unsigned int modify(unsigned int reg, unsigned int val, unsigned int iMask); | ||||
| unsigned short dap_audio_eq_band(uint8_t bandNum, float n); | |||||
| private: | |||||
| bool semi_automated; | |||||
| void automate(uint8_t dap, uint8_t eq); | |||||
| void automate(uint8_t dap, uint8_t eq, uint8_t filterCount); | |||||
| }; | }; | ||||
| //For Filter Type: 0 = LPF, 1 = HPF, 2 = BPF, 3 = NOTCH, 4 = PeakingEQ, 5 = LowShelf, 6 = HighShelf | //For Filter Type: 0 = LPF, 1 = HPF, 2 = BPF, 3 = NOTCH, 4 = PeakingEQ, 5 = LowShelf, 6 = HighShelf |
| // Enable the audio shield, select the input and set the output volume. | // Enable the audio shield, select the input and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(75); | |||||
| audioShield.volume(0.75); | |||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| calcBiquad(FILTER_PARAEQ,110,0,0.2,2147483648,44100,updateFilter); | calcBiquad(FILTER_PARAEQ,110,0,0.2,2147483648,44100,updateFilter); | ||||
| calcBiquad(FILTER_PARAEQ,4400,0,0.167,2147483648,44100,updateFilter); | calcBiquad(FILTER_PARAEQ,4400,0,0.167,2147483648,44100,updateFilter); | ||||
| filterTone_L.updateCoefs(1,updateFilter); | filterTone_L.updateCoefs(1,updateFilter); | ||||
| filterTone_R.updateCoefs(1,updateFilter); | filterTone_R.updateCoefs(1,updateFilter); | ||||
| Serial.begin(9600); | |||||
| } | } | ||||
| elapsedMillis chgMsec=0; | elapsedMillis chgMsec=0; |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.volume(82); | |||||
| audioShield.volume(0.82); | |||||
| while (!Serial) ; | while (!Serial) ; | ||||
| delay(100); | delay(100); |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(60); | |||||
| audioShield.volume(0.6); | |||||
| } | } | ||||
| void loop() { | void loop() { |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(60); | |||||
| audioShield.volume(0.6); | |||||
| } | } | ||||
| elapsedMillis volmsec=0; | elapsedMillis volmsec=0; | ||||
| // every 50 ms, adjust the volume | // every 50 ms, adjust the volume | ||||
| if (volmsec > 50) { | if (volmsec > 50) { | ||||
| float vol = analogRead(15); | float vol = analogRead(15); | ||||
| vol = vol / 10.24; | |||||
| vol = vol / 1024; | |||||
| audioShield.volume(vol); | audioShield.volume(vol); | ||||
| volmsec = 0; | volmsec = 0; | ||||
| } | } |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(60); | |||||
| audioShield.volume(0.6); | |||||
| } | } | ||||
| elapsedMillis volmsec=0; | elapsedMillis volmsec=0; |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.volume(60); | |||||
| audioShield.volume(0.6); | |||||
| } | } | ||||
| void loop() { | void loop() { |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(60); | |||||
| audioShield.volume(0.60); | |||||
| } | } | ||||
| elapsedMillis volmsec=0; | elapsedMillis volmsec=0; |
| // turn on the output | // turn on the output | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.volume(50); | |||||
| audioShield.volume(0.5); | |||||
| // by default the Teensy 3.1 DAC uses 3.3Vp-p output | // by default the Teensy 3.1 DAC uses 3.3Vp-p output | ||||
| // if your 3.3V power has noise, switching to the | // if your 3.3V power has noise, switching to the |
| AudioMemory(8); | AudioMemory(8); | ||||
| codec.enable(); | codec.enable(); | ||||
| codec.volume(volume); | |||||
| codec.volume(0.5); | |||||
| // I want output on the line out too | // I want output on the line out too | ||||
| codec.unmuteLineout(); | codec.unmuteLineout(); | ||||
| int n = analogRead(15); | int n = analogRead(15); | ||||
| if (n != volume) { | if (n != volume) { | ||||
| volume = n; | volume = n; | ||||
| codec.volume((float)n / 10.23); | |||||
| codec.volume((float)n / 1023); | |||||
| } | } | ||||
| c = *sp++; | c = *sp++; |
| AudioMemory(10); | AudioMemory(10); | ||||
| codec.enable(); | codec.enable(); | ||||
| codec.volume(volume); | |||||
| codec.volume(0.5); | |||||
| // I want output on the line out too | // I want output on the line out too | ||||
| // Comment this if you don't it | // Comment this if you don't it | ||||
| codec.unmuteLineout(); | codec.unmuteLineout(); | ||||
| int n = analogRead(15); | int n = analogRead(15); | ||||
| if (n != volume) { | if (n != volume) { | ||||
| volume = n; | volume = n; | ||||
| codec.volume((float)n / 10.23); | |||||
| codec.volume((float)n / 1023); | |||||
| } | } | ||||
| // read the next note from the table | // read the next note from the table |
| AudioMemory(5); | AudioMemory(5); | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.volume(20); | |||||
| audioShield.volume(0.5); | |||||
| SPI.setMOSI(7); | SPI.setMOSI(7); | ||||
| SPI.setSCK(14); | SPI.setSCK(14); | ||||
| void loop() { | void loop() { | ||||
| float vol = analogRead(15); | float vol = analogRead(15); | ||||
| vol = vol / 10.24; | |||||
| vol = vol / 1024; | |||||
| audioShield.volume(vol); | audioShield.volume(vol); | ||||
| delay(20); | delay(20); | ||||
| } | } |
| // Enable the audio shield, select the input and set the output volume. | // Enable the audio shield, select the input and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(75); | |||||
| audioShield.volume(0.75); | |||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| audioShield.dap_enable(); // enable the DAP block in SGTL5000 | |||||
| audioShield.dap_audio_eq(1); // using PEQ Biquad filters | |||||
| audioShield.dap_peqs(2); // enable filter 0 & filter 1 | |||||
| calcBiquad(FILTER_PARAEQ,110,0,0.2,524288,44100,updateFilter); | |||||
| audioShield.load_peq(0,updateFilter); | |||||
| // audioShield.audioProcessorEnable(); // enable the DAP block in SGTL5000 | |||||
| // audioShield.eqSelect(1); // using PEQ Biquad filters | |||||
| // audioShield.eqFilterCount(2); // enable filter 0 & filter 1 | |||||
| calcBiquad(FILTER_PARAEQ,110,0,0.2,524288,44100,updateFilter); // automation negates the need | |||||
| audioShield.eqFilter(0,updateFilter); // for the three lines commented out above. | |||||
| calcBiquad(FILTER_PARAEQ,4400,0,0.167,524288,44100,updateFilter); | calcBiquad(FILTER_PARAEQ,4400,0,0.167,524288,44100,updateFilter); | ||||
| audioShield.load_peq(1,updateFilter); | |||||
| audioShield.eqFilter(1,updateFilter); | |||||
| } | } | ||||
| elapsedMillis chgMsec=0; | elapsedMillis chgMsec=0; | ||||
| { | { | ||||
| // calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*); | // calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*); | ||||
| calcBiquad(FILTER_PARAEQ,110,-tone2,0.2,524288,44100,updateFilter); | calcBiquad(FILTER_PARAEQ,110,-tone2,0.2,524288,44100,updateFilter); | ||||
| audioShield.load_peq(0,updateFilter); | |||||
| audioShield.eqFilter(0,updateFilter); | |||||
| calcBiquad(FILTER_PARAEQ,4400,tone2,0.167,524288,44100,updateFilter); | calcBiquad(FILTER_PARAEQ,4400,tone2,0.167,524288,44100,updateFilter); | ||||
| audioShield.load_peq(1,updateFilter); | |||||
| audioShield.eqFilter(1,updateFilter); | |||||
| tone1=tone2; | tone1=tone2; | ||||
| } | } | ||||
| chgMsec = 0; | chgMsec = 0; |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(75); | |||||
| audioShield.volume(0.75); | |||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| } | } | ||||
| // every 10 ms, check for adjustment | // every 10 ms, check for adjustment | ||||
| if (chgMsec > 10) { | if (chgMsec > 10) { | ||||
| float bal1=analogRead(15); | float bal1=analogRead(15); | ||||
| bal1=((bal1-512)/512)*100; | |||||
| bal1=((bal1-512)/512); | |||||
| bal1=(int)bal1; | bal1=(int)bal1; | ||||
| if(lastBal!=bal1) | if(lastBal!=bal1) | ||||
| { | { | ||||
| if(bal1<0) | if(bal1<0) | ||||
| { // leaning toward left... | { // leaning toward left... | ||||
| audioShield.dac_vol(100,100+bal1); | |||||
| audioShield.dacVolume(1,1+bal1); | |||||
| } else if(bal1>0) { // to the right | } else if(bal1>0) { // to the right | ||||
| audioShield.dac_vol(100-bal1,100); | |||||
| audioShield.dacVolume(1-bal1,1); | |||||
| } else { // middle | } else { // middle | ||||
| audioShield.dac_vol(100); | |||||
| audioShield.dacVolume(1); | |||||
| } | } | ||||
| lastBal=bal1; | lastBal=bal1; | ||||
| } | } |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(60); | |||||
| audioShield.volume(0.75); | |||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| } | } | ||||
| elapsedMillis chgMsec=0; | elapsedMillis chgMsec=0; | ||||
| float lastBal=1024; | float lastBal=1024; | ||||
| float vol1=75; | |||||
| float vol1=0.75; | |||||
| void loop() { | void loop() { | ||||
| // every 10 ms, check for adjustment | // every 10 ms, check for adjustment | ||||
| if (chgMsec > 10) { | if (chgMsec > 10) { | ||||
| float bal1=analogRead(15); | float bal1=analogRead(15); | ||||
| bal1=((bal1-512)/512)*100; | |||||
| bal1=((bal1-512)/512); | |||||
| bal1=(int)bal1; | bal1=(int)bal1; | ||||
| if(lastBal!=bal1) | if(lastBal!=bal1) | ||||
| { | { | ||||
| if(bal1<0) | if(bal1<0) | ||||
| { | { | ||||
| audioShield.volume(vol1,(vol1/100)*(100+bal1)); | |||||
| audioShield.volume(vol1,vol1*(1+bal1)); | |||||
| } else { | } else { | ||||
| audioShield.volume((vol1/100)*(100-bal1),vol1); | |||||
| audioShield.volume(vol1*(1-bal1),vol1); | |||||
| } | } | ||||
| lastBal=bal1; | lastBal=bal1; | ||||
| } | } |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(75); | |||||
| audioShield.volume(0.75); | |||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| // have to enable DAP to use AVC | |||||
| audioShield.dap_enable(); | |||||
| // here are some settings for AVC that have a fairly obvious effect | // 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/ | |||||
| audioShield.autoVolumeControl(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 | // AVC has its own enable/disable bit | ||||
| audioShield.dap_avc_enable(); // you can use audioShield.dap_avc_enable(0); to turn off AVC | |||||
| // you can use audioShield.autoVolumeEnable(0); to turn off AVC | |||||
| } | } | ||||
| elapsedMillis chgMsec=0; | elapsedMillis chgMsec=0; |
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(75); | |||||
| audioShield.volume(0.75); | |||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| // have to enable DAP to use bass enhance | |||||
| audioShield.dap_enable(); | |||||
| audioShield.dap_bass_enhance_enable(); // all we need to do for default bass enhancement settings. | |||||
| // audioShield.dap_bass_enhance((float)lr_level,(float)bass_level); | |||||
| // audioShield.dap_bass_enhance((float)lr_level,(float)bass_level,(uint8_t)hpf_bypass,(uint8_t)cutoff); | |||||
| // just enable it to use default settings. | |||||
| audioShield.enhanceBassEnable(); // all we need to do for default bass enhancement settings. | |||||
| // audioShield.enhanceBass((float)lr_level,(float)bass_level); | |||||
| // audioShield.enhanceBass((float)lr_level,(float)bass_level,(uint8_t)hpf_bypass,(uint8_t)cutoff); | |||||
| // please see http://www.pjrc.com/teensy/SGTL5000.pdf page 50 for valid values for BYPASS_HPF and CUTOFF | // please see http://www.pjrc.com/teensy/SGTL5000.pdf page 50 for valid values for BYPASS_HPF and CUTOFF | ||||
| } | } | ||||
| // Enable the audio shield and set the output volume. | // Enable the audio shield and set the output volume. | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(60); | |||||
| audioShield.volume(0.6); | |||||
| lcd.begin(16, 2); | lcd.begin(16, 2); | ||||
| lcd.print("Audio Spectrum"); | lcd.print("Audio Spectrum"); |
| AudioMemory(6); | AudioMemory(6); | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(75); | |||||
| audioShield.volume(0.75); | |||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| Serial.begin(Serial.baud()); | Serial.begin(Serial.baud()); | ||||
| } | } |
| AudioMemory(2); | AudioMemory(2); | ||||
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.volume(50); | |||||
| audioShield.volume(0.5); | |||||
| // I want output on the line out too | // I want output on the line out too | ||||
| audioShield.unmuteLineout(); | audioShield.unmuteLineout(); | ||||
| // audioShield.muteHeadphone(); | // audioShield.muteHeadphone(); |
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(50); | |||||
| audioShield.volume(0.5); | |||||
| // Warn that the passthru pin is grounded | // Warn that the passthru pin is grounded | ||||
| if(!digitalRead(PASSTHRU_PIN)) { | if(!digitalRead(PASSTHRU_PIN)) { | ||||
| int n = analogRead(15); | int n = analogRead(15); | ||||
| if (n != volume) { | if (n != volume) { | ||||
| volume = n; | volume = n; | ||||
| audioShield.volume((float)n / 10.23); | |||||
| audioShield.volume((float)n / 1023); | |||||
| } | } | ||||
| if(0) { | if(0) { | ||||
| if(millis() - last_time >= 5000) { | if(millis() - last_time >= 5000) { |
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(50); | |||||
| audioShield.volume(0.5); | |||||
| // Warn that the passthru pin is grounded | // Warn that the passthru pin is grounded | ||||
| if(!digitalRead(PASSTHRU_PIN)) { | if(!digitalRead(PASSTHRU_PIN)) { |
| audioShield.enable(); | audioShield.enable(); | ||||
| audioShield.inputSelect(myInput); | audioShield.inputSelect(myInput); | ||||
| audioShield.volume(50); | |||||
| audioShield.volume(0.5); | |||||
| // Warn that the passthru pin is grounded | // Warn that the passthru pin is grounded | ||||
| if(!digitalRead(PASSTHRU_PIN)) { | if(!digitalRead(PASSTHRU_PIN)) { | ||||
| int n = analogRead(15); | int n = analogRead(15); | ||||
| if (n != volume) { | if (n != volume) { | ||||
| volume = n; | volume = n; | ||||
| audioShield.volume((float)n / 10.23); | |||||
| audioShield.volume((float)n / 1023); | |||||
| } | } | ||||
| // update the two buttons | // update the two buttons |