Conflicts: Audio.cpp Audio.hdds
release(block); | release(block); | ||||
} | } | ||||
void AudioFilterBiquad::updateCoefs(int *source, bool doReset) | |||||
{ | |||||
int32_t *dest=(int32_t *)definition; | |||||
int32_t *src=(int32_t *)source; | |||||
__disable_irq(); | |||||
for(uint8_t index=0;index<5;index++) | |||||
{ | |||||
*dest++=*src++; | |||||
} | |||||
if(doReset) | |||||
{ | |||||
*dest++=0; | |||||
*dest++=0; | |||||
*dest++=0; | |||||
} | |||||
__enable_irq(); | |||||
} | |||||
void AudioFilterBiquad::updateCoefs(int *source) | |||||
{ | |||||
updateCoefs(source,false); | |||||
} | |||||
/******************************************************************/ | /******************************************************************/ | ||||
#define DAP_BASS_ENHANCE_CTRL 0x0106 | #define DAP_BASS_ENHANCE_CTRL 0x0106 | ||||
#define DAP_AUDIO_EQ 0x0108 | #define DAP_AUDIO_EQ 0x0108 | ||||
#define DAP_SGTL_SURROUND 0x010A | #define DAP_SGTL_SURROUND 0x010A | ||||
#define DAP_FILTER_COEF_ACCES 0x010C | |||||
#define DAP_FILTER_COEF_ACCESS 0x010C | |||||
#define DAP_COEF_WR_B0_MSB 0x010E | #define DAP_COEF_WR_B0_MSB 0x010E | ||||
#define DAP_COEF_WR_B0_LSB 0x0110 | #define DAP_COEF_WR_B0_LSB 0x0110 | ||||
#define DAP_AUDIO_EQ_BASS_BAND0 0x0116 // 115 Hz | #define DAP_AUDIO_EQ_BASS_BAND0 0x0116 // 115 Hz | ||||
write(CHIP_ANA_POWER, 0x4060); // VDDD is externally driven with 1.8V | write(CHIP_ANA_POWER, 0x4060); // VDDD is externally driven with 1.8V | ||||
write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V | write(CHIP_LINREG_CTRL, 0x006C); // VDDA & VDDIO both over 3.1V | ||||
write(CHIP_REF_CTRL, 0x01F1); // VAG=1.575 slow ramp, normal bias current | write(CHIP_REF_CTRL, 0x01F1); // VAG=1.575 slow ramp, normal bias current | ||||
write(CHIP_LINE_OUT_CTRL, 0x0322); | |||||
write(CHIP_LINE_OUT_CTRL, 0x0322); // LO_VAGCNTRL=1.65V, OUT_CURRENT=0.36mA | |||||
write(CHIP_SHORT_CTRL, 0x4446); // allow up to 125mA | write(CHIP_SHORT_CTRL, 0x4446); // allow up to 125mA | ||||
write(CHIP_ANA_CTRL, 0x0137); // enable zero cross detectors | write(CHIP_ANA_CTRL, 0x0137); // enable zero cross detectors | ||||
write(CHIP_ANA_POWER, 0x40FF); // power up: lineout, hp, adc, dac | write(CHIP_ANA_POWER, 0x40FF); // power up: lineout, hp, adc, dac | ||||
write(CHIP_DIG_POWER, 0x0073); // power up all digital stuff | write(CHIP_DIG_POWER, 0x0073); // power up all digital stuff | ||||
delay(400); | delay(400); | ||||
// 40*log((1.575)/(1.65)) + 15 = 13.1391993746043 but it seems wrong, 5 is better... | |||||
write(CHIP_LINE_OUT_VOL, 0x0505); // TODO: correct value for 3.3V | write(CHIP_LINE_OUT_VOL, 0x0505); // TODO: correct value for 3.3V | ||||
write(CHIP_CLK_CTRL, 0x0004); // 44.1 kHz, 256*Fs | write(CHIP_CLK_CTRL, 0x0004); // 44.1 kHz, 256*Fs | ||||
write(CHIP_I2S_CTRL, 0x0130); // SCLK=32*Fs, 16bit, I2S format | write(CHIP_I2S_CTRL, 0x0130); // SCLK=32*Fs, 16bit, I2S format | ||||
return false; | 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) | bool AudioControlSGTL5000::volumeInteger(unsigned int n) | ||||
{ | { | ||||
if (n == 0) { | if (n == 0) { | ||||
return write(CHIP_ANA_HP_CTRL, n); // set volume | return write(CHIP_ANA_HP_CTRL, n); // set volume | ||||
} | } | ||||
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); | |||||
} | |||||
// CHIP_LINE_OUT_VOL | |||||
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) // 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); | |||||
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); | |||||
} | |||||
// DAP_CONTROL | |||||
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); // I2S_IN if n==0 else DAP | |||||
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); | |||||
} | |||||
// DAP_PEQ | |||||
unsigned short AudioControlSGTL5000::dap_peqs(uint8_t n) // valid to n&7, 0 thru 7 filters enabled. | |||||
{ | |||||
return modify(DAP_PEQ,(n&7),7); | |||||
} | |||||
// 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) | |||||
{ | |||||
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); | |||||
} | |||||
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(2); | |||||
{ | |||||
dap_audio_eq_band(0,bass); | |||||
dap_audio_eq_band(4,treble); | |||||
} | |||||
// SGTL5000 PEQ Coefficient loader | |||||
void AudioControlSGTL5000::load_peq(uint8_t filterNum, int *filterParameters) | |||||
{ | |||||
// 1111 11111111 11111111 | |||||
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); // seems necessary, didn't work for 1ms. | |||||
modify(DAP_FILTER_COEF_ACCESS,(uint16_t)filterNum,15); | |||||
} | |||||
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; | |||||
} | |||||
// 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) | |||||
{ | |||||
// I used resources like http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt | |||||
// to make this routine, I tested most of the filter types and they worked. Such filters have limits and | |||||
// before calling this routine with varying values the end user should check that those values are limited | |||||
// to valid results. | |||||
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*sinh((log(2)/2)*BW*W0/sinw); | |||||
//float beta = sqrt(2*A); | |||||
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; // =(1-COS($H$2))/2 | |||||
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; // once here instead of five times there... | |||||
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); | |||||
} |
#define AudioNoInterrupts() (NVIC_DISABLE_IRQ(IRQ_SOFTWARE)) | #define AudioNoInterrupts() (NVIC_DISABLE_IRQ(IRQ_SOFTWARE)) | ||||
#define AudioInterrupts() (NVIC_ENABLE_IRQ(IRQ_SOFTWARE)) | #define AudioInterrupts() (NVIC_ENABLE_IRQ(IRQ_SOFTWARE)) | ||||
// waveforms.c | // waveforms.c | ||||
extern "C" { | extern "C" { | ||||
extern const int16_t AudioWaveformSine[257]; | extern const int16_t AudioWaveformSine[257]; | ||||
AudioFilterBiquad(int *parameters) | AudioFilterBiquad(int *parameters) | ||||
: AudioStream(1, inputQueueArray), definition(parameters) { } | : AudioStream(1, inputQueueArray), definition(parameters) { } | ||||
virtual void update(void); | virtual void update(void); | ||||
void updateCoefs(int *source, bool doReset); | |||||
void updateCoefs(int *source); | |||||
private: | private: | ||||
int *definition; | int *definition; | ||||
audio_block_t *inputQueueArray[1]; | audio_block_t *inputQueueArray[1]; | ||||
} | } | ||||
//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)); } | ||||
bool volume(float left, float right); | |||||
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 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); | |||||
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 char calcVol(float n, unsigned char range); | |||||
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); | |||||
}; | }; | ||||
//For Filter Type: 0 = LPF, 1 = HPF, 2 = BPF, 3 = NOTCH, 4 = PeakingEQ, 5 = LowShelf, 6 = HighShelf | |||||
#define FILTER_LOPASS 0 | |||||
#define FILTER_HIPASS 1 | |||||
#define FILTER_BANDPASS 2 | |||||
#define FILTER_NOTCH 3 | |||||
#define FILTER_PARAEQ 4 | |||||
#define FILTER_LOSHELF 5 | |||||
#define FILTER_HISHELF 6 | |||||
void calcBiquad(uint8_t filtertype, float fC, float dB_Gain, float Q, uint32_t quantization_unit, uint32_t fS, int *coef); | |||||
// A u d i o E f f e c t C h o r u s | // A u d i o E f f e c t C h o r u s | ||||
// Written by Pete (El Supremo) Jan 2014 | // Written by Pete (El Supremo) Jan 2014 | ||||
#define DELAY_PASSTHRU -1 | |||||
class AudioEffectChorus : | class AudioEffectChorus : | ||||
public AudioStream | public AudioStream | ||||
// Tone example using AudioFilterBiquad object and calcBiquad filter calculator routine. | |||||
#include <Audio.h> | |||||
#include <Wire.h> | |||||
#include <SD.h> | |||||
const int myInput = AUDIO_INPUT_LINEIN; | |||||
// const int myInput = AUDIO_INPUT_MIC; | |||||
int BassFilter_L[]={0,0,0,0,0,0,0,0}; | |||||
int BassFilter_R[]={0,0,0,0,0,0,0,0}; | |||||
int TrebFilter_L[]={0,0,0,0,0,0,0,0}; | |||||
int TrebFilter_R[]={0,0,0,0,0,0,0,0}; | |||||
int updateFilter[5]; | |||||
AudioInputI2S audioInput; // audio shield: mic or line-in | |||||
AudioFilterBiquad filterBass_L(BassFilter_L); | |||||
AudioFilterBiquad filterBass_R(BassFilter_R); | |||||
AudioFilterBiquad filterTreb_L(TrebFilter_L); | |||||
AudioFilterBiquad filterTreb_R(TrebFilter_R); | |||||
AudioOutputI2S audioOutput; // audio shield: headphones & line-out | |||||
// Create Audio connections between the components | |||||
// | |||||
AudioConnection c1(audioInput,0,filterBass_L,0); | |||||
AudioConnection c2(audioInput,1,filterBass_R,0); | |||||
AudioConnection c3(filterBass_L,0,filterTreb_L,0); | |||||
AudioConnection c4(filterBass_R,0,filterTreb_R,0); | |||||
AudioConnection c5(filterTreb_L,0,audioOutput,0); | |||||
AudioConnection c6(filterTreb_R,0,audioOutput,1); | |||||
// 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(12); | |||||
// Enable the audio shield, select the input and set the output volume. | |||||
audioShield.enable(); | |||||
audioShield.inputSelect(myInput); | |||||
audioShield.volume(75); | |||||
audioShield.unmuteLineout(); | |||||
calcBiquad(FILTER_PARAEQ,110,0,0.2,2147483648,44100,updateFilter); | |||||
filterBass_L.updateCoefs(updateFilter); | |||||
filterBass_R.updateCoefs(updateFilter); | |||||
calcBiquad(FILTER_PARAEQ,4400,0,0.167,2147483648,44100,updateFilter); | |||||
filterTreb_L.updateCoefs(updateFilter); | |||||
filterTreb_R.updateCoefs(updateFilter); | |||||
} | |||||
elapsedMillis chgMsec=0; | |||||
float tone1=0; | |||||
void loop() { | |||||
// every 10 ms, check for adjustment the tone & vol | |||||
if (chgMsec > 10) { // more regular updates for actual changes seems better. | |||||
float tone2=analogRead(15); | |||||
tone2=floor(((tone2-512)/512)*70)/10; | |||||
if(tone2!=tone1) | |||||
{ | |||||
// calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*); | |||||
calcBiquad(FILTER_PARAEQ,110,-tone2,0.2,2147483648,44100,updateFilter); | |||||
filterBass_L.updateCoefs(updateFilter); | |||||
filterBass_R.updateCoefs(updateFilter); | |||||
calcBiquad(FILTER_PARAEQ,4400,tone2,0.167,2147483648,44100,updateFilter); | |||||
filterTreb_L.updateCoefs(updateFilter); | |||||
filterTreb_R.updateCoefs(updateFilter); | |||||
tone1=tone2; | |||||
} | |||||
chgMsec = 0; | |||||
} | |||||
} | |||||
// Tone example using SGTL5000 DAP PEQ filters and calcBiquad filter calculator routine. | |||||
#include <Audio.h> | |||||
#include <Wire.h> | |||||
#include <SD.h> | |||||
const int myInput = AUDIO_INPUT_LINEIN; | |||||
// const int myInput = AUDIO_INPUT_MIC; | |||||
int updateFilter[5]; | |||||
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, select the input and set the output volume. | |||||
audioShield.enable(); | |||||
audioShield.inputSelect(myInput); | |||||
audioShield.volume(75); | |||||
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); | |||||
calcBiquad(FILTER_PARAEQ,4400,0,0.167,524288,44100,updateFilter); | |||||
audioShield.load_peq(1,updateFilter); | |||||
} | |||||
elapsedMillis chgMsec=0; | |||||
float tone1=0; | |||||
void loop() { | |||||
// every 10 ms, check for adjustment the tone & vol | |||||
if (chgMsec > 10) { // more regular updates for actual changes seems better. | |||||
float tone2=analogRead(15); | |||||
tone2=floor(((tone2-512)/512)*70)/10; | |||||
if(tone2!=tone1) | |||||
{ | |||||
// calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*); | |||||
calcBiquad(FILTER_PARAEQ,110,-tone2,0.2,524288,44100,updateFilter); | |||||
audioShield.load_peq(0,updateFilter); | |||||
calcBiquad(FILTER_PARAEQ,4400,tone2,0.167,524288,44100,updateFilter); | |||||
audioShield.load_peq(1,updateFilter); | |||||
tone1=tone2; | |||||
} | |||||
chgMsec = 0; | |||||
} | |||||
} | |||||
// DAC balance example: Will influence both HP & LO outputs. | |||||
#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(); | |||||
} | |||||
elapsedMillis chgMsec=0; | |||||
float lastBal=1024; | |||||
void loop() { | |||||
// every 10 ms, check for adjustment the balance & vol | |||||
if (chgMsec > 10) { // more regular updates for actual changes seems better. | |||||
float bal1=analogRead(15); | |||||
bal1=((bal1-512)/512)*100; | |||||
bal1=(int)bal1; | |||||
if(lastBal!=bal1) | |||||
{ | |||||
if(bal1<0) | |||||
{ // leaning toward left... | |||||
audioShield.dac_vol(100,100+bal1); | |||||
} else if(bal1>0) { // to the right | |||||
audioShield.dac_vol(100-bal1,100); | |||||
} else { // middle | |||||
audioShield.dac_vol(100); | |||||
} | |||||
lastBal=bal1; | |||||
} | |||||
chgMsec = 0; | |||||
} | |||||
} | |||||
// HP balance example: Will influence only HP output. | |||||
#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 | |||||
// Just connecting in to out | |||||
AudioConnection c1(audioInput, 0, audioOutput, 0); // left connection | |||||
AudioConnection c2(audioInput, 1, audioOutput, 1); // right connection | |||||
// 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(60); | |||||
audioShield.unmuteLineout(); | |||||
} | |||||
elapsedMillis chgMsec=0; | |||||
float lastBal=1024; | |||||
float vol1=75; | |||||
void loop() { | |||||
// every 10 ms, check for adjustment the balance & vol | |||||
if (chgMsec > 10) { // more regular updates for actual changes seems better. | |||||
float bal1=analogRead(15); | |||||
bal1=((bal1-512)/512)*100; | |||||
bal1=(int)bal1; | |||||
if(lastBal!=bal1) | |||||
{ | |||||
if(bal1<0) | |||||
{ | |||||
audioShield.volume(vol1,(vol1/100)*(100+bal1)); | |||||
} else { | |||||
audioShield.volume((vol1/100)*(100-bal1),vol1); | |||||
} | |||||
lastBal=bal1; | |||||
} | |||||
chgMsec = 0; | |||||
} | |||||
} | |||||