소스 검색

Merge pull request #4 from robsoles/master

Some filter additions, some SGTL5000 additions
dds
Paul Stoffregen 10 년 전
부모
커밋
06555e188a
6개의 변경된 파일530개의 추가작업 그리고 18개의 파일을 삭제
  1. +232
    -2
      Audio.cpp
  2. +32
    -16
      Audio.h
  3. +78
    -0
      examples/CalcBiquadToneControl/CalcBiquadToneControl.ino
  4. +64
    -0
      examples/SGTL5000_Specific/CalcBiquadToneControlDAP/CalcBiquadToneControlDAP.ino
  5. +62
    -0
      examples/SGTL5000_Specific/balanceDAC/balanceDAC.ino
  6. +62
    -0
      examples/SGTL5000_Specific/balanceHP/balanceHP.ino

+ 232
- 2
Audio.cpp 파일 보기

@@ -2204,7 +2204,28 @@ void AudioFilterBiquad::update(void)
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);
}

/******************************************************************/

@@ -2962,7 +2983,7 @@ bool AudioControlWM8731master::enable(void)
#define DAP_BASS_ENHANCE_CTRL 0x0106
#define DAP_AUDIO_EQ 0x0108
#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_LSB 0x0110
#define DAP_AUDIO_EQ_BASS_BAND0 0x0116 // 115 Hz
@@ -3005,12 +3026,13 @@ bool AudioControlSGTL5000::enable(void)
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_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_ANA_CTRL, 0x0137); // enable zero cross detectors
write(CHIP_ANA_POWER, 0x40FF); // power up: lineout, hp, adc, dac
write(CHIP_DIG_POWER, 0x0073); // power up all digital stuff
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_CLK_CTRL, 0x0004); // 44.1 kHz, 256*Fs
write(CHIP_I2S_CTRL, 0x0130); // SCLK=32*Fs, 16bit, I2S format
@@ -3050,6 +3072,13 @@ bool AudioControlSGTL5000::write(unsigned int reg, unsigned int val)
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) {
@@ -3069,6 +3098,207 @@ bool AudioControlSGTL5000::volumeInteger(unsigned int n)
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);
}

+ 32
- 16
Audio.h 파일 보기

@@ -14,7 +14,6 @@
#define AudioNoInterrupts() (NVIC_DISABLE_IRQ(IRQ_SOFTWARE))
#define AudioInterrupts() (NVIC_ENABLE_IRQ(IRQ_SOFTWARE))


// waveforms.c
extern "C" {
extern const int16_t AudioWaveformSine[257];
@@ -377,6 +376,9 @@ public:
AudioFilterBiquad(int *parameters)
: AudioStream(1, inputQueueArray), definition(parameters) { }
virtual void update(void);
void updateCoefs(int *source, bool doReset);
void updateCoefs(int *source);
private:
int *definition;
audio_block_t *inputQueueArray[1];
@@ -527,29 +529,43 @@ public:
}
//bool inputLinein(void) { return 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:
bool muted;
bool volumeInteger(unsigned int n); // range: 0x00 to 0x80
uint16_t ana_ctrl;


unsigned char calcVol(float n, unsigned char range);

unsigned int read(unsigned int reg);
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);

+ 78
- 0
examples/CalcBiquadToneControl/CalcBiquadToneControl.ino 파일 보기

@@ -0,0 +1,78 @@
// 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;
}
}


+ 64
- 0
examples/SGTL5000_Specific/CalcBiquadToneControlDAP/CalcBiquadToneControlDAP.ino 파일 보기

@@ -0,0 +1,64 @@
// 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;
}
}


+ 62
- 0
examples/SGTL5000_Specific/balanceDAC/balanceDAC.ino 파일 보기

@@ -0,0 +1,62 @@
// 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;
}
}


+ 62
- 0
examples/SGTL5000_Specific/balanceHP/balanceHP.ino 파일 보기

@@ -0,0 +1,62 @@
// 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;
}
}


Loading…
취소
저장