Posts with «3-rd degree polynomial coefficient» label

TRUE ANALOG AUDIO VOLUME CONTROL (T.A.A.V.C.).

 

More:   Video1   and   Video2

Now my Arduino can precisely measure audio input (VU meter),   and obviously, next thing that comes to mind right after measurements, is regulation or control. There are many different ways how to electronically adjust audio volume or level of AC signal.  I’ll name a few:

  • Specifically design IC, Digital potentiometers.
  • Mechanical potentiometers, driven by servo / motors.
  • Vacuum tubes amplifiers in “variable-mu” configuration.
  • Resistive opto-isolators.

First category (#1) fits nicely for arduino project. But it’s not interesting to me. My apologies to someone, who was searching an example of interface between arduino and digital pot. Other people don’t tolerate semiconductors in audio path ( tube sound lovers ). Third option would make them happy, only (#3) requires high voltage and difficult to accomplish on low hobbyist budget, so I left it out of the scope. Mechanical pot (#2) would be good solution to satisfy Hi-Fi perfectionists and arduino fans. The same time response time of mechanical parts is too slow, verdict – discarded.  (#4) have been in use since 1960s, but would you like your lovely music to be adjusted by highly toxic CdSe / CdS ?  I don’t think so. Wiki says opto-isolators have low THD distortion level, less than 0.1%. Probably true, but apart from technical aspect, there is always psychological, poisonous CdSe affects my perception.

How about variable resistor in it’s simplest form – tungsten wire? Where you can get one? In the electrical bulb. Perfect material for audiophiles – where distortion could get into ? – It’s pure metal ! And here is my design of the “basic cell” – True Analog Audio Volume Control (T.A.A.V.C.)

As you can see, cell consists of 5 bulbs plus 1 resistor. All elements form 2 attenuation stages, basically – voltage dividers with variable resistors. Resistive values of bulbs proportional to temperature, which is easy to control passing DC current through. To make it work with the biggest possible dynamic range, middle bulb is also heated up by current flow from two differential control lines / phases.

 Hardware prototype / Proof of Concept.

Differential Power Amplifier (PA) IC LM4863  is used as DC current source for control lines. Circuitry powered from 5V regulated switching power supply (4A).  Bulbs – clear mini lights, 2.5V, approximately 200 mA. Cold state resistance about 1.2 – 1.5 Ohm, hot state resistance is rising up to 15 Ohm.  Volume regulator could be connected to any audio source with output impedance no more than 32 Ohm, for example, headphones output. For test I used second channel of the PA, that shown in “optional” box on the left side. Second channel is a “nice to have” feature  in stereo version of the project, when both channels would drive two separate TAAVC cells, so using it as a “buffer” amplifier may be not an option.

Results.

  Measured attenuation  range of the “basic cell” is  20 dB, or 10 x times.

 to be continue…

 Chart, PWM (Voltage) to Attenuation:

 Quite interesting, isn’t it? I was not expecting it’s to be linear, but changing direction surprised me. There is one things, which could explain such abnormality, is that when voltage on the control lines 1 and 2 ( LM4863 outputs ) is approaching power rails, output impedance of the power amplifier is increasing, and consequently, attenuation characteristics of the basic cell deteriorate. It means, that in order to keep attenuation curve gradually declining, more powerful PA necessary. For now, I limited PWM to 0 – 200 range.

I’m thinking, STA540  powered from +12V, and 5 V bulbs would make sense to try next time.  Probably, replacing middle bulb for less current hungry, will increase max attenuation per cell up to 30-35 dB.

 O’K, after I get this data, how could I “straighten it up” for practical use ?  Volume control device, could be linear or logarithmic, but chart doesn’t resemble nether of this. And this is exactly what I need Arduino for.

Linearization.

 If you, by chance, have read this page, than you know how to do this part. Polynomial approximation. Unfortunately,  2-nd degree polynomial I used last time is not enough for VERY non-linear curve like I have. So, I “upgraded” my calibration subroutine (method: LEAST SQUARES) up to 3-rd degree:

void calibrate()
{
 //Least squares 3-rd degree polynomial coefficient calculation
 float arr[10][5] ={{0},{0}}, err[10] = {0}, coeff[10] = {0};

 err[0] = 10;
 for(uint8_t i = 1; i < 7; i++)
 {
  err[i] = 0;
  for(uint8_t j = 0; j < 10; j++)
  {
   err[i] += pow(level_table[j], i);
  }
 }

 for(uint8_t i = 0; i < 4; i++)
 {
  for(uint8_t j = 0; j < 4; j++)
  {
   arr[i][j] = err[i+j];
  }
 }

 for(uint8_t i = 0; i < 4; i++)
 {
  arr[i][4] = 0;
  for(uint8_t j = 0; j < 10; j++)
  {
   if (i==0) arr[i][4] += calibration[j];
   else arr[i][4] += calibration[j] * pow(level_table[j], i);
  }
 }

 for(uint8_t k = 0; k < 4; k++)
 {
  for(uint8_t i = 0; i < 4; i++)
  {
   if ( i != k )
   {
    for(uint8_t j = (k + 1); j < 5; j++)
    {
     arr[i][j] -= ((arr[i][k] * arr[k][j]) / arr[k][k]);
    }
   }
  }
 }

 union split_float {
 uint16_t tegri[2];
 float loatf;
 } sf; 

 for(uint8_t i = 0; i < 4; i++)
 {
  coeff[i] = ( arr[i][4] / arr[i][i]);
  sf.loatf = coeff[i];
  store_entry(( 2 * i ), sf.tegri[0] );
  store_entry(( 1 + (2 * i)), sf.tegri[1] );
 }
}

Procedure takes 10 data samples as input, calculates 4 coefficients and stores them in EEPROM memory.

VU meter based on Arduino UNO ( in minimum configuration Arduino and DC offsetting circuit ) should be connected right to T.A.A.V.C. output. Everything works in automatic mode, with results printed on serial monitor for review. Stable AC input is necessary, which easy to get from any PC sound card based signal generator, recorded media file or lab sine-wave generator. Arduino also provides PWM for T.A.A.V.C       via pin D3 (TIMER2 OCR2B).

Link to download Arduino UNO sketch: T.A.A.V.C.

to be continue…audio compressor, .

Last part,

Dynamic Range Compressor.

There are two important parameters defined in the beginning of the sketch:

#define          CMP_THRE                     -10             // Compression Threshold 
#define          CMP_RATE                        4             // Compression Ratio 4 : 1

Threshold and Ratio. I’m not into explaining all bunch of the details about compressors or what for do you need one, rather forward you to this link.  I only want to say, that I didn’t find any evidence that someone ever used electrical bulbs as compressors “engine”. So, this is my idea, and my implementation.

Technical specification of this design is quite modest, having close to 20 dB maximum attenuation and setting ratio to 2:1, threshold couldn’t be set lower than -40 dB. Good news, that for practical use in home environment it’s  really unlikely, that you ‘d need more. It’s also should be enough to solve a problem with annoying TV or Radio commercial / advertisement.

Compare to VU Meter project, I’ve made a few “relaxing” changes to the code, as it appears there are no strict industry standard on Dynamic Range Regulation. I reduce sampling rate down to 10 kHz,  and  split Low Pass Filtering in two sections. One is the same, as in VU Meter, inside sampling interruption subroutine, only with lower time constants. First LPF section is responsible for “shaping” attack and decay timing. Using quite inertial electrical bulbs in the project, reduce importance of this timing. Here attack and release mostly defined  by thermal responsiveness of the bulbs, which isn’t very high. Decreasing software LPF time constants helps to improve sensitivity. Other LPF section included inside LCD drawing function, works to overcome display slowness, suppressing LCD flickering. Other changes from simple VU Meter, is that finally I “scaled” everything correctly,  and “0″ db corresponds exactly to 1.228 V RMS at the input. Threshold level -10 expressed in dB as well. You may see threshold “mark” above the log scale. Indicator “needle” just below it, small 5×2 pixels only, but you can make it bigger if you wish.

I already described calibration procedure, to do it right, you need to connect arduino to output of the TAAVC cell.  Polynomial coefficients and minimum / maximum constants stored in EEPROM, so you don’t have to do this procedure each time after power cycling.  In normal mode arduino getting input measurements from the cell input:

Finished.  I’ll do a video “on demand” -);  If I had time…

Arduino UNO sketch:  Audio Dynamic Range Compressor. (TAAVC part 3).