// AudioColorizer.
// Pros 2010
#define F_CPU 16000000UL
#define UART
#ifndef PRG_RDB
#define PRG_RDB(x) pgm_read_byte(x)
#endif
#ifndef P
#define P(s) ({static const char c[] __attribute__ ((progmem)) = s;c;})
#endif
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <util/delay.h>
#include "ffft.h" // Defs for using Fixed-point FFT module
#ifdef UART
#include "UART.c"
#endif
int16_t capture[FFT_N]; // Wave captureing buffer
complex_t bfly_buff[FFT_N]; // FFT buffer
uint16_t spectrum[FFT_N / 2]; // Spectrum output buffer
unsigned int channel[4];
unsigned int cnt, ch;
int sample, tmp;
int main(void)
{
int16_t *buffer;
#ifdef UART
char txt[32];
uint16_t m, n, uart_flag = 0;
#endif
ADCSRA = 0;
ADMUX = _BV(REFS0); // Ref = 5V; ADC0 = ingang
TCCR0 = _BV(WGM00) | _BV(COM01) | _BV(CS00) | _BV(CS01);
OCR0 = 128;
DDRB = _BV(PB0) | _BV(PB1) | _BV(PB3);
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
TCCR1B = _BV(CS10) | _BV(CS11);
OCR1A = 128;
OCR1B = 128;
DDRD = _BV(PD4) | _BV(PD5) | _BV(PD7);
TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS22);
OCR2 = 128;
TCNT0 = 0;
TCNT1 = 80;
TCNT2 = 160;
#ifdef UART
uart_init();
sei();
#endif
while (1) {
PORTB |= _BV(PB0);
buffer = capture;
for (cnt = 0; cnt < FFT_N; cnt++) {
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | _BV(ADPS2) | _BV(ADPS1);
while (bit_is_clear(ADCSRA, ADIF)); // Sampelen
*buffer = ADC - 32768;
buffer++;
}
ADCSRA = 0;
PORTB |= _BV(PB1);
fft_input(capture, bfly_buff); // Bewerken
fft_execute(bfly_buff);
fft_output(bfly_buff, spectrum);
PORTB &= ~(_BV(PB0));
sample = spectrum[2];
if (spectrum[3] > sample) { // Voor elke groep
sample = spectrum[3]; // de hoogste waarde opzoeken
}
channel[0] = sample;
sample = spectrum[4];
for (n = 5; n < 8; n++) {
if (spectrum[n] > sample) {
sample = spectrum[n];
}
}
channel[1] = sample;
sample = spectrum[8];
for (n = 9; n < 16; n++) {
if (spectrum[n] > sample) {
sample = spectrum[n];
}
}
channel[2] = sample;
sample = spectrum[17];
for (n = 18; n < 51; n++) {
if (spectrum[n] > sample) {
sample = spectrum[n];
}
}
channel[3] = sample;
#ifdef UART
uart_flag = 0;
if (uart_linecomplete != 0) { // RS232-input?
if (strncmp(uart_outbuf, "Who", 3) == 0) { // Wie heb ik aan de lijn?
uart_sendstr_P(" AudioColorizer\n");
} else {
switch (uart_outbuf[0]) {
case 'w': // w: show waveform
for (n = 0; n < FFT_N; n++) {
sample = capture[n];
sample = (sample + 32768) / 10;
for (m = 0; m < sample; m++) {
uart_sendchar('*');
}
uart_sendchar('\n');
}
break;
case 's': // s: show spectrum
uart_flag = 1;
for (n = 2; n < FFT_N / 2; n++) {
sprintf(txt, "%4u ", n);
uart_sendstr(txt);
for (m = 0; m < spectrum[n]; m++) {
uart_sendchar('*');
}
uart_sendchar('\n');
}
for (n = 0; n < 4; n++) {
sprintf(txt, "Ch[%u] = ", n);
uart_sendstr(txt);
for (m = 0; m < channel[n]; m++) {
uart_sendchar('*');
}
uart_sendchar('\n');
}
uart_sendchar('\n');
break;
default: // Unknown command
uart_sendchar('?');
break;
}
uart_sendchar('\n');
}
uart_linecomplete = 0;
}
#endif
sample = channel[0];
ch = 0;
for (cnt = 1; cnt < 4; cnt++) { // channel met de hoogste waarde zoeken
if (channel[cnt] > sample) {
sample = channel[cnt];
ch = cnt;
}
}
channel[ch] = 250; // Die zetten we op maximum
sample = channel[0];
ch = 0;
for (cnt = 1; cnt < 4; cnt++) { // channel met de laagste waarde zoeken
if (channel[cnt] < sample) {
sample = channel[cnt];
ch = cnt;
}
}
channel[ch] = 1; // Die zetten we op minimum
if (channel[0] < 20) {
channel[0] = 1;
} else if (channel[0] > 150) {
channel[0] = 253;
}
if (channel[1] < 20) {
channel[1] = 1;
} else if (channel[1] > 150) {
channel[1] = 253;
}
if (channel[2] < 20) {
channel[2] = 1;
} else if (channel[2] > 150) {
channel[2] = 253;
}
if (channel[3] < 20) {
channel[3] = 1;
} else if (channel[3] > 150) {
channel[3] = 253;
}
channel[0] /= 4; // Van de nieuwe waarde nemen we 1/4
channel[0] += OCR0 * 3; // Van de oude waarde 3/4
OCR0 = channel[0] / 4; // Uitmiddelen
channel[1] /= 4;
channel[1] += OCR1A * 3;
OCR1A = channel[1] / 4;
channel[2] /= 4;
channel[2] += OCR1B * 3;
OCR1B = channel[2] / 4;
channel[3] /= 4;
channel[3] += OCR2 * 3;
OCR2 = channel[3] / 4;
#ifdef UART
if (uart_flag != 0) {
sprintf(txt, "OCR0 = %3u\n", OCR0);
uart_sendstr(txt);
sprintf(txt, "OCR1A = %3u\n", OCR1A);
uart_sendstr(txt);
sprintf(txt, "OCR1B = %3u\n", OCR1B);
uart_sendstr(txt);
sprintf(txt, "OCR2 = %3u\n", OCR2);
uart_sendstr(txt);
uart_flag = 0;
}
#endif
PORTB &= ~(_BV(PB1));
}
}