@@ -77,7 +77,7 @@ class GoertzelDetector {
7777 this ->config = config;
7878 this ->sample_count = 0 ;
7979
80- if (config.target_frequency == 0 .0f ){
80+ if (config.target_frequency == 0 .0f ) {
8181 return false ;
8282 }
8383
@@ -110,9 +110,9 @@ class GoertzelDetector {
110110 config.sample_rate );
111111 float imag =
112112 s2 * sin (2 .0f * M_PI * config.target_frequency / config.sample_rate );
113- magnitude_squared = real * real + imag * imag;
113+ magnitude_squared = ( real * real) + ( imag * imag) ;
114114 magnitude = sqrt (magnitude_squared);
115-
115+
116116 // Reset for next block
117117 reset ();
118118 return true ;
@@ -146,15 +146,14 @@ class GoertzelDetector {
146146 * @return True if magnitude is above configured threshold
147147 */
148148 bool isDetected () const { return isDetected (config.threshold ); }
149-
149+
150150 /* *
151151 * @brief Reset the detector state
152152 */
153153 void reset () {
154154 s1 = 0 .0f ;
155155 s2 = 0 .0f ;
156156 sample_count = 0 ;
157- magnitude = 0 .0f ;
158157 magnitude_squared = 0 .0f ;
159158 }
160159
@@ -173,14 +172,14 @@ class GoertzelDetector {
173172 */
174173 const GoertzelConfig& getConfig () const { return config; }
175174
176- void setReference (void * ref){ this ->reference = ref; }
175+ void setReference (void * ref) { this ->reference = ref; }
177176
178- void * getReference (){ return reference; }
177+ void * getReference () { return reference; }
179178
180179 protected:
181180 GoertzelConfig config;
182181 float coeff = 0 .0f ;
183- void * reference = nullptr ;
182+ void * reference = nullptr ;
184183
185184 // State variables
186185 float s1 = 0 .0f ;
@@ -193,10 +192,13 @@ class GoertzelDetector {
193192};
194193
195194/* *
196- * @brief AudioStream-based multi-frequency Goertzel detector for real-time audio analysis.
195+ * @brief AudioStream-based multi-frequency Goertzel detector for real-time
196+ * audio analysis.
197197 *
198- * GoertzelStream enables efficient detection of one or more target frequencies in a continuous audio stream.
199- * It acts as a transparent filter: audio data flows through unchanged, while the class analyzes the signal for specified tones.
198+ * GoertzelStream enables efficient detection of one or more target frequencies
199+ * in a continuous audio stream. It acts as a transparent filter: audio data
200+ * flows through unchanged, while the class analyzes the signal for specified
201+ * tones.
200202 *
201203 * Key Features:
202204 * - Detects multiple frequencies simultaneously (DTMF, tone detection, etc.)
@@ -208,10 +210,12 @@ class GoertzelDetector {
208210 * - Configurable detection parameters (block size, threshold, volume, etc.)
209211 *
210212 * Usage:
211- * 1. Configure the stream with GoertzelConfig or AudioInfo (sample rate, channels, etc.)
213+ * 1. Configure the stream with GoertzelConfig or AudioInfo (sample rate,
214+ * channels, etc.)
212215 * 2. Add one or more target frequencies using addFrequency()
213216 * 3. Optionally set a detection callback with setFrequencyDetectionCallback()
214- * 4. Use write() or readBytes() to process audio data; detection runs automatically
217+ * 4. Use write() or readBytes() to process audio data; detection runs
218+ * automatically
215219 *
216220 * Supported sample formats:
217221 * - 8-bit: unsigned (0-255), internally converted to signed (-128 to 127)
@@ -226,7 +230,12 @@ class GoertzelDetector {
226230 */
227231class GoertzelStream : public AudioStream {
228232 public:
233+ // Default Constructor with no output or input
229234 GoertzelStream () = default ;
235+ GoertzelStream (Print& out) { setOutput (out); }
236+ GoertzelStream (AudioOutput& out) { setOutput (out); }
237+ GoertzelStream (Stream& io) { setStream (io); };
238+ GoertzelStream (AudioStream& io) { setStream (io); };
230239
231240 /* *
232241 * @brief Set audio format and initialize detector array
@@ -245,6 +254,20 @@ class GoertzelStream : public AudioStream {
245254 begin ();
246255 }
247256
257+ /* *
258+ * @brief Returns a default GoertzelConfig instance with standard parameters
259+ *
260+ * This utility method provides a convenient way to obtain a default
261+ * configuration for the Goertzel algorithm. The returned config can be
262+ * customized before use.
263+ *
264+ * @return GoertzelConfig with default values
265+ */
266+ GoertzelConfig defaultConfig () {
267+ GoertzelConfig result;
268+ return result;
269+ }
270+
248271 /* *
249272 * @brief Initialize with GoertzelConfig
250273 *
@@ -284,11 +307,12 @@ class GoertzelStream : public AudioStream {
284307 GoertzelConfig cfg = default_config;
285308 cfg.target_frequency = freq;
286309 GoertzelDetector detector;
287- if (i++ < references.size ()){
310+ if (i < references.size ()) {
288311 detector.setReference (references[i]);
289312 }
290313 detector.begin (cfg);
291314 detectors.push_back (detector);
315+ i++;
292316 }
293317 sample_no = 0 ;
294318 return true ;
@@ -308,9 +332,21 @@ class GoertzelStream : public AudioStream {
308332 p_print = ∈
309333 }
310334
335+ // / Defines/Changes the input & output
336+ void setStream (AudioStream& io) {
337+ setStream ((Stream&)io);
338+ addNotifyAudioChange (io);
339+ }
340+
311341 // / Defines/Changes the output target
312342 void setOutput (Print& out) { p_print = &out; }
313343
344+ // / Defines/Changes the output target
345+ void setOutput (AudioOutput& out) {
346+ setOutput ((Print&)out);
347+ addNotifyAudioChange (out);
348+ }
349+
314350 /* *
315351 * @brief Set detection callback function for channel-aware frequency
316352 * detection
@@ -322,8 +358,9 @@ class GoertzelStream : public AudioStream {
322358 * @param callback Function to call when frequency is detected, includes
323359 * channel info
324360 */
325- void setFrequencyDetectionCallback (void (*callback)(
326- int channel, float frequency, float magnitude, void * ref)) {
361+ void setFrequencyDetectionCallback (void (*callback)(float frequency,
362+ float magnitude,
363+ void * ref)) {
327364 frequency_detection_callback = callback;
328365 }
329366
@@ -340,8 +377,6 @@ class GoertzelStream : public AudioStream {
340377 * @return Number of bytes written to output stream
341378 */
342379 size_t write (const uint8_t * data, size_t len) override {
343- if (p_print == nullptr ) return 0 ;
344-
345380 // Process samples for detection
346381 processSamples (data, len);
347382
@@ -408,40 +443,43 @@ class GoertzelStream : public AudioStream {
408443 GoertzelDetector& getDetector (int no) { return detectors[no]; }
409444
410445 /* *
411- * @brief Add a frequency to the detection list
446+ * @brief Add a frequency to the detection list
412447 *
413448 * @param freq Frequency in Hz to add to the detection list
414449 */
415450 void addFrequency (float freq) { frequencies.push_back (freq); }
416451
417452 /* *
418- * @brief Add a frequency to the detection list with a custom reference pointer
453+ * @brief Add a frequency to the detection list with a custom reference
454+ * pointer
419455 *
420- * This method allows you to associate a user-defined reference (context pointer)
421- * with a specific frequency. The reference will be passed to the detection callback
422- * when this frequency is detected, enabling per-frequency context handling.
456+ * This method allows you to associate a user-defined reference (context
457+ * pointer) with a specific frequency. The reference will be passed to the
458+ * detection callback when this frequency is detected, enabling per-frequency
459+ * context handling.
423460 *
424461 * @param freq Frequency in Hz to add to the detection list
425462 * @param ref Pointer to user-defined context object for this frequency
426463 */
427- void addFrequency (float freq, void * ref) {
428- frequencies.push_back (freq);
464+ void addFrequency (float freq, void * ref) {
465+ frequencies.push_back (freq);
429466 references.push_back (ref);
430467 }
431468
432469 protected:
433470 // Core detection components
434- Vector<GoertzelDetector> detectors; // /< One detector per frequency in frequencies
471+ Vector<GoertzelDetector>
472+ detectors; // /< One detector per frequency in frequencies
435473 Vector<float > frequencies; // /< List of frequencies to detect
436- Vector<void *> references; // /< List of frequencies to detect
474+ Vector<void *> references; // /< List of frequencies to detect
437475 GoertzelConfig default_config; // /< Current algorithm configuration
438476 // Stream I/O components
439477 Stream* p_stream = nullptr ; // /< Input stream for reading audio data
440478 Print* p_print = nullptr ; // /< Output stream for writing audio data
441479
442480 // Callback system
443- void (*frequency_detection_callback)(int channel , float frequency ,
444- float magnitude, void * ref) =
481+ void (*frequency_detection_callback)(float frequency , float magnitude ,
482+ void * ref) =
445483 nullptr ; // /< User callback for detection events
446484 void * ref = this ; // /< User-defined reference for callback context
447485
@@ -452,13 +490,15 @@ class GoertzelStream : public AudioStream {
452490 */
453491 void checkDetection (GoertzelDetector& detector) {
454492 float magnitude = detector.getMagnitude ();
493+ if (magnitude > 0 .0f )
494+ LOGD (" frequency: %f / magnitude: %f / threshold: %f" , detector.getTargetFrequency (), magnitude, default_config.threshold );
495+
455496 if (magnitude > default_config.threshold ) {
456497 float frequency = detector.getTargetFrequency ();
457- void * reference = detector.getReference ();
458- if (reference== nullptr ) reference = ref;
498+ void * reference = detector.getReference ();
499+ if (reference == nullptr ) reference = ref;
459500 if (frequency_detection_callback != nullptr ) {
460- frequency_detection_callback (default_config.channel , frequency,
461- magnitude, reference);
501+ frequency_detection_callback (frequency, magnitude, reference);
462502 }
463503 }
464504 }
@@ -487,8 +527,9 @@ class GoertzelStream : public AudioStream {
487527 if (sample_no % channels == default_config.channel ) {
488528 float normalized = clip (NumberConverter::toFloatT<T>(samples[i]) *
489529 default_config.volume );
530+ LOGD (" sample: %f" , normalized);
490531 // process all frequencies
491- for (auto & detector : detectors) {
532+ for (auto & detector : detectors) {
492533 if (detector.processSample (normalized)) {
493534 checkDetection (detector);
494535 }
0 commit comments