minor cleanups
* add "override" to all methods that oveeride the base usermod class * fixing a minor copy-paste mistake * ovoid shadowing class attributes * spelling, grammar and other nitpick
This commit is contained in:
@@ -127,7 +127,7 @@
|
|||||||
#define AUDIOSYNC_REC_PLUS 0x06 // UDP sound sync - receiver + local mode (uses local input if no receiving udp sound)
|
#define AUDIOSYNC_REC_PLUS 0x06 // UDP sound sync - receiver + local mode (uses local input if no receiving udp sound)
|
||||||
#define AUDIOSYNC_IDLE_MS 2500 // timeout for "receiver idle" (milliseconds)
|
#define AUDIOSYNC_IDLE_MS 2500 // timeout for "receiver idle" (milliseconds)
|
||||||
|
|
||||||
static volatile bool disableSoundProcessing = false; // if true, sound processing (FFT, filters, AGC) will be suspended. "volatile" as its shared between tasks.
|
static volatile bool disableSoundProcessing = false; // if true, sound processing (FFT, filters, AGC) will be suspended. "volatile" as it is shared between tasks.
|
||||||
static uint8_t audioSyncEnabled = AUDIOSYNC_NONE; // bit field: bit 0 - send, bit 1 - receive, bit 2 - use local if not receiving
|
static uint8_t audioSyncEnabled = AUDIOSYNC_NONE; // bit field: bit 0 - send, bit 1 - receive, bit 2 - use local if not receiving
|
||||||
static bool audioSyncSequence = true; // if true, the receiver will drop out-of-sequence packets
|
static bool audioSyncSequence = true; // if true, the receiver will drop out-of-sequence packets
|
||||||
static uint8_t audioSyncPurge = 1; // 0: process all received packets; 1: auto-purge old packets; 2:only process last received packets
|
static uint8_t audioSyncPurge = 1; // 0: process all received packets; 1: auto-purge old packets; 2:only process last received packets
|
||||||
@@ -317,7 +317,7 @@ static const float fftResultPink[MAX_PINK+1][NUM_GEQ_CHANNELS] = {
|
|||||||
* Your HiFi equipment should receive its audio input from Line-In, SPDIF, HDMI, or another "undistorted" connection (like CDROM).
|
* Your HiFi equipment should receive its audio input from Line-In, SPDIF, HDMI, or another "undistorted" connection (like CDROM).
|
||||||
* Try not to use Bluetooth or MP3 when playing the "pink noise" audio. BT-audio and MP3 both perform "acoustic adjustments" that we don't want now.
|
* Try not to use Bluetooth or MP3 when playing the "pink noise" audio. BT-audio and MP3 both perform "acoustic adjustments" that we don't want now.
|
||||||
|
|
||||||
* SR WLED: enable AGC ("standard" or "lazy"), set squelch to a low level, check that LEDs don't reacts in silence.
|
* SR WLED: enable AGC ("standard" or "lazy"), set squelch to a low level, check that LEDs don't react in silence.
|
||||||
* SR WLED: select "Generic Line-In" as your Frequency Profile, "Linear" or "Square Root" as Frequency Scale
|
* SR WLED: select "Generic Line-In" as your Frequency Profile, "Linear" or "Square Root" as Frequency Scale
|
||||||
* SR WLED: Dynamic Limiter On, Dynamics Fall Time around 4200 - makes GEQ hold peaks for much longer
|
* SR WLED: Dynamic Limiter On, Dynamics Fall Time around 4200 - makes GEQ hold peaks for much longer
|
||||||
* SR WLED: Select GEQ effect, move all effect slider to max (i.e. right side)
|
* SR WLED: Select GEQ effect, move all effect slider to max (i.e. right side)
|
||||||
@@ -328,12 +328,12 @@ static const float fftResultPink[MAX_PINK+1][NUM_GEQ_CHANNELS] = {
|
|||||||
* Your own profile:
|
* Your own profile:
|
||||||
* - Target for each LED bar is 50% to 75% of the max height --> 8(high) x 16(wide) panel means target = 5. 32 x 16 means target = 22.
|
* - Target for each LED bar is 50% to 75% of the max height --> 8(high) x 16(wide) panel means target = 5. 32 x 16 means target = 22.
|
||||||
* - From left to right - count the LEDs in each of the 16 frequency columns (that's why you need the photo). This is the barheight for each channel.
|
* - From left to right - count the LEDs in each of the 16 frequency columns (that's why you need the photo). This is the barheight for each channel.
|
||||||
* - math time! Find the multiplier that will bring each bar to to target.
|
* - math time! Find the multiplier that will bring each bar to the target.
|
||||||
* * in case of square root scale: multiplier = (target * target) / (barheight * barheight)
|
* * in case of square root scale: multiplier = (target * target) / (barheight * barheight)
|
||||||
* * in case of linear scale: multiplier = target / barheight
|
* * in case of linear scale: multiplier = target / barheight
|
||||||
*
|
*
|
||||||
* - replace one of the "userdef" lines with a copy of the parameter line for "Line-In",
|
* - replace one of the "userdef" lines with a copy of the parameter line for "Line-In",
|
||||||
* - go through your new "userdef" parameter line, multiply each entry with the mutliplier you found for that column.
|
* - go through your new "userdef" parameter line, multiply each entry with the multiplier you found for that column.
|
||||||
|
|
||||||
* Compile + upload
|
* Compile + upload
|
||||||
* Test your new profile (same procedure as above). Iterate the process to improve results.
|
* Test your new profile (same procedure as above). Iterate the process to improve results.
|
||||||
@@ -404,7 +404,7 @@ constexpr float binWidth = SAMPLE_RATE / (float)samplesFFT; // frequency range o
|
|||||||
// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
||||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
// these options actually cause slow-down on -S2 (-S2 doesn't have floating point hardware)
|
// these options actually cause slow-down on -S2 (-S2 doesn't have floating point hardware)
|
||||||
//#define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc), and an a few other speedups - WLEDMM not faster on ESP32
|
//#define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc), and a few other speedups - WLEDMM not faster on ESP32
|
||||||
//#define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt - WLEDMM slower on ESP32
|
//#define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt - WLEDMM slower on ESP32
|
||||||
#endif
|
#endif
|
||||||
#define sqrt(x) sqrtf(x) // little hack that reduces FFT time by 10-50% on ESP32 (as alternative to FFT_SQRT_APPROXIMATION)
|
#define sqrt(x) sqrtf(x) // little hack that reduces FFT time by 10-50% on ESP32 (as alternative to FFT_SQRT_APPROXIMATION)
|
||||||
@@ -675,11 +675,11 @@ void FFTcode(void * parameter)
|
|||||||
haveOldSamples = true;
|
haveOldSamples = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// find highest sample in the batch, and count zero crossings
|
// find the highest sample in the batch, and count zero crossings
|
||||||
float maxSample = 0.0f; // max sample from FFT batch
|
float maxSample = 0.0f; // max sample from FFT batch
|
||||||
uint_fast16_t newZeroCrossingCount = 0;
|
uint_fast16_t newZeroCrossingCount = 0;
|
||||||
for (int i=0; i < samplesFFT; i++) {
|
for (int i=0; i < samplesFFT; i++) {
|
||||||
// pick our our current mic sample - we take the max value from all samples that go into FFT
|
// pick our current mic sample - we take the max value from all samples that go into FFT
|
||||||
if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) { //skip extreme values - normally these are artefacts
|
if ((vReal[i] <= (INT16_MAX - 1024)) && (vReal[i] >= (INT16_MIN + 1024))) { //skip extreme values - normally these are artefacts
|
||||||
#ifdef FFT_USE_SLIDING_WINDOW
|
#ifdef FFT_USE_SLIDING_WINDOW
|
||||||
if (usingOldSamples) {
|
if (usingOldSamples) {
|
||||||
@@ -706,7 +706,7 @@ void FFTcode(void * parameter)
|
|||||||
micReal_max = datMax;
|
micReal_max = datMax;
|
||||||
micReal_avg = datAvg / samplesFFT;
|
micReal_avg = datAvg / samplesFFT;
|
||||||
#if 0
|
#if 0
|
||||||
// compute mix/max again after filering - usefull for filter debugging
|
// compute mix/max again after filtering - useful for filter debugging
|
||||||
for (int i=0; i < samplesFFT; i++) {
|
for (int i=0; i < samplesFFT; i++) {
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
datMin = datMax = vReal[i];
|
datMin = datMax = vReal[i];
|
||||||
@@ -750,7 +750,7 @@ void FFTcode(void * parameter)
|
|||||||
break;
|
break;
|
||||||
case 0: // falls through
|
case 0: // falls through
|
||||||
default:
|
default:
|
||||||
FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // Weigh data using "Blackman- Harris" window - sharp peaks due to excellent sideband rejection
|
FFT.windowing(FFTWindow::Blackman_Harris, FFTDirection::Forward); // Weigh data using "Blackman - Harris" window - sharp peaks due to excellent sideband rejection
|
||||||
wc = 1.0f; // 2.7929062517 * 2.0
|
wc = 1.0f; // 2.7929062517 * 2.0
|
||||||
}
|
}
|
||||||
#ifdef FFT_USE_SLIDING_WINDOW
|
#ifdef FFT_USE_SLIDING_WINDOW
|
||||||
@@ -1233,11 +1233,11 @@ class AudioReactive : public Usermod {
|
|||||||
float soundPressure = 0; // Sound Pressure estimation, based on microphone raw readings. 0 ->5db, 255 ->105db
|
float soundPressure = 0; // Sound Pressure estimation, based on microphone raw readings. 0 ->5db, 255 ->105db
|
||||||
|
|
||||||
// used to feed "Info" Page
|
// used to feed "Info" Page
|
||||||
unsigned long last_UDPTime = 0; // time of last valid UDP sound sync datapacket
|
unsigned long last_UDPTime = 0; // time of last valid UDP sound sync data packet
|
||||||
int receivedFormat = 0; // last received UDP sound sync format - 0=none, 1=v1 (0.13.x), 2=v2 (0.14.x)
|
int receivedFormat = 0; // last received UDP sound sync format - 0=none, 1=v1 (0.13.x), 2=v2 (0.14.x)
|
||||||
float maxSample5sec = 0.0f; // max sample (after AGC) in last 5 seconds
|
float maxSample5sec = 0.0f; // max sample (after AGC) in last 5 seconds
|
||||||
unsigned long sampleMaxTimer = 0; // last time maxSample5sec was reset
|
unsigned long sampleMaxTimer = 0; // last time maxSample5sec was reset
|
||||||
#define CYCLE_SAMPLEMAX 3500 // time window for merasuring
|
#define CYCLE_SAMPLEMAX 3500 // time window for measuring
|
||||||
|
|
||||||
// strings to reduce flash memory usage (used more than twice)
|
// strings to reduce flash memory usage (used more than twice)
|
||||||
static const char _name[];
|
static const char _name[];
|
||||||
@@ -1296,7 +1296,7 @@ class AudioReactive : public Usermod {
|
|||||||
//
|
//
|
||||||
// Set true if wanting to see all the bands in their own vertical space on the Serial Plotter, false if wanting to see values in Serial Monitor
|
// Set true if wanting to see all the bands in their own vertical space on the Serial Plotter, false if wanting to see values in Serial Monitor
|
||||||
const bool mapValuesToPlotterSpace = false;
|
const bool mapValuesToPlotterSpace = false;
|
||||||
// Set true to apply an auto-gain like setting to to the data (this hasn't been tested recently)
|
// Set true to apply an auto-gain like setting to the data (this hasn't been tested recently)
|
||||||
const bool scaleValuesFromCurrentMaxVal = false;
|
const bool scaleValuesFromCurrentMaxVal = false;
|
||||||
// prints the max value seen in the current data
|
// prints the max value seen in the current data
|
||||||
const bool printMaxVal = false;
|
const bool printMaxVal = false;
|
||||||
@@ -1343,7 +1343,7 @@ class AudioReactive : public Usermod {
|
|||||||
/*
|
/*
|
||||||
* A "PI controller" multiplier to automatically adjust sound sensitivity.
|
* A "PI controller" multiplier to automatically adjust sound sensitivity.
|
||||||
*
|
*
|
||||||
* A few tricks are implemented so that sampleAgc does't only utilize 0% and 100%:
|
* A few tricks are implemented so that sampleAgc doesn't only utilize 0% and 100%:
|
||||||
* 0. don't amplify anything below squelch (but keep previous gain)
|
* 0. don't amplify anything below squelch (but keep previous gain)
|
||||||
* 1. gain input = maximum signal observed in the last 5-10 seconds
|
* 1. gain input = maximum signal observed in the last 5-10 seconds
|
||||||
* 2. we use two setpoints, one at ~60%, and one at ~80% of the maximum signal
|
* 2. we use two setpoints, one at ~60%, and one at ~80% of the maximum signal
|
||||||
@@ -1576,12 +1576,12 @@ class AudioReactive : public Usermod {
|
|||||||
// * sample < squelch -> just above hearing level --> 5db ==> 0
|
// * sample < squelch -> just above hearing level --> 5db ==> 0
|
||||||
// see https://en.wikipedia.org/wiki/Sound_pressure#Examples_of_sound_pressure
|
// see https://en.wikipedia.org/wiki/Sound_pressure#Examples_of_sound_pressure
|
||||||
// use with I2S digital microphones. Expect stupid values for analog in, and with Line-In !!
|
// use with I2S digital microphones. Expect stupid values for analog in, and with Line-In !!
|
||||||
float estimatePressure() {
|
float estimatePressure() const {
|
||||||
// some constants
|
// some constants
|
||||||
constexpr float logMinSample = 0.8329091229351f; // ln(2.3)
|
constexpr float logMinSample = 0.8329091229351f; // ln(2.3)
|
||||||
constexpr float sampleMin = 2.3f;
|
constexpr float sampleRangeMin = 2.3f;
|
||||||
constexpr float logMaxSample = 10.1895683436f; // ln(32767 - 6144)
|
constexpr float logMaxSample = 10.1895683436f; // ln(32767 - 6144)
|
||||||
constexpr float sampleMax = 32767.0f - 6144.0f;
|
constexpr float sampleRangeMax = 32767.0f - 6144.0f;
|
||||||
|
|
||||||
// take the max sample from last I2S batch.
|
// take the max sample from last I2S batch.
|
||||||
float micSampleMax = fabsf(sampleReal); // from getSample() - nice results, however a bit distorted by MicLev processing
|
float micSampleMax = fabsf(sampleReal); // from getSample() - nice results, however a bit distorted by MicLev processing
|
||||||
@@ -1589,18 +1589,18 @@ class AudioReactive : public Usermod {
|
|||||||
if (dmType == 0) micSampleMax *= 2.0f; // correction for ADC analog
|
if (dmType == 0) micSampleMax *= 2.0f; // correction for ADC analog
|
||||||
//if (dmType == 4) micSampleMax *= 16.0f; // correction for I2S Line-In
|
//if (dmType == 4) micSampleMax *= 16.0f; // correction for I2S Line-In
|
||||||
if (dmType == 5) micSampleMax *= 2.0f; // correction for PDM
|
if (dmType == 5) micSampleMax *= 2.0f; // correction for PDM
|
||||||
if (dmType == 4) { // I2S Line-In. This is a dirty trick to make sound pressure look interesting for line-in (which doesn't have "sound pressure" as its not a microphone)
|
if (dmType == 4) { // I2S Line-In. This is a dirty trick to make sound pressure look interesting for line-in (which doesn't have "sound pressure" as it is not a microphone)
|
||||||
micSampleMax /= 11.0f; // reduce to max 128
|
micSampleMax /= 11.0f; // reduce to max 128
|
||||||
micSampleMax *= micSampleMax; // blow up --> max 16000
|
micSampleMax *= micSampleMax; // blow up --> max 16000
|
||||||
}
|
}
|
||||||
// make sure we are in expected ranges
|
// make sure we are in expected ranges
|
||||||
if(micSampleMax <= sampleMin) return 0.0f;
|
if(micSampleMax <= sampleRangeMin) return 0.0f;
|
||||||
if(micSampleMax >= sampleMax) return 255.0f;
|
if(micSampleMax >= sampleRangeMax) return 255.0f;
|
||||||
|
|
||||||
// apply logarithmic scaling
|
// apply logarithmic scaling
|
||||||
float scaledvalue = logf(micSampleMax);
|
float scaledvalue = logf(micSampleMax);
|
||||||
scaledvalue = (scaledvalue - logMinSample) / (logMaxSample - logMinSample); // 0...1
|
scaledvalue = (scaledvalue - logMinSample) / (logMaxSample - logMinSample); // 0...1
|
||||||
return fminf(fmaxf(256.0*scaledvalue, 0), 255.0); // scaled value
|
return fminf(fmaxf(256.0f*scaledvalue, 0.0f), 255.0f); // scaled value
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1765,7 +1765,7 @@ class AudioReactive : public Usermod {
|
|||||||
if (millis()- last_UDPTime >= AUDIOSYNC_IDLE_MS) sequenceOK = true; // receiver timed out - resync needed
|
if (millis()- last_UDPTime >= AUDIOSYNC_IDLE_MS) sequenceOK = true; // receiver timed out - resync needed
|
||||||
if (lastReceivedFormat < 2) sequenceOK = true; // first or second V2 packet - accept anything (prevents delay when re-enabling AR)
|
if (lastReceivedFormat < 2) sequenceOK = true; // first or second V2 packet - accept anything (prevents delay when re-enabling AR)
|
||||||
if(audioSyncSequence == false) sequenceOK = true; // sequence checking disabled by user
|
if(audioSyncSequence == false) sequenceOK = true; // sequence checking disabled by user
|
||||||
if((sequenceOK == false) && (receivedPacket.frameCounter != 0)) { // always accept "0" - its the legacy value
|
if((sequenceOK == false) && (receivedPacket.frameCounter != 0)) { // always accept "0" as the legacy value
|
||||||
DEBUGSR_PRINTF("Skipping audio frame out of order or duplicated - %u vs %u\n", lastFrameCounter, receivedPacket.frameCounter);
|
DEBUGSR_PRINTF("Skipping audio frame out of order or duplicated - %u vs %u\n", lastFrameCounter, receivedPacket.frameCounter);
|
||||||
return false; // reject out-of sequence frame
|
return false; // reject out-of sequence frame
|
||||||
}
|
}
|
||||||
@@ -1920,7 +1920,7 @@ class AudioReactive : public Usermod {
|
|||||||
* You can use it to initialize variables, sensors or similar.
|
* You can use it to initialize variables, sensors or similar.
|
||||||
* It is called *AFTER* readFromConfig()
|
* It is called *AFTER* readFromConfig()
|
||||||
*/
|
*/
|
||||||
void setup()
|
void setup() override
|
||||||
{
|
{
|
||||||
disableSoundProcessing = true; // just to be sure
|
disableSoundProcessing = true; // just to be sure
|
||||||
if (!initDone) {
|
if (!initDone) {
|
||||||
@@ -2173,7 +2173,7 @@ class AudioReactive : public Usermod {
|
|||||||
* connected() is called every time the WiFi is (re)connected
|
* connected() is called every time the WiFi is (re)connected
|
||||||
* Use it to initialize network interfaces
|
* Use it to initialize network interfaces
|
||||||
*/
|
*/
|
||||||
void connected()
|
void connected() override
|
||||||
{
|
{
|
||||||
if (udpSyncConnected) { // clean-up: if open, close old UDP sync connection
|
if (udpSyncConnected) { // clean-up: if open, close old UDP sync connection
|
||||||
udpSyncConnected = false;
|
udpSyncConnected = false;
|
||||||
@@ -2213,7 +2213,7 @@ class AudioReactive : public Usermod {
|
|||||||
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
|
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
|
||||||
* Instead, use a timer check as shown here.
|
* Instead, use a timer check as shown here.
|
||||||
*/
|
*/
|
||||||
void loop()
|
void loop() override
|
||||||
{
|
{
|
||||||
static unsigned long lastUMRun = millis();
|
static unsigned long lastUMRun = millis();
|
||||||
|
|
||||||
@@ -2291,7 +2291,7 @@ class AudioReactive : public Usermod {
|
|||||||
if (lastUMRun == 0) userloopDelay=0; // startup - don't have valid data from last run.
|
if (lastUMRun == 0) userloopDelay=0; // startup - don't have valid data from last run.
|
||||||
|
|
||||||
#if defined(SR_DEBUG)
|
#if defined(SR_DEBUG)
|
||||||
// complain when audio userloop has been delayed for long time. Currently we need userloop running between 500 and 1500 times per second.
|
// complain when audio userloop has been delayed for long time. Currently, we need userloop running between 500 and 1500 times per second.
|
||||||
// softhack007 disabled temporarily - avoid serial console spam with MANY LEDs and low FPS
|
// softhack007 disabled temporarily - avoid serial console spam with MANY LEDs and low FPS
|
||||||
//if ((userloopDelay > /*23*/ 65) && !disableSoundProcessing && (audioSyncEnabled == AUDIOSYNC_NONE)) {
|
//if ((userloopDelay > /*23*/ 65) && !disableSoundProcessing && (audioSyncEnabled == AUDIOSYNC_NONE)) {
|
||||||
//DEBUG_PRINTF("[AR userLoop] hiccup detected -> was inactive for last %d millis!\n", userloopDelay);
|
//DEBUG_PRINTF("[AR userLoop] hiccup detected -> was inactive for last %d millis!\n", userloopDelay);
|
||||||
@@ -2350,7 +2350,7 @@ class AudioReactive : public Usermod {
|
|||||||
unsigned timeElapsed = (millis() - last_UDPTime);
|
unsigned timeElapsed = (millis() - last_UDPTime);
|
||||||
unsigned maxReadSamples = timeElapsed / AR_UDP_AVG_SEND_RATE; // estimate how many packets arrived since last receive
|
unsigned maxReadSamples = timeElapsed / AR_UDP_AVG_SEND_RATE; // estimate how many packets arrived since last receive
|
||||||
maxReadSamples = max(1U, min(maxReadSamples, 20U)); // constrain to [1...20] = max 380ms drop
|
maxReadSamples = max(1U, min(maxReadSamples, 20U)); // constrain to [1...20] = max 380ms drop
|
||||||
// check if we should purge the the receiving queue
|
// check if we should purge the receiving queue
|
||||||
switch (audioSyncPurge) {
|
switch (audioSyncPurge) {
|
||||||
case 0: maxReadSamples = 1; break; // never drop packets, unless new connection or timed out
|
case 0: maxReadSamples = 1; break; // never drop packets, unless new connection or timed out
|
||||||
case 2: maxReadSamples = AR_UDP_FLUSH_ALL; break; // always drop - process latest packet only
|
case 2: maxReadSamples = AR_UDP_FLUSH_ALL; break; // always drop - process latest packet only
|
||||||
@@ -2447,12 +2447,12 @@ class AudioReactive : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_MoonModules_WLED_) && defined(WLEDMM_FASTPATH)
|
#if defined(_MoonModules_WLED_) && defined(WLEDMM_FASTPATH)
|
||||||
void loop2(void) {
|
void loop2(void) override {
|
||||||
loop();
|
loop();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool getUMData(um_data_t **data)
|
bool getUMData(um_data_t **data) override
|
||||||
{
|
{
|
||||||
if (!data || !enabled) return false; // no pointer provided by caller or not enabled -> exit
|
if (!data || !enabled) return false; // no pointer provided by caller or not enabled -> exit
|
||||||
*data = um_data;
|
*data = um_data;
|
||||||
@@ -2461,7 +2461,7 @@ class AudioReactive : public Usermod {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
void onUpdateBegin(bool init)
|
void onUpdateBegin(bool init) override
|
||||||
{
|
{
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
fftTime = sampleTime = filterTime = 0;
|
fftTime = sampleTime = filterTime = 0;
|
||||||
@@ -2550,7 +2550,7 @@ class AudioReactive : public Usermod {
|
|||||||
* handleButton() can be used to override default button behaviour. Returning true
|
* handleButton() can be used to override default button behaviour. Returning true
|
||||||
* will prevent button working in a default way.
|
* will prevent button working in a default way.
|
||||||
*/
|
*/
|
||||||
bool handleButton(uint8_t b) {
|
bool handleButton(uint8_t b) override {
|
||||||
yield();
|
yield();
|
||||||
// crude way of determining if audio input is analog
|
// crude way of determining if audio input is analog
|
||||||
// better would be for AudioSource to implement getType()
|
// better would be for AudioSource to implement getType()
|
||||||
@@ -2573,7 +2573,7 @@ class AudioReactive : public Usermod {
|
|||||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||||
* Below it is shown how this could be used for e.g. a light sensor
|
* Below it is shown how this could be used for e.g. a light sensor
|
||||||
*/
|
*/
|
||||||
void addToJsonInfo(JsonObject& root)
|
void addToJsonInfo(JsonObject& root) override
|
||||||
{
|
{
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
char myStringBuffer[16]; // buffer for snprintf() - not used yet on 8266
|
char myStringBuffer[16]; // buffer for snprintf() - not used yet on 8266
|
||||||
@@ -2760,7 +2760,7 @@ class AudioReactive : public Usermod {
|
|||||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||||
* Values in the state object may be modified by connected clients
|
* Values in the state object may be modified by connected clients
|
||||||
*/
|
*/
|
||||||
void addToJsonState(JsonObject& root)
|
void addToJsonState(JsonObject& root) override
|
||||||
{
|
{
|
||||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||||
JsonObject usermod = root[FPSTR(_name)];
|
JsonObject usermod = root[FPSTR(_name)];
|
||||||
@@ -2775,7 +2775,7 @@ class AudioReactive : public Usermod {
|
|||||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||||
* Values in the state object may be modified by connected clients
|
* Values in the state object may be modified by connected clients
|
||||||
*/
|
*/
|
||||||
void readFromJsonState(JsonObject& root)
|
void readFromJsonState(JsonObject& root) override
|
||||||
{
|
{
|
||||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||||
bool prevEnabled = enabled;
|
bool prevEnabled = enabled;
|
||||||
@@ -2829,8 +2829,7 @@ class AudioReactive : public Usermod {
|
|||||||
*
|
*
|
||||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
*/
|
*/
|
||||||
void addToConfig(JsonObject& root)
|
void addToConfig(JsonObject& root) override {
|
||||||
{
|
|
||||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||||
top[FPSTR(_enabled)] = enabled;
|
top[FPSTR(_enabled)] = enabled;
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
@@ -2901,8 +2900,7 @@ class AudioReactive : public Usermod {
|
|||||||
*
|
*
|
||||||
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
|
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
|
||||||
*/
|
*/
|
||||||
bool readFromConfig(JsonObject& root)
|
bool readFromConfig(JsonObject& root) override {
|
||||||
{
|
|
||||||
JsonObject top = root[FPSTR(_name)];
|
JsonObject top = root[FPSTR(_name)];
|
||||||
bool configComplete = !top.isNull();
|
bool configComplete = !top.isNull();
|
||||||
|
|
||||||
@@ -2974,7 +2972,7 @@ class AudioReactive : public Usermod {
|
|||||||
if (initDone) {
|
if (initDone) {
|
||||||
if ((audioSource != nullptr) && (oldDMType != dmType)) errorFlag = ERR_REBOOT_NEEDED; // changing mic type requires reboot
|
if ((audioSource != nullptr) && (oldDMType != dmType)) errorFlag = ERR_REBOOT_NEEDED; // changing mic type requires reboot
|
||||||
if ( (audioSource != nullptr) && (enabled==true)
|
if ( (audioSource != nullptr) && (enabled==true)
|
||||||
&& ((oldI2SsdPin != i2ssdPin) || (oldI2SsdPin != i2ssdPin) || (oldI2SckPin != i2sckPin)) ) errorFlag = ERR_REBOOT_NEEDED; // changing mic pins requires reboot
|
&& ((oldI2SsdPin != i2ssdPin) || (oldI2SwsPin != i2swsPin) || (oldI2SckPin != i2sckPin)) ) errorFlag = ERR_REBOOT_NEEDED; // changing mic pins requires reboot
|
||||||
if ((audioSource != nullptr) && (oldI2SmclkPin != mclkPin)) errorFlag = ERR_REBOOT_NEEDED; // changing MCLK pin requires reboot
|
if ((audioSource != nullptr) && (oldI2SmclkPin != mclkPin)) errorFlag = ERR_REBOOT_NEEDED; // changing MCLK pin requires reboot
|
||||||
if ((oldDMType != dmType) && (oldDMType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing from analog mic requires power cycle
|
if ((oldDMType != dmType) && (oldDMType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing from analog mic requires power cycle
|
||||||
if ((oldDMType != dmType) && (dmType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing to analog mic requires power cycle
|
if ((oldDMType != dmType) && (dmType == 0)) errorFlag = ERR_POWEROFF_NEEDED; // changing to analog mic requires power cycle
|
||||||
@@ -2984,8 +2982,7 @@ class AudioReactive : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void appendConfigData()
|
void appendConfigData() override {
|
||||||
{
|
|
||||||
oappend(SET_F("ux='AudioReactive';")); // ux = shortcut for Audioreactive - fingers crossed that "ux" isn't already used as JS var, html post parameter or css style
|
oappend(SET_F("ux='AudioReactive';")); // ux = shortcut for Audioreactive - fingers crossed that "ux" isn't already used as JS var, html post parameter or css style
|
||||||
oappend(SET_F("uxp=ux+':digitalmic:pin[]';")); // uxp = shortcut for AudioReactive:digitalmic:pin[]
|
oappend(SET_F("uxp=ux+':digitalmic:pin[]';")); // uxp = shortcut for AudioReactive:digitalmic:pin[]
|
||||||
oappend(SET_F("addInfo(ux+':help',0,'<button onclick=\"location.href="https://mm.kno.wled.ge/soundreactive/Sound-Settings"\" type=\"button\">?</button>');"));
|
oappend(SET_F("addInfo(ux+':help',0,'<button onclick=\"location.href="https://mm.kno.wled.ge/soundreactive/Sound-Settings"\" type=\"button\">?</button>');"));
|
||||||
@@ -3264,10 +3261,10 @@ class AudioReactive : public Usermod {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
* getId() allows you to optionally give your V2 usermod a unique ID (please define it in const.h!).
|
||||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||||
*/
|
*/
|
||||||
uint16_t getId()
|
uint16_t getId() override
|
||||||
{
|
{
|
||||||
return USERMOD_ID_AUDIOREACTIVE;
|
return USERMOD_ID_AUDIOREACTIVE;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user