welcome: please sign in
location: attachment:AuidoCodecEx.h of AudioCodecShield

Attachment 'AuidoCodecEx.h'

Download

   1 // AudioCodec.h
   2 // guest openmusiclabs 7.28.11
   3 // this is the library file for ARDUINO -> there is a different
   4 // file for Maple, make sure you are using the right one.
   5 // place this file in the libraries file of your Arduino sketches folder
   6 // e.g. C:\Documents and Settings\user\My Documents\Arduino\libraries\
   7 // you may have to create the \libraries folder
   8 // modded 4.15.12
   9 // added better pot handling and more sample rates
  10 
  11 #ifndef AudioCodec_h // include guard
  12 #define AudioCodec_h
  13 
  14 #include "WProgram.h"
  15 #include <avr/pgmspace.h>
  16 #include "mult16x16.h"
  17 #include "mult16x8.h"
  18 #include "mult32x16.h"
  19 
  20 
  21 #ifndef SAMPLE_RATE
  22   #define SAMPLE_RATE 44
  23 #elif (SAMPLE_RATE == 88)||(SAMPLE_RATE == 44)||(SAMPLE_RATE == 22)||(SAMPLE_RATE == 8)||(SAMPLE_RATE == 2)
  24 #else
  25   #error SAMPLE_RATE value not defined
  26 #endif
  27 
  28 #ifndef ADCHPD
  29   #define ADCHPD 0
  30 #elif (ADCHPD == 0)||(ADCHPD == 1)
  31 #else
  32   #error ADCHPD value not defined
  33 #endif
  34 
  35 #ifndef ADCS
  36   #define ADCS 2
  37 #elif (ADCS >=0)&&(ADCS <= 4)
  38 #else
  39   #error ADCS value not defined
  40 #endif
  41 
  42 #ifndef HYST
  43   #define HYST 32
  44 #elif (HYST >= 0)&&(HYST <= 255)
  45 #else
  46   #error HYST value not defined
  47 #endif
  48 
  49 #ifndef LINVOL
  50   #define LINVOL 23
  51 #elif (LINVOL >= 0) && (LINVOL <= 0x1f)
  52 #else
  53   #error LINVOL value not defined
  54 #endif
  55 
  56 #ifndef RINVOL
  57   #define RINVOL 23
  58 #elif (RINVOL >= 0) && (RINVOL <= 0x1f)
  59 #else
  60   #error RINVOL value not defined
  61 #endif
  62 
  63 #ifndef LHPVOL
  64   #define LHPVOL 121
  65 #elif (LHPVOL == 0) || ((LHPVOL >= 0x30) && (LHPVOL <= 0x7f))
  66 #else
  67   #error LHPVOL value not defined
  68 #endif
  69 
  70 #ifndef RHPVOL
  71   #define RHPVOL 121
  72 #elif (RHPVOL == 0) || ((RHPVOL >= 0x30) && (RHPVOL <= 0x7f))
  73 #else
  74   #error RHPVOL value not defined
  75 #endif
  76 
  77 #ifndef MICBOOST
  78   #define MICBOOST 0
  79 #elif (MICBOOST == 0)||(MICBOOST == 1)
  80 #else
  81   #error MICBOOST value not defined
  82 #endif
  83 
  84 #ifndef MUTEMIC
  85   #define MUTEMIC 1
  86 #elif (MUTEMIC == 0)||(MUTEMIC == 1)
  87 #else
  88   #error MUTEMIC value not defined
  89 #endif
  90 
  91 #ifndef INSEL
  92   #define INSEL 0
  93 #elif (INSEL == 0)||(INSEL == 1)
  94 #else
  95   #error INSEL value not defined
  96 #endif
  97 
  98 #ifndef BYPASS
  99   #define BYPASS 0
 100 #elif (BYPASS == 0)||(BYPASS == 1)
 101 #else
 102   #error BYPASS value not defined
 103 #endif
 104 
 105 #ifndef DACSEL
 106   #define DACSEL 1
 107 #elif (DACSEL == 0)||(DACSEL == 1)
 108 #else
 109   #error DACSEL value not defined
 110 #endif
 111 
 112 #ifndef SIDETONE
 113   #define SIDETONE 0
 114 #elif (SIDETONE == 0)||(SIDETONE == 1)
 115 #else
 116   #error SIDETONE value not defined
 117 #endif
 118 
 119 #ifndef SIDEATT
 120   #define SIDEATT 0
 121 #elif (SIDEATT >= 0)&&(SIDEATT <= 3)
 122 #else
 123   #error SIDEATT value not defined
 124 #endif
 125 
 126 #ifndef OVERSAMPLE
 127   #define OVERSAMPLE 64
 128 #elif (OVERSAMPLE == 1)||(OVERSAMPLE == 2)||(OVERSAMPLE == 4)||(OVERSAMPLE == 8)||(OVERSAMPLE == 16)||(OVERSAMPLE == 32)||(OVERSAMPLE == 64)
 129 #else
 130   #error OVERSAMPLE value not defined
 131 #endif
 132 
 133 
 134 // setup variables for ADC
 135 #if ADCS == 0
 136   // do nothing
 137 #else
 138   unsigned char _t = OVERSAMPLE; // number of times to oversample
 139   unsigned char _n = 0x00; // we start with mod0
 140   unsigned int _modtemp = 0x0000;
 141 #endif
 142 
 143 
 144 static inline void AudioCodec_init(void) {
 145 
 146   // setup spi peripheral
 147   digitalWrite(10, LOW); // set ss pin to output low
 148   pinMode (10, OUTPUT);
 149   SPI.begin();
 150   SPI.setBitOrder(MSBFIRST);
 151   SPI.setClockDivider(SPI_CLOCK_DIV2);
 152   SPI.setDataMode(SPI_MODE0);
 153   
 154   // setup i2c pins and configure codec
 155   Wire.begin();
 156   Wire.beginTransmission(0x1a);
 157   Wire.send(0x0c); // power reduction register
 158   Wire.send(0x00); // turn everything on
 159   Wire.endTransmission();
 160   
 161   Wire.beginTransmission(0x1a);
 162   Wire.send(0x0e); // digital data format
 163   Wire.send(0x03); // 16b SPI mode
 164   Wire.endTransmission();
 165   
 166   Wire.beginTransmission(0x1a);
 167   Wire.send(0x00); // left in setup register
 168   Wire.send(LINVOL);
 169   Wire.endTransmission();
 170   
 171   Wire.beginTransmission(0x1a);
 172   Wire.send(0x02); // right in setup register
 173   Wire.send(RINVOL);
 174   Wire.endTransmission();
 175   
 176   Wire.beginTransmission(0x1a);
 177   Wire.send(0x04); // left headphone out register
 178   Wire.send(LHPVOL);
 179   Wire.endTransmission();
 180   
 181   Wire.beginTransmission(0x1a);
 182   Wire.send(0x06); // right headphone out register
 183   Wire.send(RHPVOL);
 184   Wire.endTransmission();
 185   
 186   Wire.beginTransmission(0x1a);
 187   Wire.send(0x0a); // digital audio path configuration
 188   Wire.send(ADCHPD);
 189   Wire.endTransmission();
 190   
 191   Wire.beginTransmission(0x1a);
 192   Wire.send(0x08); // analog audio pathway configuration
 193   Wire.send((SIDEATT << 6)|(SIDETONE << 5)|(DACSEL << 4)|(BYPASS << 3)|(INSEL << 2)|(MUTEMIC << 1)|(MICBOOST << 0));
 194   Wire.endTransmission();
 195   
 196   Wire.beginTransmission(0x1a);
 197   Wire.send(0x10); // clock configuration
 198   #if SAMPLE_RATE == 88
 199     Wire.send(0xbc);
 200   #elif SAMPLE_RATE == 44
 201     Wire.send(0xa0);
 202   #elif SAMPLE_RATE == 22
 203     Wire.send(0xe0);
 204   #elif SAMPLE_RATE == 8
 205     Wire.send(0xac);
 206   #elif SAMPLE_RATE == 2
 207     Wire.send(0xce);
 208   #endif
 209   Wire.endTransmission();
 210 
 211   Wire.beginTransmission(0x1a);
 212   Wire.send(0x12); // codec enable
 213   Wire.send(0x01);
 214   Wire.endTransmission();
 215   
 216   // setup ADCs
 217   #if ADCS == 0
 218     DIDR0 = (1 << ADC1D)|(1 << ADC0D); // turn off digital inputs for ADC0 and ADC1
 219   #elif (ADCS == 1) || (ADCS == 2)
 220     ADMUX = 0x40; // start with ADC0 - internal VCC for Vref
 221     ADCSRA = 0xc7; // ADC enable, single sample, ck/128
 222     ADCSRB = 0x00; // just in case
 223     DIDR0 = (1 << ADC1D)|(1 << ADC0D); // turn off digital inputs for ADC0 and ADC1
 224   #elif (ADCS == 3)
 225     ADMUX = 0x40; // start with ADC0 - internal VCC for Vref
 226     ADCSRA = 0xc7; // ADC enable, single sample, ck/128
 227     ADCSRB = 0x00; // just in case
 228     DIDR0 = (1<<ADC2D)|(1 << ADC1D)|(1 << ADC0D); // turn off digital inputs for ADC0:2
 229   #elif (ADCS == 4)
 230     ADMUX = 0x40; // start with ADC0 - internal VCC for Vref
 231     ADCSRA = 0xc7; // ADC enable, single sample, ck/128
 232     ADCSRB = 0x00; // just in case
 233     DIDR0 = (1<<ADC3D)|(1<<ADC2D)|(1 << ADC1D)|(1 << ADC0D); // turn off digital inputs for ADC0:3
 234   #endif
 235   
 236   // setup timer1 for codec clock division
 237   TCCR1A = 0x00; // set to CTC mode
 238   TCCR1B = 0x0f; // set to CTC mode, external clock
 239   TCCR1C = 0x00; // not used
 240   TCNT1H = 0x00; // clear the counter
 241   TCNT1H = 0x00;
 242   #if SAMPLE_RATE == 88
 243     OCR1AH = 0x00; // set the counter top
 244     OCR1AL = 0x3f;
 245   #elif (SAMPLE_RATE == 44) || (SAMPLE_RATE == 22)
 246     OCR1AH = 0x00; // set the counter top
 247     OCR1AL = 0x7f;
 248   #elif SAMPLE_RATE == 8
 249     OCR1AH = 0x02; // set the counter top
 250     OCR1AL = 0xbf;
 251   #elif SAMPLE_RATE == 2
 252     OCR1AH = 0x04; // set the counter top
 253     OCR1AL = 0x7f;
 254   #endif
 255   TIMSK1 = 0x02; // turn on compare match interrupt
 256   
 257   // turn off all enabled interrupts (delay and wire)
 258   TIMSK0 = 0x00;
 259   TWCR = 0x00;
 260 
 261   sei(); // turn on interrupts
 262 }
 263 
 264 
 265 // adc sample routine
 266 // this creates relatively low noise 16b values from adc samples
 267 #if ADCS == 0
 268   static inline void AudioCodec_ADC() {
 269     // do nothing
 270   }
 271 #elif ADCS == 1
 272   static inline void AudioCodec_ADC(unsigned int* _mod0value) {
 273     if (ADCSRA & (1 << ADIF)) { // check if sample ready
 274       _modtemp += ADCL; // fetch ADCL first to freeze sample
 275       _modtemp += (ADCH << 8); // add to temp register
 276       ADCSRA = 0xd7; // reset the interrupt flag
 277       --_t; // decrement sample counter
 278       if (_t == 0) { // check if enough samples have been averaged
 279         // shift value to make a 16b integer
 280         unsigned char x = 0;
 281         for (unsigned char y = OVERSAMPLE; y > 1; y >>= 1) {
 282           x += 1;
 283         }
 284         _modtemp <<= 6 - x;
 285         // add in hysteresis to remove jitter
 286         if (((_modtemp - *_mod0value) < HYST) || ((*_mod0value - _modtemp) < HYST)) {
 287         }
 288         else {
 289           *_mod0value = _modtemp; // move temp value
 290 	}
 291         _modtemp = 0x0000; // reset temp value
 292         _t = OVERSAMPLE; // reset counter
 293       }
 294     }
 295   }
 296 #elif ADCS == 2
 297   static inline void AudioCodec_ADC(unsigned int* _mod0value, unsigned int* _mod1value) {
 298     if (ADCSRA & (1 << ADIF)) { // check if sample ready
 299       _modtemp += ADCL; // fetch ADCL first to freeze sample
 300       _modtemp += (ADCH << 8); // add to temp register
 301       --_t; // decrement sample counter
 302       if (_t == 0) { // check if enough samples have been averaged
 303         // shift value to make a 16b integer
 304         unsigned char x = 0;
 305         for (unsigned char y = OVERSAMPLE; y > 1; y >>= 1) {
 306           x += 1;
 307         }
 308         _modtemp <<= 6 - x;
 309 	if (_n == 0) { // check if just finished with mod0
 310 	  ADMUX = 0x41; // change mux to mod1
 311           _n = 1; // index counter to mod1      
 312           // add in hysteresis to remove jitter
 313           if (((_modtemp - *_mod0value) < HYST) || ((*_mod0value - _modtemp) < HYST)) {
 314           }
 315           else {
 316             *_mod0value = _modtemp; // move temp value
 317 	  }
 318         }
 319         else { // just finished with mod1
 320 	  ADMUX = 0x40; // change mux to mod0
 321           _n = 0; // set counter to mod0      
 322           // add in hysteresis to remove jitter
 323           if (((_modtemp - *_mod1value) < HYST) || ((*_mod1value - _modtemp) < HYST)) {
 324           }
 325           else {
 326             *_mod1value = _modtemp; // move temp value
 327 	  }
 328         }
 329         _modtemp = 0x0000; // reset temp value
 330         _t = OVERSAMPLE; // reset counter
 331       }
 332       ADCSRA = 0xd7; // reset the interrupt flag and start next conversion
 333     }
 334   }
 335 #elif ADCS == 3
 336   static inline void AudioCodec_ADC(unsigned int* _mod0value, unsigned int* _mod1value, unsigned int* _mod2value) {
 337     if (ADCSRA & (1 << ADIF)) { // check if sample ready
 338       _modtemp += ADCL; // fetch ADCL first to freeze sample
 339       _modtemp += (ADCH << 8); // add to temp register
 340       --_t; // decrement sample counter
 341       if (_t == 0) { // check if enough samples have been averaged
 342         // shift value to make a 16b integer
 343         unsigned char x = 0;
 344         for (unsigned char y = OVERSAMPLE; y > 1; y >>= 1) {
 345           x += 1;
 346         }
 347         _modtemp <<= 6 - x;
 348 	if (_n == 0) { // check if just finished with mod0
 349 	  ADMUX = 0x41; // change mux to mod1
 350           _n = 1; // index counter to mod1      
 351           // add in hysteresis to remove jitter
 352           if (((_modtemp - *_mod0value) < HYST) || ((*_mod0value - _modtemp) < HYST)) {
 353           }
 354           else {
 355             *_mod0value = _modtemp; // move temp value
 356 	  }
 357         }
 358         else if (_n == 1){ // just finished with mod1
 359 	  ADMUX = 0x42; // change mux to mod2
 360           _n = 2; // set counter to mod2      
 361           // add in hysteresis to remove jitter
 362           if (((_modtemp - *_mod1value) < HYST) || ((*_mod1value - _modtemp) < HYST)) {
 363           }
 364           else {
 365             *_mod1value = _modtemp; // move temp value
 366 	  }
 367         }
 368         else { // just finished with mod2
 369 	  ADMUX = 0x40; // change mux to mod0
 370           _n = 0; // set counter to mod0 
 371           // add in hysteresis to remove jitter
 372           if (((_modtemp - *_mod2value) < HYST) || ((*_mod2value - _modtemp) < HYST)) {
 373           }
 374           else {
 375             *_mod2value = _modtemp; // move temp value
 376 	  }
 377         }
 378         _modtemp = 0x0000; // reset temp value
 379         _t = OVERSAMPLE; // reset counter
 380       }
 381       ADCSRA = 0xd7; // reset the interrupt flag and start next conversion
 382     }
 383   }
 384 #elif ADCS == 4
 385   static inline void AudioCodec_ADC(unsigned int* _mod0value, unsigned int* _mod1value, unsigned int* _mod2value, unsigned int* _mod3value) {
 386     if (ADCSRA & (1 << ADIF)) { // check if sample ready
 387       _modtemp += ADCL; // fetch ADCL first to freeze sample
 388       _modtemp += (ADCH << 8); // add to temp register
 389       --_t; // decrement sample counter
 390       if (_t == 0) { // check if enough samples have been averaged
 391         // shift value to make a 16b integer
 392         unsigned char x = 0;
 393         for (unsigned char y = OVERSAMPLE; y > 1; y >>= 1) {
 394           x += 1;
 395         }
 396         _modtemp <<= 6 - x;
 397 	if (_n == 0) { // check if just finished with mod0
 398 	  ADMUX = 0x41; // change mux to mod1
 399           _n = 1; // index counter to mod1      
 400           // add in hysteresis to remove jitter
 401           if (((_modtemp - *_mod0value) < HYST) || ((*_mod0value - _modtemp) < HYST)) {
 402           }
 403           else {
 404             *_mod0value = _modtemp; // move temp value
 405 	  }
 406         }
 407         else if (_n == 1){ // just finished with mod1
 408 	  ADMUX = 0x42; // change mux to mod2
 409           _n = 2; // set counter to mod2      
 410           // add in hysteresis to remove jitter
 411           if (((_modtemp - *_mod1value) < HYST) || ((*_mod1value - _modtemp) < HYST)) {
 412           }
 413           else {
 414             *_mod1value = _modtemp; // move temp value
 415 	  }
 416         }
 417         else if (_n == 2) { // just finished with mod2
 418 	  ADMUX = 0x43; // change mux to mod3
 419           _n = 3; // set counter to mod3
 420           // add in hysteresis to remove jitter
 421           if (((_modtemp - *_mod2value) < HYST) || ((*_mod2value - _modtemp) < HYST)) {
 422           }
 423           else {
 424             *_mod2value = _modtemp; // move temp value
 425 	  }
 426         }
 427         else { // just finished with mod3
 428 	  ADMUX = 0x40; // change mux to mod0
 429           _n = 0; // set counter to mod0 
 430           // add in hysteresis to remove jitter
 431           if (((_modtemp - *_mod3value) < HYST) || ((*_mod3value - _modtemp) < HYST)) {
 432           }
 433           else {
 434             *_mod3value = _modtemp; // move temp value
 435 	  }
 436         }
 437         _modtemp = 0x0000; // reset temp value
 438         _t = OVERSAMPLE; // reset counter
 439       }
 440       ADCSRA = 0xd7; // reset the interrupt flag and start next conversion
 441     }
 442   }
 443 #endif
 444 
 445 
 446 // codec data transfer function
 447 static inline void AudioCodec_data(int* _lin, int* _rin, int _lout, int _rout) {
 448 
 449   int _out_temp = _lout;
 450   PORTB |= (1<<PORTB2);  // toggle ss pina
 451   asm volatile ("out %0, %B1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
 452   PORTB &= ~(1<<PORTB2); // toggle ss pin
 453   while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
 454   }
 455   asm volatile ("out %0, %A1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
 456   asm volatile ("in r3, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
 457   _out_temp = _rout;
 458   while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
 459   }
 460   asm volatile ("out %0, %B1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
 461   asm volatile ("in r2, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
 462   asm volatile ("movw %0, r2" : "=r" (*_lin) : );
 463   while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
 464   }
 465   asm volatile ("out %0, %A1" : : "I" (_SFR_IO_ADDR(SPDR)), "r" (_out_temp) );
 466   asm volatile ("in r3, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
 467   while(!(SPSR & (1<<SPIF))){ // wait for data transfer to complete
 468   }
 469   asm volatile ("in r2, %0" : : "I" (_SFR_IO_ADDR(SPDR)) );
 470   asm volatile ("movw %0, r2" : "=r" (*_rin) : );
 471 }
 472 
 473 
 474 #endif // end include guard
 475 

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.