first commit
This commit is contained in:
Executable
+136
@@ -0,0 +1,136 @@
|
||||
#include "goertzel.h"
|
||||
|
||||
/*
|
||||
|
||||
|
||||
Goertzel formula audio detector
|
||||
|
||||
This code comes from http://www.skovholm.com/cwdecoder , http://www.skovholm.com/decoder11.ino
|
||||
|
||||
Hjalmar skovholm Hansen, Oz1jhm <hjh@skovholm.com>
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
float coeff = 0;
|
||||
float Q1 = 0;
|
||||
float Q2 = 0;
|
||||
float sine = 0;
|
||||
float cosine = 0;
|
||||
//float sampling_freq = GOERTZ_SAMPLING_FREQ;
|
||||
//float target_freq = GOERTZ_TARGET_FREQ;
|
||||
//float n = GOERTZ_SAMPLES_FLOAT;
|
||||
int testData[GOERTZ_SAMPLES];
|
||||
int audioInPin = 0;
|
||||
int realstate = LOW;
|
||||
int realstatebefore = LOW;
|
||||
int filteredstate = LOW;
|
||||
unsigned long laststarttime = 0;
|
||||
int magnitudelimit = 100;
|
||||
float magnitude = 0;
|
||||
|
||||
//////////////////////////////
|
||||
// Noise Blanker time which //
|
||||
// shall be computed so //
|
||||
// this is initial //
|
||||
//////////////////////////////
|
||||
|
||||
int nbtime = GOERTZ_NOISE_BLANKER_INITIAL_MS;
|
||||
|
||||
|
||||
Goertzdetector::Goertzdetector(){}
|
||||
|
||||
|
||||
void Goertzdetector::init(int _audioInPin){
|
||||
// The basic goertzel calculation
|
||||
|
||||
int k = 0;
|
||||
float omega = 0;
|
||||
//k = (int) (0.5 + ((n * target_freq) / sampling_freq));
|
||||
k = (int) (0.5 + (((float)GOERTZ_SAMPLES * (float)GOERTZ_TARGET_FREQ) / (float)GOERTZ_SAMPLING_FREQ));
|
||||
//omega = (2.0 * PI * k) / n;
|
||||
omega = (2.0 * PI * k) / (float) GOERTZ_SAMPLES;
|
||||
sine = sin(omega);
|
||||
cosine = cos(omega);
|
||||
coeff = 2.0 * cosine;
|
||||
|
||||
audioInPin = _audioInPin;
|
||||
|
||||
}
|
||||
|
||||
int Goertzdetector::detecttone(){
|
||||
|
||||
|
||||
// The basic where we get the tone
|
||||
|
||||
|
||||
for (char index = 0; index < GOERTZ_SAMPLES; index++){
|
||||
testData[index] = analogRead(audioInPin);
|
||||
}
|
||||
|
||||
for (char index = 0; index < GOERTZ_SAMPLES; index++){
|
||||
float Q0;
|
||||
Q0 = coeff * Q1 - Q2 + (float) testData[index];
|
||||
Q2 = Q1;
|
||||
Q1 = Q0;
|
||||
}
|
||||
|
||||
float magnitudeSquared = (Q1*Q1)+(Q2*Q2)-Q1*Q2*coeff; // we do only need the real part //
|
||||
|
||||
magnitude = sqrt(magnitudeSquared);
|
||||
|
||||
Q2 = 0;
|
||||
Q1 = 0;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// here we will try to set the magnitude limit automatic //
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
if (magnitude > GOERTZ_MAGNITUDE_LIMIT_LOW){
|
||||
magnitudelimit = (magnitudelimit + ((magnitude - magnitudelimit) / GOERTZ_MOVING_AVERAGE_FILTER)); /// moving average filter
|
||||
} else {
|
||||
magnitudelimit = GOERTZ_MAGNITUDE_LIMIT_LOW;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// now we check for the magnitude //
|
||||
////////////////////////////////////
|
||||
|
||||
if (magnitude > ((float) magnitudelimit * (float) GOERTZ_MAGNITUDE_THRESHOLD)){
|
||||
realstate = HIGH;
|
||||
} else {
|
||||
realstate = LOW;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// here we clean up the state with a noise blanker //
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
if (realstate != realstatebefore){
|
||||
laststarttime = millis();
|
||||
}
|
||||
|
||||
if ((millis()-laststarttime) > nbtime){
|
||||
if (realstate != filteredstate){
|
||||
filteredstate = realstate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
realstatebefore = realstate;
|
||||
|
||||
return(filteredstate);
|
||||
|
||||
}
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#ifndef GOERTZEL_H
|
||||
#define GOERTZEL_H
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
Goertzel formula audio detector
|
||||
|
||||
This code comes from http://www.skovholm.com/cwdecoder , http://www.skovholm.com/decoder11.ino
|
||||
|
||||
Hjalmar skovholm Hansen, OZ1JHM <hjh@skovholm.com>
|
||||
|
||||
|
||||
Notes from the original code author, OZ1JHM (with edits from Goody K3NG)
|
||||
|
||||
GOERTZ_SAMPLING_FREQ will be 8928 on a 16 mhz without any prescaler etc.
|
||||
because we need the tone in the center of the bins
|
||||
you can set GOERTZ_TARGET_FREQ (the tone) to 496, 558, 744 or 992
|
||||
then GOERTZ_SAMPLES_INT the number of samples which give the bandwidth
|
||||
which can be (8928 / GOERTZ_TARGET_FREQ) * 1 or 2 or 3 or 4 etc
|
||||
init is 8928/558 = 16 * 4 = 64 samples
|
||||
|
||||
try to take GOERTZ_SAMPLES = 96 or 128 ;o)
|
||||
|
||||
48 will give you a bandwidth around 186 hz
|
||||
64 will give you a bandwidth around 140 hz
|
||||
96 will give you a bandwidth around 94 hz
|
||||
128 will give you a bandwidth around 70 hz
|
||||
|
||||
BUT remember that a high GOERTZ_SAMPLES will take a lot of time so you have to find a compromise
|
||||
|
||||
*/
|
||||
|
||||
#if defined(_VARIANT_ARDUINO_DUE_X_)
|
||||
// Arduino Due (84 Mhz clock)
|
||||
#define GOERTZ_SAMPLING_FREQ 46872.0
|
||||
#define GOERTZ_SAMPLES 252 //168 //84
|
||||
#else
|
||||
// Arduino Uno, Mega (16 Mhz clock)
|
||||
#define GOERTZ_SAMPLING_FREQ 8928.0
|
||||
#define GOERTZ_SAMPLES 48 //48 //64
|
||||
#endif
|
||||
|
||||
#define GOERTZ_NOISE_BLANKER_INITIAL_MS 6
|
||||
#define GOERTZ_TARGET_FREQ 558.0
|
||||
|
||||
|
||||
|
||||
#define GOERTZ_MAGNITUDE_LIMIT_LOW 100
|
||||
#define GOERTZ_MAGNITUDE_THRESHOLD 0.6 //0.6
|
||||
#define GOERTZ_MOVING_AVERAGE_FILTER 6
|
||||
|
||||
|
||||
class Goertzdetector {
|
||||
|
||||
public:
|
||||
Goertzdetector();
|
||||
void init(int _audioInPin);
|
||||
int detecttone();
|
||||
int testData[GOERTZ_SAMPLES];
|
||||
float magnitude;
|
||||
int magnitudelimit;
|
||||
int magnitudelimit_low;
|
||||
|
||||
private:
|
||||
|
||||
float coeff;
|
||||
float Q1;
|
||||
float Q2;
|
||||
float sine;
|
||||
float cosine;
|
||||
int audioInPin;
|
||||
int realstate;
|
||||
int realstatebefore;
|
||||
int filteredstate;
|
||||
unsigned long laststarttime;
|
||||
|
||||
};
|
||||
|
||||
#endif //GOERTZEL_H
|
||||
Reference in New Issue
Block a user