-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added Goertzel library and restructured files
- Loading branch information
Showing
3 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <[email protected]> | ||
*/ | ||
|
||
#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); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#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 <[email protected]> | ||
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 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 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 |