You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
3.2 KiB
152 lines
3.2 KiB
/* |
|
* vumeter.c: |
|
* Simple VU meter |
|
* |
|
* Heres the theory: |
|
* We will sample at 4000 samples/sec and put the data into a |
|
* low-pass filter with a depth of 1000 samples. This will give |
|
* us 1/4 a second of lag on the signal, but I think it might |
|
* produce a more pleasing output. |
|
* |
|
* The input of the microphone should be at mid-pont with no |
|
* sound input, but we might have to sample that too, to get |
|
* our reference zero... |
|
* |
|
* Copyright (c) 2013 Gordon Henderson |
|
*********************************************************************** |
|
*/ |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <sys/time.h> |
|
|
|
#include <wiringPi.h> |
|
#include <gertboard.h> |
|
|
|
#ifndef TRUE |
|
#define TRUE (1==1) |
|
#define FALSE (!TRUE) |
|
#endif |
|
|
|
#define B_SIZE 1000 |
|
#define S_SIZE 128 |
|
|
|
static int buffer [B_SIZE] ; |
|
static int bPtr = 0 ; |
|
|
|
/* |
|
* ledPercent: |
|
* Output the given value as a percentage on the LEDs |
|
********************************************************************************* |
|
*/ |
|
|
|
static void ledPercent (int percent) |
|
{ |
|
unsigned int output = 0 ; |
|
|
|
if (percent > 11) output |= 0x01 ; |
|
if (percent > 22) output |= 0x02 ; |
|
if (percent > 33) output |= 0x04 ; |
|
if (percent > 44) output |= 0x08 ; |
|
if (percent > 55) output |= 0x10 ; |
|
if (percent > 66) output |= 0x20 ; |
|
if (percent > 77) output |= 0x40 ; |
|
if (percent > 88) output |= 0x80 ; |
|
|
|
digitalWriteByte (output) ; |
|
} |
|
|
|
static unsigned int tPeriod, tNextSampleTime ; |
|
|
|
/* |
|
* sample: |
|
* Get a sample from the Gertboard. If not enough time has elapsed |
|
* since the last sample, then wait... |
|
********************************************************************************* |
|
*/ |
|
|
|
static void sample (void) |
|
{ |
|
unsigned int tFuture ; |
|
|
|
// Calculate the future sample time |
|
|
|
tFuture = tPeriod + tNextSampleTime ; |
|
|
|
// Wait until the next sample time |
|
|
|
while (micros () < tNextSampleTime) |
|
; |
|
|
|
buffer [bPtr] = gertboardAnalogRead (0) ; |
|
|
|
tNextSampleTime = tFuture ; |
|
} |
|
|
|
|
|
int main () |
|
{ |
|
int quietLevel, min, max ; |
|
int i, sum ; |
|
unsigned int tStart, tEnd ; |
|
|
|
printf ("\n") ; |
|
printf ("Gertboard demo: VU Meter\n") ; |
|
printf ("========================\n") ; |
|
|
|
wiringPiSetup () ; |
|
gertboardSPISetup () ; |
|
|
|
ledPercent (0) ; |
|
for (i = 0 ; i < 8 ; ++i) |
|
pinMode (i, OUTPUT) ; |
|
|
|
for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr) |
|
buffer [bPtr] = 99 ; |
|
|
|
tPeriod = 1000000 / 1000 ; |
|
|
|
printf ("Shhhh.... ") ; fflush (stdout) ; |
|
delay (1000) ; |
|
printf ("Sampling quiet... ") ; fflush (stdout) ; |
|
|
|
tStart = micros () ; |
|
|
|
tNextSampleTime = micros () ; |
|
for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr) |
|
sample () ; |
|
|
|
tEnd = micros () ; |
|
|
|
quietLevel = 0 ; |
|
max = 0 ; |
|
min = 1024 ; |
|
for (i = 0 ; i < B_SIZE ; ++i) |
|
{ |
|
quietLevel += buffer [i] ; |
|
if (buffer [i] > max) max = buffer [i] ; |
|
if (buffer [i] < min) min = buffer [i] ; |
|
} |
|
quietLevel /= B_SIZE ; |
|
|
|
printf ("Done. Quiet level is: %d [%d:%d] [%d:%d]\n", quietLevel, min, max, quietLevel - min, max - quietLevel) ; |
|
|
|
printf ("Time taken for %d reads: %duS\n", B_SIZE, tEnd - tStart) ; |
|
|
|
for (bPtr = 0 ;;) |
|
{ |
|
sample () ; |
|
sum = 0 ; |
|
for (i = 0 ; i < S_SIZE ; ++i) |
|
sum += buffer [i] ; |
|
sum /= S_SIZE ; |
|
sum = abs (quietLevel - sum) ; |
|
sum = (sum * 1000) / quietLevel ; |
|
ledPercent (sum) ; |
|
if (++bPtr > S_SIZE) |
|
bPtr = 0 ; |
|
} |
|
|
|
|
|
return 0 ; |
|
}
|
|
|