Browse Source

Fix the DC offset computation. The previous computation would occassionally get stuck with an incorrect offset.

dds
Konstantin Lopyrev 8 years ago
parent
commit
dde07982b0
2 changed files with 18 additions and 9 deletions
  1. +16
    -8
      input_adc.cpp
  2. +2
    -1
      input_adc.h

+ 16
- 8
input_adc.cpp View File

@@ -31,7 +31,8 @@
DMAMEM static uint16_t analog_rx_buffer[AUDIO_BLOCK_SAMPLES];
audio_block_t * AudioInputAnalog::block_left = NULL;
uint16_t AudioInputAnalog::block_offset = 0;
uint16_t AudioInputAnalog::dc_average = 0;
int32_t AudioInputAnalog::dc_average_hist[16];
int32_t AudioInputAnalog::current_dc_average_index = 0;
bool AudioInputAnalog::update_responsibility = false;
DMAChannel AudioInputAnalog::dma(false);

@@ -50,7 +51,9 @@ void AudioInputAnalog::init(uint8_t pin)
for (i=0; i < 1024; i++) {
sum += analogRead(pin);
}
dc_average = sum >> 10;
for (i = 0; i < 16; i++) {
dc_average_hist[i] = sum >> 10;
}

// set the programmable delay block to trigger the ADC at 44.1 kHz
#if defined(KINETISK)
@@ -133,7 +136,7 @@ void AudioInputAnalog::isr(void)
void AudioInputAnalog::update(void)
{
audio_block_t *new_left=NULL, *out_left=NULL;
unsigned int dc, offset;
uint32_t i, dc, offset;
int32_t tmp;
int16_t s, *p, *end;

@@ -178,18 +181,23 @@ void AudioInputAnalog::update(void)
block_offset = 0;
__enable_irq();

// find and subtract DC offset....
// TODO: this may not be correct, needs testing with more types of signals
dc = dc_average;
// Find and subtract DC offset... We use an average of the
// last 16 * AUDIO_BLOCK_SAMPLES samples.
dc = 0;
for (i = 0; i < 16; i++) {
dc += dc_average_hist[i];
}
dc /= 16 * AUDIO_BLOCK_SAMPLES;
dc_average_hist[current_dc_average_index] = 0;
p = out_left->data;
end = p + AUDIO_BLOCK_SAMPLES;
do {
dc_average_hist[current_dc_average_index] += (uint16_t)(*p);
tmp = (uint16_t)(*p) - (int32_t)dc;
s = signed_saturate_rshift(tmp, 16, 0);
*p++ = s;
dc += s / 12000; // slow response, remove DC component
} while (p < end);
dc_average = dc;
current_dc_average_index = (current_dc_average_index + 1) % 16;

// then transmit the AC data
transmit(out_left);

+ 2
- 1
input_adc.h View File

@@ -41,7 +41,8 @@ public:
private:
static audio_block_t *block_left;
static uint16_t block_offset;
static uint16_t dc_average;
static int32_t dc_average_hist[16];
static int32_t current_dc_average_index;
static bool update_responsibility;
static DMAChannel dma;
static void isr(void);

Loading…
Cancel
Save