Skip to content

Commit

Permalink
added Goertzel library and restructured files
Browse files Browse the repository at this point in the history
  • Loading branch information
k3ng committed May 15, 2018
1 parent 5449fee commit 72f1f2a
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 0 deletions.
File renamed without changes.
136 changes: 136 additions & 0 deletions libraries/Goertzel/goertzel.cpp
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);

}
80 changes: 80 additions & 0 deletions libraries/Goertzel/goertzel.h
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

0 comments on commit 72f1f2a

Please sign in to comment.