prepare for merge with upstream
- prepare for merging upstream --> audiorective files should stay the same after merging! - makuna just release NeoPixelBus 2.7.1 -> use for "V4" build
This commit is contained in:
@@ -268,7 +268,7 @@ build_flagsV4 = -g
|
|||||||
;;; V4.4.x libraries (without LOROL_LITTLEFS; with newer NeoPixelBus)
|
;;; V4.4.x libraries (without LOROL_LITTLEFS; with newer NeoPixelBus)
|
||||||
lib_depsV4 =
|
lib_depsV4 =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
https://github.com/Makuna/NeoPixelBus.git#master @ 2.7.0 ;; NPB 2.6.9 tends to crash whith IDF V4.4.3 -> use latest NeoPixelBus dev version instead
|
https://github.com/Makuna/NeoPixelBus.git#master @ 2.7.1 ;; NPB 2.6.9 tends to crash whith IDF V4.4.3 -> use latest NeoPixelBus 2.7.1 instead
|
||||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||||
|
|
||||||
[esp32s2]
|
[esp32s2]
|
||||||
@@ -310,7 +310,7 @@ build_flags = -g
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
;; currently we need the latest NeoPixelBus dev version, because it contains important bugfixes for -S3
|
;; currently we need the latest NeoPixelBus dev version, because it contains important bugfixes for -S3
|
||||||
https://github.com/Makuna/NeoPixelBus.git#master @ 2.7.0
|
https://github.com/Makuna/NeoPixelBus.git#master @ 2.7.1
|
||||||
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
https://github.com/pbolduc/AsyncTCP.git @ 1.2.0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,16 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MIC_LOGGER) || defined(FFT_SAMPLING_LOG)
|
||||||
|
#define PLOT_PRINT(x) DEBUGOUT.print(x)
|
||||||
|
#define PLOT_PRINTLN(x) DEBUGOUT.println(x)
|
||||||
|
#define PLOT_PRINTF(x...) DEBUGOUT.printf(x)
|
||||||
|
#else
|
||||||
|
#define PLOT_PRINT(x)
|
||||||
|
#define PLOT_PRINTLN(x)
|
||||||
|
#define PLOT_PRINTF(x...)
|
||||||
|
#endif
|
||||||
|
|
||||||
// use audio source class (ESP32 specific)
|
// use audio source class (ESP32 specific)
|
||||||
#include "audio_source.h"
|
#include "audio_source.h"
|
||||||
constexpr i2s_port_t I2S_PORT = I2S_NUM_0; // I2S port to use (do not change !)
|
constexpr i2s_port_t I2S_PORT = I2S_NUM_0; // I2S port to use (do not change !)
|
||||||
@@ -137,6 +147,8 @@ static void autoResetPeak(void); // peak auto-reset function
|
|||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
// some prototypes, to ensure consistent interfaces
|
// some prototypes, to ensure consistent interfaces
|
||||||
|
static float mapf(float x, float in_min, float in_max, float out_min, float out_max); // map function for float
|
||||||
|
static float fftAddAvg(int from, int to); // average of several FFT result bins
|
||||||
void FFTcode(void * parameter); // audio processing task: read samples, run FFT, fill GEQ channels from FFT results
|
void FFTcode(void * parameter); // audio processing task: read samples, run FFT, fill GEQ channels from FFT results
|
||||||
static void runMicFilter(uint16_t numSamples, float *sampleBuffer); // pre-filtering of raw samples (band-pass)
|
static void runMicFilter(uint16_t numSamples, float *sampleBuffer); // pre-filtering of raw samples (band-pass)
|
||||||
static void postProcessFFTResults(bool noiseGateOpen, int numberOfChannels); // post-processing and post-amp of GEQ channels
|
static void postProcessFFTResults(bool noiseGateOpen, int numberOfChannels); // post-processing and post-amp of GEQ channels
|
||||||
@@ -228,7 +240,7 @@ constexpr uint16_t samplesFFT_2 = 256; // meaningfull part of FFT resul
|
|||||||
// the following are observed values, supported by a bit of "educated guessing"
|
// the following are observed values, supported by a bit of "educated guessing"
|
||||||
//#define FFT_DOWNSCALE 0.65f // 20kHz - downscaling factor for FFT results - "Flat-Top" window @20Khz, old freq channels
|
//#define FFT_DOWNSCALE 0.65f // 20kHz - downscaling factor for FFT results - "Flat-Top" window @20Khz, old freq channels
|
||||||
#define FFT_DOWNSCALE 0.46f // downscaling factor for FFT results - for "Flat-Top" window @22Khz, new freq channels
|
#define FFT_DOWNSCALE 0.46f // downscaling factor for FFT results - for "Flat-Top" window @22Khz, new freq channels
|
||||||
#define LOG_256 5.54517744 // log2(256)
|
#define LOG_256 5.54517744f // log(256)
|
||||||
|
|
||||||
// These are the input and output vectors. Input vectors receive computed results from FFT.
|
// These are the input and output vectors. Input vectors receive computed results from FFT.
|
||||||
static float vReal[samplesFFT] = {0.0f}; // FFT sample inputs / freq output - these are our raw result bins
|
static float vReal[samplesFFT] = {0.0f}; // FFT sample inputs / freq output - these are our raw result bins
|
||||||
@@ -247,6 +259,7 @@ static float windowWeighingFactors[samplesFFT] = {0.0f};
|
|||||||
// lib_deps += https://github.com/blazoncek/arduinoFFT.git
|
// lib_deps += https://github.com/blazoncek/arduinoFFT.git
|
||||||
#endif
|
#endif
|
||||||
#include <arduinoFFT.h>
|
#include <arduinoFFT.h>
|
||||||
|
|
||||||
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
|
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
|
||||||
static ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, windowWeighingFactors);
|
static ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, windowWeighingFactors);
|
||||||
#else
|
#else
|
||||||
@@ -488,10 +501,10 @@ static void runMicFilter(uint16_t numSamples, float *sampleBuffer) // p
|
|||||||
constexpr float alpha = 0.0225f; // 80hz
|
constexpr float alpha = 0.0225f; // 80hz
|
||||||
//constexpr float alpha = 0.01693f;// 60hz
|
//constexpr float alpha = 0.01693f;// 60hz
|
||||||
// high frequency cutoff parameter
|
// high frequency cutoff parameter
|
||||||
//constexpr float beta1 = 0.75; // 11Khz
|
//constexpr float beta1 = 0.75f; // 11Khz
|
||||||
//constexpr float beta1 = 0.82; // 15Khz
|
//constexpr float beta1 = 0.82f; // 15Khz
|
||||||
//constexpr float beta1 = 0.8285; // 18Khz
|
//constexpr float beta1 = 0.8285f; // 18Khz
|
||||||
constexpr float beta1 = 0.85; // 20Khz
|
constexpr float beta1 = 0.85f; // 20Khz
|
||||||
|
|
||||||
constexpr float beta2 = (1.0f - beta1) / 2.0;
|
constexpr float beta2 = (1.0f - beta1) / 2.0;
|
||||||
static float last_vals[2] = { 0.0f }; // FIR high freq cutoff filter
|
static float last_vals[2] = { 0.0f }; // FIR high freq cutoff filter
|
||||||
@@ -620,7 +633,6 @@ static void detectSamplePeak(void) {
|
|||||||
timeOfPeak = millis();
|
timeOfPeak = millis();
|
||||||
udpSamplePeak = true;
|
udpSamplePeak = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void autoResetPeak(void) {
|
static void autoResetPeak(void) {
|
||||||
@@ -724,7 +736,7 @@ class AudioReactive : public Usermod {
|
|||||||
// variables used by getSample() and agcAvg()
|
// variables used by getSample() and agcAvg()
|
||||||
int16_t micIn = 0; // Current sample starts with negative values and large values, which is why it's 16 bit signed
|
int16_t micIn = 0; // Current sample starts with negative values and large values, which is why it's 16 bit signed
|
||||||
double sampleMax = 0.0; // Max sample over a few seconds. Needed for AGC controler.
|
double sampleMax = 0.0; // Max sample over a few seconds. Needed for AGC controler.
|
||||||
double micLev = 0.0f; // Used to convert returned value to have '0' as minimum. A leveller
|
double micLev = 0.0; // Used to convert returned value to have '0' as minimum. A leveller
|
||||||
float expAdjF = 0.0f; // Used for exponential filter.
|
float expAdjF = 0.0f; // Used for exponential filter.
|
||||||
float sampleReal = 0.0f; // "sampleRaw" as float, to provide bits that are lost otherwise (before amplification by sampleGain or inputLevel). Needed for AGC.
|
float sampleReal = 0.0f; // "sampleRaw" as float, to provide bits that are lost otherwise (before amplification by sampleGain or inputLevel). Needed for AGC.
|
||||||
int16_t sampleRaw = 0; // Current sample. Must only be updated ONCE!!! (amplified mic value by sampleGain and inputLevel)
|
int16_t sampleRaw = 0; // Current sample. Must only be updated ONCE!!! (amplified mic value by sampleGain and inputLevel)
|
||||||
@@ -760,29 +772,29 @@ class AudioReactive : public Usermod {
|
|||||||
if (disableSoundProcessing && (!udpSyncConnected || ((audioSyncEnabled & 0x02) == 0))) return; // no audio availeable
|
if (disableSoundProcessing && (!udpSyncConnected || ((audioSyncEnabled & 0x02) == 0))) return; // no audio availeable
|
||||||
#ifdef MIC_LOGGER
|
#ifdef MIC_LOGGER
|
||||||
// Debugging functions for audio input and sound processing. Comment out the values you want to see
|
// Debugging functions for audio input and sound processing. Comment out the values you want to see
|
||||||
Serial.print("micReal:"); Serial.print(micDataReal); Serial.print("\t");
|
PLOT_PRINT("micReal:"); PLOT_PRINT(micDataReal); PLOT_PRINT("\t");
|
||||||
Serial.print("volumeSmth:"); Serial.print(volumeSmth); Serial.print("\t");
|
PLOT_PRINT("volumeSmth:"); PLOT_PRINT(volumeSmth); PLOT_PRINT("\t");
|
||||||
//Serial.print("volumeRaw:"); Serial.print(volumeRaw); Serial.print("\t");
|
//PLOT_PRINT("volumeRaw:"); PLOT_PRINT(volumeRaw); PLOT_PRINT("\t");
|
||||||
Serial.print("DC_Level:"); Serial.print(micLev); Serial.print("\t");
|
PLOT_PRINT("DC_Level:"); PLOT_PRINT(micLev); PLOT_PRINT("\t");
|
||||||
//Serial.print("sampleAgc:"); Serial.print(sampleAgc); Serial.print("\t");
|
//PLOT_PRINT("sampleAgc:"); PLOT_PRINT(sampleAgc); PLOT_PRINT("\t");
|
||||||
//Serial.print("sampleAvg:"); Serial.print(sampleAvg); Serial.print("\t");
|
//PLOT_PRINT("sampleAvg:"); PLOT_PRINT(sampleAvg); PLOT_PRINT("\t");
|
||||||
//Serial.print("sampleReal:"); Serial.print(sampleReal); Serial.print("\t");
|
//PLOT_PRINT("sampleReal:"); PLOT_PRINT(sampleReal); PLOT_PRINT("\t");
|
||||||
//Serial.print("micIn:"); Serial.print(micIn); Serial.print("\t");
|
//PLOT_PRINT("micIn:"); PLOT_PRINT(micIn); PLOT_PRINT("\t");
|
||||||
//Serial.print("sample:"); Serial.print(sample); Serial.print("\t");
|
//PLOT_PRINT("sample:"); PLOT_PRINT(sample); PLOT_PRINT("\t");
|
||||||
//Serial.print("sampleMax:"); Serial.print(sampleMax); Serial.print("\t");
|
//PLOT_PRINT("sampleMax:"); PLOT_PRINT(sampleMax); PLOT_PRINT("\t");
|
||||||
//Serial.print("samplePeak:"); Serial.print((samplePeak!=0) ? 128:0); Serial.print("\t");
|
//PLOT_PRINT("samplePeak:"); PLOT_PRINT((samplePeak!=0) ? 128:0); PLOT_PRINT("\t");
|
||||||
//Serial.print("multAgc:"); Serial.print(multAgc, 4); Serial.print("\t");
|
//PLOT_PRINT("multAgc:"); PLOT_PRINT(multAgc, 4); PLOT_PRINT("\t");
|
||||||
Serial.println();
|
PLOT_PRINTLN();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FFT_SAMPLING_LOG
|
#ifdef FFT_SAMPLING_LOG
|
||||||
#if 0
|
#if 0
|
||||||
for(int i=0; i<NUM_GEQ_CHANNELS; i++) {
|
for(int i=0; i<NUM_GEQ_CHANNELS; i++) {
|
||||||
Serial.print(fftResult[i]);
|
PLOT_PRINT(fftResult[i]);
|
||||||
Serial.print("\t");
|
PLOT_PRINT("\t");
|
||||||
}
|
}
|
||||||
Serial.println();
|
PLOT_PRINTLN();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// OPTIONS are in the following format: Description \n Option
|
// OPTIONS are in the following format: Description \n Option
|
||||||
//
|
//
|
||||||
@@ -808,20 +820,21 @@ class AudioReactive : public Usermod {
|
|||||||
if(fftResult[i] < minVal) minVal = fftResult[i];
|
if(fftResult[i] < minVal) minVal = fftResult[i];
|
||||||
}
|
}
|
||||||
for(int i = 0; i < NUM_GEQ_CHANNELS; i++) {
|
for(int i = 0; i < NUM_GEQ_CHANNELS; i++) {
|
||||||
Serial.print(i); Serial.print(":");
|
PLOT_PRINT(i); PLOT_PRINT(":");
|
||||||
Serial.printf("%04ld ", map(fftResult[i], 0, (scaleValuesFromCurrentMaxVal ? maxVal : defaultScalingFromHighValue), (mapValuesToPlotterSpace*i*scalingToHighValue)+0, (mapValuesToPlotterSpace*i*scalingToHighValue)+scalingToHighValue-1));
|
PLOT_PRINTF("%04ld ", map(fftResult[i], 0, (scaleValuesFromCurrentMaxVal ? maxVal : defaultScalingFromHighValue), (mapValuesToPlotterSpace*i*scalingToHighValue)+0, (mapValuesToPlotterSpace*i*scalingToHighValue)+scalingToHighValue-1));
|
||||||
}
|
}
|
||||||
if(printMaxVal) {
|
if(printMaxVal) {
|
||||||
Serial.printf("maxVal:%04d ", maxVal + (mapValuesToPlotterSpace ? 16*256 : 0));
|
PLOT_PRINTF("maxVal:%04d ", maxVal + (mapValuesToPlotterSpace ? 16*256 : 0));
|
||||||
}
|
}
|
||||||
if(printMinVal) {
|
if(printMinVal) {
|
||||||
Serial.printf("%04d:minVal ", minVal); // printed with value first, then label, so negative values can be seen in Serial Monitor but don't throw off y axis in Serial Plotter
|
PLOT_PRINTF("%04d:minVal ", minVal); // printed with value first, then label, so negative values can be seen in Serial Monitor but don't throw off y axis in Serial Plotter
|
||||||
}
|
}
|
||||||
if(mapValuesToPlotterSpace)
|
if(mapValuesToPlotterSpace)
|
||||||
Serial.printf("max:%04d ", (printMaxVal ? 17 : 16)*256); // print line above the maximum value we expect to see on the plotter to avoid autoscaling y axis
|
PLOT_PRINTF("max:%04d ", (printMaxVal ? 17 : 16)*256); // print line above the maximum value we expect to see on the plotter to avoid autoscaling y axis
|
||||||
else
|
else {
|
||||||
Serial.printf("max:%04d ", 256);
|
PLOT_PRINTF("max:%04d ", 256);
|
||||||
Serial.println();
|
}
|
||||||
|
PLOT_PRINTLN();
|
||||||
#endif // FFT_SAMPLING_LOG
|
#endif // FFT_SAMPLING_LOG
|
||||||
} // logAudio()
|
} // logAudio()
|
||||||
|
|
||||||
@@ -955,12 +968,7 @@ class AudioReactive : public Usermod {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//micLev = ((micLev * 8191.0f) + micDataReal) / 8192.0f; // takes a few seconds to "catch up" with the Mic Input
|
|
||||||
//if (useBandPassFilter)
|
|
||||||
// micLev += (micDataReal-micLev) / 8192.0f; // we expect some more fluctuations with mics that need pre-filtering
|
|
||||||
//else
|
|
||||||
micLev += (micDataReal-micLev) / 12288.0f;
|
micLev += (micDataReal-micLev) / 12288.0f;
|
||||||
|
|
||||||
if(micIn < micLev) micLev = ((micLev * 31.0f) + micDataReal) / 32.0f; // align MicLev to lowest input signal
|
if(micIn < micLev) micLev = ((micLev * 31.0f) + micDataReal) / 32.0f; // align MicLev to lowest input signal
|
||||||
|
|
||||||
micIn -= micLev; // Let's center it to 0 now
|
micIn -= micLev; // Let's center it to 0 now
|
||||||
@@ -1767,7 +1775,7 @@ class AudioReactive : public Usermod {
|
|||||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
JsonObject amic = top.createNestedObject(FPSTR(_analogmic));
|
JsonObject amic = top.createNestedObject(FPSTR(_analogmic));
|
||||||
amic["pin"] = audioPin;
|
amic["pin"] = audioPin;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject dmic = top.createNestedObject(FPSTR(_digitalmic));
|
JsonObject dmic = top.createNestedObject(FPSTR(_digitalmic));
|
||||||
dmic[F("type")] = dmType;
|
dmic[F("type")] = dmType;
|
||||||
@@ -1918,8 +1926,8 @@ class AudioReactive : public Usermod {
|
|||||||
#else
|
#else
|
||||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'', 'I2S Master CLK');"));
|
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',3,'', 'I2S Master CLK');"));
|
||||||
#endif
|
#endif
|
||||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',4,'I2C SDA',' ');"));
|
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',4,'', 'I2C SDA');"));
|
||||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',5,'I2C SCL',' ');"));
|
oappend(SET_F("addInfo('AudioReactive:digitalmic:pin[]',5,'', 'I2C SCL');"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -218,10 +218,15 @@ class I2SSource : public AudioSource {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
// example from espressif: https://github.com/espressif/esp-idf/blob/release/v4.4/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c
|
|
||||||
// This is an I2S PDM microphone, these microphones only use a clock and
|
// This is an I2S PDM microphone, these microphones only use a clock and
|
||||||
// data line, to make it simpler to debug, use the WS pin as CLK and SD
|
// data line, to make it simpler to debug, use the WS pin as CLK and SD pin as DATA
|
||||||
// pin as DATA
|
// example from espressif: https://github.com/espressif/esp-idf/blob/release/v4.4/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c
|
||||||
|
|
||||||
|
// note to self: PDM has known bugs on S3, and does not work on C3
|
||||||
|
// * S3: PDM sample rate only at 50% of expected rate: https://github.com/espressif/esp-idf/issues/9893
|
||||||
|
// * S3: I2S PDM has very low amplitude: https://github.com/espressif/esp-idf/issues/8660
|
||||||
|
// * C3: does not support PDM to PCM input. SoC would allow PDM RX, but there is no hardware to directly convert to PCM so it will not work. https://github.com/espressif/esp-idf/issues/8796
|
||||||
|
|
||||||
_config.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM); // Change mode to pdm if clock pin not provided. PDM is not supported on ESP32-S2. PDM RX not supported on ESP32-C3
|
_config.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM); // Change mode to pdm if clock pin not provided. PDM is not supported on ESP32-S2. PDM RX not supported on ESP32-C3
|
||||||
_config.channel_format =I2S_PDM_MIC_CHANNEL; // seems that PDM mono mode always uses left channel.
|
_config.channel_format =I2S_PDM_MIC_CHANNEL; // seems that PDM mono mode always uses left channel.
|
||||||
_config.use_apll = true; // experimental - use aPLL clock source to improve sampling quality
|
_config.use_apll = true; // experimental - use aPLL clock source to improve sampling quality
|
||||||
@@ -424,7 +429,7 @@ class ES7243 : public I2SSource {
|
|||||||
Wire.write((uint8_t)val);
|
Wire.write((uint8_t)val);
|
||||||
uint8_t i2cErr = Wire.endTransmission(); // i2cErr == 0 means OK
|
uint8_t i2cErr = Wire.endTransmission(); // i2cErr == 0 means OK
|
||||||
if (i2cErr != 0) {
|
if (i2cErr != 0) {
|
||||||
DEBUGSR_PRINTF("AR: ES7243 I2C write failed with error=%d (addr=0x%X, reg 0x%X, val 0x%X).\n", ES7243_ADDR, i2cErr, reg, val);
|
DEBUGSR_PRINTF("AR: ES7243 I2C write failed with error=%d (addr=0x%X, reg 0x%X, val 0x%X).\n", i2cErr, ES7243_ADDR, reg, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,73 @@
|
|||||||
# Audioreactive usermod
|
# Audioreactive usermod
|
||||||
|
|
||||||
This usermod allows controlling LEDs using audio input. Audio input can be either microphone or analog-in (AUX) using appropriate adapter.
|
This usermod allows controlling LEDs using audio input. Audio input can be either microphone or analog-in (AUX) using appropriate adapter.
|
||||||
Supported microphones range from analog (MAX4466, MAX9814, ...) to digital (INMP441, ICS-43434, ...).
|
Supported microphones range from cheap analog (MAX4466, MAX9814, ...) to high quality digital (INMP441, ICS-43434, ...) and dgital Line-In.
|
||||||
|
|
||||||
The usermod does audio processing and provides data structure that specially written effect can use.
|
The usermod does audio processing and provides data structure that specially written effect can use.
|
||||||
|
|
||||||
The usermod **does not** provide effects or draws anything to LED strip/matrix.
|
The usermod **does not** provide effects or draws anything to LED strip/matrix.
|
||||||
|
|
||||||
|
## Additional Documentation
|
||||||
|
This usermod is an evolution of [SR-WLED](https://github.com/atuline/WLED), and a lot of documentation and information can be found in the [SR-WLED wiki](https://github.com/atuline/WLED/wiki):
|
||||||
|
* [getting started with audio](https://github.com/atuline/WLED/wiki/First-Time-Setup#sound)
|
||||||
|
* [Sound settings](https://github.com/atuline/WLED/wiki/Sound-Settings) - similar to options on the usemod settings page in WLED.
|
||||||
|
* [Digital Audio](https://github.com/atuline/WLED/wiki/Digital-Microphone-Hookup)
|
||||||
|
* [Analog Audio](https://github.com/atuline/WLED/wiki/Analog-Audio-Input-Options)
|
||||||
|
* [UDP Sound sync](https://github.com/atuline/WLED/wiki/UDP-Sound-Sync)
|
||||||
|
|
||||||
|
|
||||||
|
## Supported MCUs
|
||||||
|
This audioreactive usermod works best on "classic ESP32" (dual core), and on ESP32-S3 which also has dual core and hardware floating point support.
|
||||||
|
|
||||||
|
It will compile succesfully for ESP32-S2 and ESP32-C3, however might not work well, as other WLED functions will become slow. Audio processing requires a lot of computing power, which can be problematic on smaller MCUs like -S2 and -C3.
|
||||||
|
|
||||||
|
Analog audio is only possible on "classic" ESP32, but not on other MCUs like ESP32-S3.
|
||||||
|
|
||||||
|
Currently ESP8266 is not supported, due to low speed and small RAM of this chip.
|
||||||
|
There are however plans to create a lightweight audioreactive for the 8266, with reduced features.
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add `-D USERMOD_AUDIOREACTIVE` to your PlatformIO environment as well as `arduinoFFT` to your `lib_deps`.
|
### using customised _arduinoFFT_ library for use with this usermod
|
||||||
|
Add `-D USERMOD_AUDIOREACTIVE` to your PlatformIO environment `build_flags`, as well as `https://github.com/blazoncek/arduinoFFT.git` to your `lib_deps`.
|
||||||
If you are not using PlatformIO (which you should) try adding `#define USERMOD_AUDIOREACTIVE` to *my_config.h* and make sure you have _arduinoFFT_ library downloaded and installed.
|
If you are not using PlatformIO (which you should) try adding `#define USERMOD_AUDIOREACTIVE` to *my_config.h* and make sure you have _arduinoFFT_ library downloaded and installed.
|
||||||
|
|
||||||
Customised _arduinoFFT_ library for use with this usermod can be found at https://github.com/blazoncek/arduinoFFT.git
|
Customised _arduinoFFT_ library for use with this usermod can be found at https://github.com/blazoncek/arduinoFFT.git
|
||||||
|
|
||||||
|
### using latest (develop) _arduinoFFT_ library
|
||||||
|
Alternatively, you can use the latest arduinoFFT development version.
|
||||||
|
ArduinoFFT `develop` library is slightly more accurate, and slighly faster than our customised library, however also needs additional 2kB RAM.
|
||||||
|
|
||||||
|
* `build_flags` = `-D USERMOD_AUDIOREACTIVE` `-D UM_AUDIOREACTIVE_USE_NEW_FFT`
|
||||||
|
* `lib_deps`= `https://github.com/kosme/arduinoFFT#develop @ 1.9.2`
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
All parameters are runtime configurable though some may require hard boot after change (I2S microphone or selected GPIOs).
|
All parameters are runtime configurable though some may require hard boot after change (I2S microphone or selected GPIOs).
|
||||||
|
|
||||||
If you want to define default GPIOs during compile time use the following (default values in parentheses):
|
If you want to define default GPIOs during compile time use the following addtional build_flags (default values in parentheses):
|
||||||
|
|
||||||
- `SR_DMTYPE=x` : defines digital microphone type: 0=analog, 1=generic I2S, 2=ES7243 I2S, 3=SPH0645 I2S, 4=generic I2S with master clock, 5=PDM I2S
|
- `-D SR_DMTYPE=x` : defines digital microphone type: 0=analog, 1=generic I2S (default), 2=ES7243 I2S, 3=SPH0645 I2S, 4=generic I2S with master clock, 5=PDM I2S
|
||||||
- `AUDIOPIN=x` : GPIO for analog microphone/AUX-in (36)
|
- `-D AUDIOPIN=x` : GPIO for analog microphone/AUX-in (36)
|
||||||
- `I2S_SDPIN=x` : GPIO for SD pin on digital mcrophone (32)
|
- `-D I2S_SDPIN=x` : GPIO for SD pin on digital microphone (32)
|
||||||
- `I2S_WSPIN=x` : GPIO for WS pin on digital mcrophone (15)
|
- `-D I2S_WSPIN=x` : GPIO for WS pin on digital microphone (15)
|
||||||
- `I2S_CKPIN=x` : GPIO for SCK pin on digital mcrophone (14)
|
- `-D I2S_CKPIN=x` : GPIO for SCK pin on digital microphone (14)
|
||||||
- `ES7243_SDAPIN` : GPIO for I2C SDA pin on ES7243 microphone (-1)
|
- `-D MCLK_PIN=x` : GPIO for master clock pin on digital Line-In boards (-1)
|
||||||
- `ES7243_SCLPIN` : GPIO for I2C SCL pin on ES7243 microphone (-1)
|
- `-D ES7243_SDAPIN` : GPIO for I2C SDA pin on ES7243 microphone (-1)
|
||||||
- `MCLK_PIN=x` : GPIO for master clock pin on digital mcrophone (-1)
|
- `-D ES7243_SCLPIN` : GPIO for I2C SCL pin on ES7243 microphone (-1)
|
||||||
|
|
||||||
**NOTE** Due to the fact that usermod uses I2S peripherial for analog audio sampling, use of analog *buttons* (i.e. potentiometers) is disabled while running this usermod with analog microphone.
|
**NOTE** Due to the fact that usermod uses I2S peripherial for analog audio sampling, use of analog *buttons* (i.e. potentiometers) is disabled while running this usermod with analog microphone.
|
||||||
|
|
||||||
|
### Advanced Compile-Time Options
|
||||||
|
You can use the following additional flags in your `build_flags`
|
||||||
|
* `-D SR_SQUELCH=x` : Default "squelch" setting (10)
|
||||||
|
* `-D SR_GAIN=x` : Default "gain" setting (60)
|
||||||
|
* `-D I2S_USE_RIGHT_CHANNEL`: Use RIGHT instead of LEFT channel (not recommended unless you strictly need this).
|
||||||
|
* `-D I2S_USE_16BIT_SAMPLES`: Use 16bit instead of 32bit for internal sample buffers. Reduces sampling quality, but frees some RAM ressources (not recommended unless you absolutely need this).
|
||||||
|
* `-D I2S_GRAB_ADC1_COMPLETELY`: Experimental: continously sample analog ADC microphone. Only effective on ESP32. WARNING this _will_ cause conflicts(lock-up) with any analogRead() call.
|
||||||
|
* `-D MIC_LOGGER` : (debugging) Logs samples from the microphone to serial USB. Use with serial plotter (Arduino IDE)
|
||||||
|
* `-D SR_DEBUG` : (debugging) Additional error diagnostics and debug info on serial USB.
|
||||||
|
|
||||||
## Release notes
|
## Release notes
|
||||||
|
|
||||||
2022-06 Ported from [soundreactive](https://github.com/atuline/WLED) by @blazoncek (AKA Blaz Kristan)
|
* 2022-06 Ported from [soundreactive WLED](https://github.com/atuline/WLED) - by @blazoncek (AKA Blaz Kristan) and the [SR-WLED team](https://github.com/atuline/WLED/wiki#sound-reactive-wled-fork-team).
|
||||||
|
* 2022-11 Updated to align with "[MoonModules/WLED](https://amg.wled.me)" audioreactive usermod - by @softhack007 (AKA Frank Möhle).
|
||||||
|
|||||||
Reference in New Issue
Block a user