return (float)sum * (1.0 / 16384.0); | return (float)sum * (1.0 / 16384.0); | ||||
} | } | ||||
void averageTogether(uint8_t n) { | void averageTogether(uint8_t n) { | ||||
if (n == 0) n == 1; | |||||
if (n == 0) n = 1; | |||||
naverage = n; | naverage = n; | ||||
} | } | ||||
void windowFunction(const int16_t *w) { | void windowFunction(const int16_t *w) { |
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) { | ||||
unsigned short AudioControlSGTL5000::dacVolume(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::dacVolume(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); | |||||
} | |||||
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); | ||||
} | } | ||||
unsigned short AudioControlSGTL5000::adcHighPassFilterControl(uint8_t bypass, uint8_t freeze) | |||||
unsigned short AudioControlSGTL5000::adcHighPassFilterEnable(void) | |||||
{ | { | ||||
return modify(CHIP_ADCDAC_CTRL, (freeze&1)<<1|bypass&1,3); | |||||
return modify(CHIP_ADCDAC_CTRL, 0, 3); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::adcHighPassFilterControl(uint8_t bypass) | |||||
unsigned short AudioControlSGTL5000::adcHighPassFilterFreeze(void) | |||||
{ | { | ||||
return modify(CHIP_ADCDAC_CTRL, bypass&1,1); | |||||
return modify(CHIP_ADCDAC_CTRL, 2, 3); | |||||
} | |||||
unsigned short AudioControlSGTL5000::adcHighPassFilterDisable(void) | |||||
{ | |||||
return modify(CHIP_ADCDAC_CTRL, 1, 3); | |||||
} | } | ||||
// DAP_CONTROL | // DAP_CONTROL | ||||
unsigned short AudioControlSGTL5000::audioMixerEnable(uint8_t n) | |||||
unsigned short AudioControlSGTL5000::audioPreProcessorEnable(void) | |||||
{ | { | ||||
return modify(DAP_CONTROL,(n&1)<<4,1<<4); | |||||
// audio processor used to pre-process analog input before Teensy | |||||
return write(DAP_CONTROL, 1) && write(CHIP_SSS_CTRL, 0x0013); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::audioProcessorEnable(uint8_t n) | |||||
unsigned short AudioControlSGTL5000::audioPostProcessorEnable(void) | |||||
{ | { | ||||
if(n) n=1; | |||||
unsigned char i2s_sel=3*n; // ADC if n==0 else DAP | |||||
modify(DAP_CONTROL,n,1); | |||||
return route(i2s_sel,SGTL_I2S_TEENSY,SGTL_ADC); | |||||
// audio processor used to post-process Teensy output before headphones/lineout | |||||
return write(DAP_CONTROL, 1) && write(CHIP_SSS_CTRL, 0x0070); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::audioProcessorEnable(void) | |||||
unsigned short AudioControlSGTL5000::audioProcessorDisable(void) | |||||
{ | { | ||||
return audioProcessorEnable(1); | |||||
return write(CHIP_SSS_CTRL, 0x0010) && write(DAP_CONTROL, 0); | |||||
} | } | ||||
// DAP_PEQ | // DAP_PEQ | ||||
unsigned short AudioControlSGTL5000::eqFilterCount(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. | ||||
{ | { | ||||
*/ | */ | ||||
unsigned short AudioControlSGTL5000::autoVolumeControl(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(semi_automated&&(!read(DAP_CONTROL)&1)) audioProcessorEnable(); | |||||
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::autoVolumeEnable(uint8_t n) | |||||
unsigned short AudioControlSGTL5000::autoVolumeEnable(void) | |||||
{ | { | ||||
n&=1; | |||||
return modify(DAP_AVC_CTRL,n,1); | |||||
return modify(DAP_AVC_CTRL, 1, 1); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::autoVolumeEnable(void) | |||||
unsigned short AudioControlSGTL5000::autoVolumeDisable(void) | |||||
{ | { | ||||
return modify(DAP_AVC_CTRL,1,1); | |||||
return modify(DAP_AVC_CTRL, 0, 1); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::enhanceBass(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::enhanceBass(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 enhanceBass(lr_lev,bass_lev); | return enhanceBass(lr_lev,bass_lev); | ||||
} | } | ||||
unsigned short AudioControlSGTL5000::enhanceBassEnable(uint8_t n) | |||||
unsigned short AudioControlSGTL5000::enhanceBassEnable(void) | |||||
{ | { | ||||
return modify(DAP_BASS_ENHANCE,n&1,1); | |||||
return modify(DAP_BASS_ENHANCE, 1, 1); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::enhanceBassEnable(void) | |||||
unsigned short AudioControlSGTL5000::enhanceBassDisable(void) | |||||
{ | { | ||||
return enhanceBassEnable(1); | |||||
return modify(DAP_BASS_ENHANCE, 0, 1); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::surroundSound(uint8_t width) | unsigned short AudioControlSGTL5000::surroundSound(uint8_t width) | ||||
{ | { | ||||
} | } | ||||
unsigned short AudioControlSGTL5000::surroundSound(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::surroundSoundEnable(uint8_t n) | |||||
unsigned short AudioControlSGTL5000::surroundSoundEnable(void) | |||||
{ | { | ||||
if(n) n=3; | |||||
return modify(DAP_SGTL_SURROUND,n,3); | |||||
return modify(DAP_SGTL_SURROUND, 3, 3); | |||||
} | } | ||||
unsigned short AudioControlSGTL5000::surroundSoundEnable(void) | |||||
unsigned short AudioControlSGTL5000::surroundSoundDisable(void) | |||||
{ | { | ||||
surroundSoundEnable(1); | |||||
return modify(DAP_SGTL_SURROUND, 0, 3); | |||||
} | } | ||||
unsigned char AudioControlSGTL5000::calcVol(float n, unsigned char range) | unsigned char AudioControlSGTL5000::calcVol(float n, unsigned char range) | ||||
void AudioControlSGTL5000::automate(uint8_t dap, uint8_t eq) | 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); | |||||
//if((dap!=0)&&(!(read(DAP_CONTROL)&1))) audioProcessorEnable(); | |||||
if((read(DAP_AUDIO_EQ)&3) != eq) eqSelect(eq); | |||||
} | } | ||||
void AudioControlSGTL5000::automate(uint8_t dap, uint8_t eq, uint8_t filterCount) | void AudioControlSGTL5000::automate(uint8_t dap, uint8_t eq, uint8_t filterCount) | ||||
{ | { | ||||
automate(dap,eq); | automate(dap,eq); | ||||
if(filterCount>read(DAP_PEQ)&7) eqFilterCount(filterCount); | |||||
if (filterCount > (read(DAP_PEQ)&7)) eqFilterCount(filterCount); | |||||
} | } | ||||
float A; | float A; | ||||
if(filtertype<FILTER_PARAEQ) A=pow(10,dB_Gain/20); else A=pow(10,dB_Gain/40); | 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 W0 = 2*3.14159265358979323846*fC/fS; | ||||
float cosw=cos(W0); | |||||
float sinw=sin(W0); | |||||
float cosw=cosf(W0); | |||||
float sinw=sinf(W0); | |||||
//float alpha = sinw*sinh((log(2)/2)*BW*W0/sinw); | //float alpha = sinw*sinh((log(2)/2)*BW*W0/sinw); | ||||
//float beta = sqrt(2*A); | //float beta = sqrt(2*A); | ||||
float alpha = sinw / (2 * Q); | float alpha = sinw / (2 * Q); | ||||
float beta = sqrt(A)/Q; | |||||
float beta = sqrtf(A)/Q; | |||||
float b0,b1,b2,a0,a1,a2; | float b0,b1,b2,a0,a1,a2; | ||||
switch(filtertype) { | switch(filtertype) { | ||||
a0 = (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)); | a1 = -2.0F * ((A-1.0F) - ((A+1.0F)*cosw)); | ||||
a2 = -((A+1.0F) - ((A-1.0F)*cosw) - (beta*sinw)); | a2 = -((A+1.0F) - ((A-1.0F)*cosw) - (beta*sinw)); | ||||
default: | |||||
b0 = 0.5; | |||||
b1 = 0.0; | |||||
b2 = 0.0; | |||||
a0 = 1.0; | |||||
a1 = 0.0; | |||||
a2 = 0.0; | |||||
} | } | ||||
a0=(a0*2)/(float)quantization_unit; // once here instead of five times there... | a0=(a0*2)/(float)quantization_unit; // once here instead of five times there... |
#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: | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
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); | ||||
bool micGain(unsigned int dB); | bool micGain(unsigned int dB); | ||||
bool lineInLevel(uint8_t n) { return lineInLevel(n, n); } | bool lineInLevel(uint8_t n) { return lineInLevel(n, n); } | ||||
unsigned short lineOutLevel(uint8_t left, uint8_t right); | unsigned short lineOutLevel(uint8_t left, uint8_t right); | ||||
unsigned short dacVolume(float n); | unsigned short dacVolume(float n); | ||||
unsigned short dacVolume(float left, float right); | 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 adcHighPassFilterEnable(void); | |||||
unsigned short adcHighPassFilterFreeze(void); | |||||
unsigned short adcHighPassFilterDisable(void); | |||||
//unsigned short adcHighPassFilterControl(uint8_t bypass, uint8_t freeze); | |||||
//unsigned short adcHighPassFilterControl(uint8_t bypass); | |||||
unsigned short audioPreProcessorEnable(void); | |||||
unsigned short audioPostProcessorEnable(void); | |||||
unsigned short audioProcessorDisable(void); | |||||
unsigned short eqFilterCount(uint8_t n); | unsigned short eqFilterCount(uint8_t n); | ||||
unsigned short eqSelect(uint8_t n); | unsigned short eqSelect(uint8_t n); | ||||
unsigned short eqBand(uint8_t bandNum, float n); | unsigned short eqBand(uint8_t bandNum, float n); | ||||
void eqBands(float bass, float treble); | void eqBands(float bass, float treble); | ||||
void eqFilter(uint8_t filterNum, int *filterParameters); | 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 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 autoVolumeEnable(void); | ||||
unsigned short autoVolumeDisable(void); | |||||
unsigned short enhanceBass(float lr_lev, float bass_lev); | 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 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 enhanceBassEnable(void); | ||||
unsigned short enhanceBassDisable(void); | |||||
unsigned short surroundSound(uint8_t width); | unsigned short surroundSound(uint8_t width); | ||||
unsigned short surroundSound(uint8_t width, uint8_t select); | unsigned short surroundSound(uint8_t width, uint8_t select); | ||||
unsigned short surroundSoundEnable(uint8_t n); | |||||
unsigned short surroundSoundEnable(void); | unsigned short surroundSoundEnable(void); | ||||
unsigned short surroundSoundDisable(void); | |||||
void killAutomation(void) { semi_automated=false; } | void killAutomation(void) { semi_automated=false; } | ||||
protected: | protected: |
} | } | ||||
void loop() { | void loop() { | ||||
float n; | |||||
int i; | |||||
if (myFFT.available()) { | if (myFFT.available()) { | ||||
// each time new FFT data is available | // each time new FFT data is available | ||||
// print it all to the Arduino Serial Monitor | // print it all to the Arduino Serial Monitor | ||||
Serial.print("FFT: "); | Serial.print("FFT: "); | ||||
for (int i=0; i<40; i++) { | |||||
Serial.print(myFFT.read(i)); | |||||
//Serial.print(myFFT.output[i]); | |||||
Serial.print(" "); | |||||
for (i=0; i<40; i++) { | |||||
n = myFFT.read(i); | |||||
if (n >= 0.01) { | |||||
Serial.print(n); | |||||
Serial.print(" "); | |||||
} else { | |||||
Serial.print(" - "); | |||||
} | |||||
} | } | ||||
Serial.println(); | Serial.println(); | ||||
} | } |
tr.even {background-color:#E0E0E0} | tr.even {background-color:#E0E0E0} | ||||
p.func {padding-bottom:0; margin:0px} | p.func {padding-bottom:0; margin:0px} | ||||
p.desc {padding-left:2em; margin:0px; padding-top:0.2em; padding-bottom:0.8em; font-size:0.75em} | p.desc {padding-left:2em; margin:0px; padding-top:0.2em; padding-bottom:0.8em; font-size:0.75em} | ||||
pre.desc {padding-left:3em; margin:0px; padding-top:0em; padding-bottom:0.8em; font-size:0.75em; | |||||
background-color:#FFFFFF; border:0px; line-height:100%; | |||||
} | |||||
span.indent {padding-left:2em} | span.indent {padding-left:2em} | ||||
span.literal {color: #006699} | span.literal {color: #006699} | ||||
span.comment {color: #777755} | span.comment {color: #777755} |
The input number is in decibels, from 0 to 63. | The input number is in decibels, from 0 to 63. | ||||
</p> | </p> | ||||
<h3>Signal Adjustment</h3> | |||||
<h3>Signal Levels</h3> | |||||
<p>The SGTL5000 supports flexible signal routing (inside the chip) and | |||||
many optional signal conditioning features.</p> | |||||
<p>The default signal levels should be used for most applications, | |||||
but these functions allow you to customize the analog signals.</p> | |||||
<p class=func><span class=keyword>route</span>(i2s, dac, dap);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>route</span>(i2s, dac, dap, dapmix);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>muteHeadphone</span>();</p> | <p class=func><span class=keyword>muteHeadphone</span>();</p> | ||||
<p class=desc>Silence the headphone output. | <p class=desc>Silence the headphone output. | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>unmuteHeadphone</span>();</p> | <p class=func><span class=keyword>unmuteHeadphone</span>();</p> | ||||
<p class=desc>Turn the headphone output on. | <p class=desc>Turn the headphone output on. | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>unmuteLineout</span>();</p> | |||||
<p class=desc>Turn the line level outputs on. | |||||
</p> | |||||
<p class=func><span class=keyword>muteLineout</span>();</p> | <p class=func><span class=keyword>muteLineout</span>();</p> | ||||
<p class=desc>Silence the line level outputs. | <p class=desc>Silence the line level outputs. | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>lineInLevel</span>(both);</p> | |||||
<p class=desc>blah blah blah blah | |||||
<p class=func><span class=keyword>unmuteLineout</span>();</p> | |||||
<p class=desc>Turn the line level outputs on. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>lineInLevel</span>(both);</p> | |||||
<p class=desc style="padding-bottom:0.2em;">Adjust the sensitivity of the line-level inputs. | |||||
Fifteen settings are possible: | |||||
</p> | |||||
<pre class="desc"> | |||||
0: 3.12 Volts p-p | |||||
1: 2.63 Volts p-p | |||||
2: 2.22 Volts p-p | |||||
3: 1.87 Volts p-p | |||||
4: 1.58 Volts p-p | |||||
5: 1.33 Volts p-p (default) | |||||
6: 1.11 Volts p-p | |||||
7: 0.94 Volts p-p | |||||
8: 0.79 Volts p-p | |||||
9: 0.67 Volts p-p | |||||
10: 0.56 Volts p-p | |||||
11: 0.48 Volts p-p | |||||
12: 0.40 Volts p-p | |||||
13: 0.34 Volts p-p | |||||
14: 0.29 Volts p-p | |||||
15: 0.24 Volts p-p | |||||
</pre> | |||||
<p class=func><span class=keyword>lineInLevel</span>(left, right);</p> | <p class=func><span class=keyword>lineInLevel</span>(left, right);</p> | ||||
<p class=desc>blah blah blah blah | |||||
<p class=desc>Adjust the sensitivity of the line-level inputs, with different | |||||
settings for left and right. The same 15 settings are available. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>lineOutLevel</span>(both);</p> | <p class=func><span class=keyword>lineOutLevel</span>(both);</p> | ||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=desc style="padding-bottom:0.2em;">Adjust the line level outout voltage range. The following | |||||
settings are possible: | |||||
</p> | |||||
<pre class="desc"> | |||||
13: 3.16 Volts p-p | |||||
14: 2.98 Volts p-p | |||||
15: 2.83 Volts p-p | |||||
16: 2.67 Volts p-p | |||||
17: 2.53 Volts p-p | |||||
18: 2.39 Volts p-p | |||||
19: 2.26 Volts p-p | |||||
20: 2.14 Volts p-p | |||||
21: 2.02 Volts p-p | |||||
22: 1.91 Volts p-p | |||||
23: 1.80 Volts p-p | |||||
24: 1.71 Volts p-p | |||||
25: 1.62 Volts p-p | |||||
26: 1.53 Volts p-p | |||||
27: 1.44 Volts p-p | |||||
28: 1.37 Volts p-p | |||||
29: 1.29 Volts p-p (default) | |||||
30: 1.22 Volts p-p | |||||
31: 1.16 Volts p-p | |||||
</pre> | |||||
<p class=func><span class=keyword>lineOutLevel</span>(left, right);</p> | <p class=func><span class=keyword>lineOutLevel</span>(left, right);</p> | ||||
<p class=desc>blah blah blah blah | |||||
<p class=desc>Adjust the line level outout voltage range, with separate | |||||
settings for left and right. The same settings (13 to 31) are available. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>dacVolume</span>(both);</p> | |||||
<p class=desc>blah blah blah blah | |||||
<h3>Signal Conditioning</h3> | |||||
<p>Usually these digital signal conditioning features should be left at their | |||||
default settings. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>dacVolume</span>(left, right);</p> | |||||
<p class=desc>blah blah blah blah | |||||
<p class=func><span class=keyword>adcHighPassFilterFreeze</span>();</p> | |||||
<p class=desc>By default, the analog input (either line-level inputs or mic) | |||||
is high-pass filtered, to remove any DC component. This function | |||||
freezes the filter, so the DC component is still substracted, but | |||||
the filter stops tracking any DC or low frequency changes. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>adcHighPassFilterControl</span>(bypass, freeze);</p> | |||||
<p class=desc>blah blah blah blah | |||||
<p class=func><span class=keyword>adcHighPassFilterDisable</span>();</p> | |||||
<p class=desc>Completely disable the analog input filter. DC and sub-audible | |||||
low frequencies are allowed to enter the digital signal. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>adcHighPassFilterControl</span>(bypass);</p> | |||||
<p class=desc>blah blah blah blah | |||||
<p class=func><span class=keyword>adcHighPassFilterEnable</span>();</p> | |||||
<p class=desc>Turn the DC-blocking filter back on, if disabled, or | |||||
allows it to resume tracking DC and low frequency changes, if | |||||
previously frozen. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>audioMixerEnable</span>(n);</p> | |||||
<p class=desc>blah blah blah blah | |||||
<p class=func><span class=keyword>dacVolume</span>(both);</p> | |||||
<p class=desc>Normally output volume should be used with volume(), which | |||||
changes the analog gain in the headphone amplifier. This function | |||||
controls digital attenuation before conversion to analog, which | |||||
reduces resolution, but allows another fine control of output | |||||
signal level. The ranges is 0 to 1.0, with the default at 1.0. | |||||
</p> | |||||
<p class=func><span class=keyword>dacVolume</span>(left, right);</p> | |||||
<p class=desc>Adjust the digital output volume separately on left and | |||||
right channels. | |||||
</p> | </p> | ||||
<h3>Audio Processor</h3> | <h3>Audio Processor</h3> | ||||
<p>An optional digital audio processor, capable of implementing a | |||||
<p>The optional digital audio processor is capable of implementing | |||||
automatic volume control, a | |||||
simple equalizer, filtering, bass enhancement and surround sound | simple equalizer, filtering, bass enhancement and surround sound | ||||
is available. It can process audio input before the SGTL5000 | |||||
sends it by I2S to Teensy, or it can process Teensy's I2S output | |||||
before converting the digital data to analog signals.</p> | |||||
is available. | |||||
</p> | |||||
<p>These signal processing features are implemented in the SGTL5000 chip, | |||||
so they do not consume CPU time on Teensy. | |||||
</p> | |||||
<p class=func><span class=keyword>audioProcessorEnable</span>(n);</p> | |||||
<p class=desc>blah blah blah blah | |||||
<p class=func><span class=keyword>audioPreProcessorEnable</span>();</p> | |||||
<p class=desc>Enable the audio processor to pre-process the input | |||||
(from either line-level inputs or microphone) before it's sent | |||||
to Teensy by I2S. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>audioProcessorEnable</span>();</p> | |||||
<p class=desc>blah blah blah blah | |||||
<p class=func><span class=keyword>audioPostProcessorEnable</span>();</p> | |||||
<p class=desc>Enable the audio processor to post-process Teensy's | |||||
I2S output before it's turned into analog signals for the | |||||
headphones and/or line level outputs. | |||||
</p> | |||||
<p class=func><span class=keyword>audioProcessorDisable</span>();</p> | |||||
<p class=desc>Disable the audio processor. | |||||
</p> | </p> | ||||
<p class=func><span class=keyword>eqFilterCount</span>(n);</p> | <p class=func><span class=keyword>eqFilterCount</span>(n);</p> | ||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
<p class=func><span class=keyword>autoVolumeControl</span>(maxGain, response, hardLimit, threshold, attack, decay);</p> | <p class=func><span class=keyword>autoVolumeControl</span>(maxGain, response, hardLimit, threshold, attack, decay);</p> | ||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>autoVolumeEnable</span>(n);</p> | |||||
<p class=func><span class=keyword>autoVolumeEnable</span>();</p> | |||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>autoVolumeEnable</span>();</p> | |||||
<p class=func><span class=keyword>autoVolumeDisable</span>();</p> | |||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev);</p> | <p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev);</p> | ||||
<p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev, hpf_bypass, cutoff);</p> | <p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev, hpf_bypass, cutoff);</p> | ||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>enhanceBassEnable</span>(n);</p> | |||||
<p class=func><span class=keyword>enhanceBassEnable</span>();</p> | |||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>enhanceBassEnable</span>();</p> | |||||
<p class=func><span class=keyword>enhanceBassDisable</span>();</p> | |||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>surroundSound</span>(width);</p> | <p class=func><span class=keyword>surroundSound</span>(width);</p> | ||||
<p class=func><span class=keyword>surroundSound</span>(width, select);</p> | <p class=func><span class=keyword>surroundSound</span>(width, select);</p> | ||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>surroundSoundEnable</span>(n);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>surroundSoundEnable</span>();</p> | <p class=func><span class=keyword>surroundSoundEnable</span>();</p> | ||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<p class=func><span class=keyword>killAutomation</span>();</p> | |||||
<p class=func><span class=keyword>surroundSoundDisable</span>();</p> | |||||
<p class=desc>blah blah blah blah | <p class=desc>blah blah blah blah | ||||
</p> | </p> | ||||
<h3>Notes</h3> | <h3>Notes</h3> | ||||
<p>TODO: how does the input AGC work | |||||
</p> | |||||
<p>TODO: document signal routing | |||||
</p> | |||||
<p>TODO: line level output adjust is weird arbitrary integers. Should this be | |||||
made into more sensible numbers, or do we just document the integer-voltage | |||||
measurements that correspond to the audio shield's hardware? | |||||
</p> | |||||
<p>TODO: make some sense out of the terribly complex audio processor features & options! | |||||
</p> | |||||
<p>TODO: can some of these enable functions be eliminated and have those features | |||||
automatically enabled or disabled depending on whether the route() function has | |||||
configured signals to/from them? | |||||
<p>TODO: document the many audio processor features & functions! | |||||
</p> | </p> | ||||
</script> | </script> | ||||
<script type="text/x-red" data-template-name="AudioControlSGTL5000"> | <script type="text/x-red" data-template-name="AudioControlSGTL5000"> |