From 17010218ce8a6f1862652eaa70b966f02084e9c0 Mon Sep 17 00:00:00 2001 From: boblark Date: Tue, 30 Mar 2021 14:03:30 -0700 Subject: [PATCH] Add class analyze_tonedetect_F32 --- OpenAudio_ArduinoLibrary.h | 4 +- analyze_tonedetect_F32.cpp | 118 +++++++++++++++++++++++++++++++++++++ analyze_tonedetect_F32.h | 101 +++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 analyze_tonedetect_F32.cpp create mode 100644 analyze_tonedetect_F32.h diff --git a/OpenAudio_ArduinoLibrary.h b/OpenAudio_ArduinoLibrary.h index aea0fde..74c2a93 100644 --- a/OpenAudio_ArduinoLibrary.h +++ b/OpenAudio_ArduinoLibrary.h @@ -9,7 +9,7 @@ #include "AudioConvert_F32.h" #include "AudioEffectCompressor_F32.h" #include "AudioEffectCompressor2_F32.h" -#include "AudioEffectCompWDRC_F32.h" +//#include "AudioEffectCompWDRC_F32.h" #include "AudioEffectEmpty_F32.h" #include "AudioEffectGain_F32.h" #include "AudioFilterBiquad_F32.h" @@ -34,6 +34,7 @@ #include "analyze_fft4096_iq_F32.h" #include "analyze_peak_f32.h" #include "analyze_rms_f32.h" +#include "analyze_tonedetect_F32.h" // #include "control_tlv320aic3206.h" collides much with Teensy Audio #include "AudioSwitch_OA_F32.h" #include "FFT_Overlapped_OA_F32.h" @@ -45,5 +46,6 @@ #include "AudioFilterEqualizer_F32.h" #include "AudioFilterFIRGeneral_F32.h" #include "RadioFMDetector_F32.h" +#include "radioFMSquelch_F32.h" #include "radioNoiseBlanker_F32.h" #include "synth_sin_cos_f32.h" diff --git a/analyze_tonedetect_F32.cpp b/analyze_tonedetect_F32.cpp new file mode 100644 index 0000000..45b95e7 --- /dev/null +++ b/analyze_tonedetect_F32.cpp @@ -0,0 +1,118 @@ +/* + * analyze_tonedetect_F32.cpp Converted to float from PJRC Teensy Audio Library + * MIT License on changed portions + * Bob Larkin March 2021 + * + * Audio Library for Teensy 3.X + * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com + * + * Development of this audio library was funded by PJRC.COM, LLC by sales of + * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop + * open source software by purchasing Teensy or other PJRC products. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice, development funding notice, and this permission + * notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "analyze_tonedetect_F32.h" +//#include "utility/dspinst.h" + +void AudioAnalyzeToneDetect_F32::update(void) { + audio_block_f32_t *block; + float q0, q1, q2, coef; + float *p, *end; + uint16_t n; + + block = receiveReadOnly_f32(); + if (!block) return; + if (!enabled) { + release(block); + return; + } + + p = block->data; + end = p + AUDIO_BLOCK_SAMPLES; + n = count; + coef = coefficient; + q1 = s1; + q2 = s2; + if(n==length) {q1=0.0f; q2=0.0; } + do { // Update Goertzel algorithm + q0 = (*p++) + coef*q1 - q2; + q2 = q1; + q1 = q0; + if (--n == 0) { // Full "count" been achieved, estimate done + out1 = q1; + out2 = q2; + q1 = 0.0f; + q2 = 0.0f; + new_output = true; + n = length; + } + } while (p < end); + count = n; + s1 = q1; + s2 = q2; + release(block); + } + +void AudioAnalyzeToneDetect_F32::set_params(float coef, uint16_t cycles, uint16_t len) { + __disable_irq(); + coefficient = coef; + ncycles = cycles; + length = len; + count = len; + s1 = 0.0f; + s2 = 0.0f; + enabled = true; + __enable_irq(); + } + +float AudioAnalyzeToneDetect_F32::read(void) { + float coef, q1, q2, power; + uint16_t len; + + __disable_irq(); + coef = coefficient; + q1 = out1; + q2 = out2; + len = length; + __enable_irq(); + power = q1*q1 + q2*q2 - q1*q2*coef; + return 2.0f*sqrtf(power)/(float)len; // Scale to (0.0, 1.0) + } + +AudioAnalyzeToneDetect_F32::operator bool() { + float coef, q1, q2, power, trigger; + uint16_t len; + + __disable_irq(); + coef = coefficient; + q1 = out1; + q2 = out2; + len = length; + __enable_irq(); + + trigger = (float)len * thresh; + trigger *= trigger; + //Serial.println("bool: power, trigger = "); Serial.print(power, 6); Serial.print(", "); Serial.println(trigger, 6); + return (power >= trigger); + // TODO: this should really remember if it's retuned true previously, + // so it can give a single true response each time a tone is seen. + } diff --git a/analyze_tonedetect_F32.h b/analyze_tonedetect_F32.h new file mode 100644 index 0000000..e11176a --- /dev/null +++ b/analyze_tonedetect_F32.h @@ -0,0 +1,101 @@ +/* + * analyze_tonedetect_F32.h Converted to float from PJRC Teensy Audio Library + * MIT License on changed portions + * Bob Larkin March 2021 + * + * Audio Library for Teensy 3.X + * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com + * + * Development of this audio library was funded by PJRC.COM, LLC by sales of + * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop + * open source software by purchasing Teensy or other PJRC products. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice, development funding notice, and this permission + * notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef analyze_tonedetect_F32_h_ +#define analyze_tonedetect_F32_h_ + +#include "Arduino.h" +#include "AudioStream_F32.h" + +class AudioAnalyzeToneDetect_F32 : public AudioStream_F32 +{ +//GUI: inputs:1, outputs:0 //this line used for automatic generation of GUI node +//GUI: shortName:ToneDet +public: + AudioAnalyzeToneDetect_F32(void) + : AudioStream_F32(1, inputQueueArray_f32), thresh(0.1f), enabled(false) { + sample_rate_Hz = AUDIO_SAMPLE_RATE; + block_size = AUDIO_BLOCK_SAMPLES; + } + // Option of AudioSettings_F32 change to block size and/or sample rate: + AudioAnalyzeToneDetect_F32(const AudioSettings_F32 &settings) : AudioStream_F32(1, inputQueueArray_f32), + thresh(0.1f), enabled(false) { + sample_rate_Hz = settings.sample_rate_Hz; + block_size = settings.audio_block_samples; + } + + void frequency(float freq, uint16_t cycles=10) { + set_params( 2.0f*cosf(freq*6.28318530718f/sample_rate_Hz), + cycles, + (uint16_t)( 0.5f + sample_rate_Hz*(float)cycles/freq) ); + //(uint16_t)( ( (float)sample_rate_Hz/freq*(float)cycles) + 0.5f) ); + } + + bool available(void) { + __disable_irq(); + bool flag = new_output; + if(flag) + new_output = false; + __enable_irq(); + return flag; + } + + float read(void); + + void threshold(float level) { + if (level < 0.01f) thresh = 0.01f; + else if (level > 0.99f) thresh = 0.99f; + else thresh = level; + } + + operator bool(); // true if at or above threshold, false if below + + void set_params(float coef, uint16_t cycles, uint16_t len); + + virtual void update(void); + +private: + float coefficient; // Goertzel algorithm coefficient + float s1, s2; // Goertzel algorithm state + float out1, out2; // Goertzel algorithm state output + float power; + uint16_t length; // number of samples to analyze + uint16_t count; // how many left to analyze + uint16_t ncycles; // number of waveform cycles to seek + uint16_t thresh = 0.1f; // threshold, 0.01 to 0.99 + bool enabled = false; + volatile bool new_output = false; + audio_block_f32_t *inputQueueArray_f32[1]; + float sample_rate_Hz = AUDIO_SAMPLE_RATE; + uint16_t block_size = 128; +}; + +#endif