microphone profiles (frequency scaling)
- added user-selectable frequency profiles, to allow adjustments for different I2S microphones (including line-in) - additionally show "GEQ Input Level" as number in percent.
This commit is contained in:
@@ -62,6 +62,7 @@ static uint16_t attackTime = 80; // int: attack time in millisecond
|
||||
static uint16_t decayTime = 1400; // int: decay time in milliseconds. Default 1.40sec
|
||||
// user settable options for FFTResult scaling
|
||||
static uint8_t FFTScalingMode = 3; // 0 none; 1 optimized logarithmic; 2 optimized linear; 3 optimized sqare root
|
||||
static uint8_t pinkIndex = 0; // 0: default; 1: line-in; 2: IMNP441
|
||||
|
||||
//
|
||||
// AGC presets
|
||||
@@ -150,7 +151,12 @@ static unsigned long sampleTime = 0;
|
||||
#endif
|
||||
|
||||
// Table of multiplication factors so that we can even out the frequency response.
|
||||
static float fftResultPink[NUM_GEQ_CHANNELS] = { 1.70f, 1.71f, 1.73f, 1.78f, 1.68f, 1.56f, 1.55f, 1.63f, 1.79f, 1.62f, 1.80f, 2.06f, 2.47f, 3.35f, 6.83f, 9.55f };
|
||||
#define MAX_PINK 2 // 0 = standard, 1= line-in (pink moise only), 2 = IMNP441, ...
|
||||
static float fftResultPink[MAX_PINK+1][NUM_GEQ_CHANNELS] = {
|
||||
{ 1.70f, 1.71f, 1.73f, 1.78f, 1.68f, 1.56f, 1.55f, 1.63f, 1.79f, 1.62f, 1.80f, 2.06f, 2.47f, 3.35f, 6.83f, 9.55f }, // default from SR WLED
|
||||
{ 1.30f, 1.32f, 1.40f, 1.46f, 1.52f, 1.57f, 1.68f, 1.80f, 1.89f, 2.00f, 2.11f, 2.21f, 2.30f, 2.39f, 3.09f, 4.34f }, // pink noise adjustment only. Good for line-in when there is nomicrophone distortion
|
||||
{ 2.60f, 2.20f, 1.30f, 1.15f, 1.35f, 2.05f, 2.90f, 2.24f, 2.00f, 2.00f, 2.55f, 2.90f, 2.70f, 2.05f, 4.50f, 8.85f } // optimized for IMNP441
|
||||
};
|
||||
|
||||
// Create FFT object
|
||||
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
|
||||
@@ -307,11 +313,12 @@ void FFTcode(void * parameter)
|
||||
}
|
||||
|
||||
// post-processing of frequency channels (pink noise adjustment, AGC, smooting, scaling)
|
||||
if (pinkIndex > MAX_PINK) pinkIndex = MAX_PINK;
|
||||
for (int i=0; i < NUM_GEQ_CHANNELS; i++) {
|
||||
|
||||
if (sampleAvg > 1) { // noise gate open
|
||||
// Adjustment for frequency curves.
|
||||
fftCalc[i] *= fftResultPink[i];
|
||||
fftCalc[i] *= fftResultPink[pinkIndex][i];
|
||||
if (FFTScalingMode > 0) fftCalc[i] *= FFT_DOWNSCALE; // adjustment related to FFT windowing function
|
||||
// Manual linear adjustment of gain using sampleGain adjustment for different input types.
|
||||
fftCalc[i] *= soundAgc ? multAgc : ((float)sampleGain/40.0f * (float)inputLevel/128.0f + 1.0f/16.0f); //apply gain, with inputLevel adjustment
|
||||
@@ -1292,10 +1299,17 @@ class AudioReactive : public Usermod {
|
||||
if (enabled) {
|
||||
// Input Level Slider
|
||||
if (disableSoundProcessing == false) { // only show slider when audio processing is running
|
||||
if (soundAgc > 0)
|
||||
if (soundAgc > 0) {
|
||||
infoArr = user.createNestedArray(F("GEQ Input Level")); // if AGC is on, this slider only affects fftResult[] frequencies
|
||||
else
|
||||
// show slider value as a number
|
||||
float post_gain = (float)inputLevel/128.0f;
|
||||
if (post_gain < 1.0f) post_gain = ((post_gain -1.0f) * 0.8f) +1.0f;
|
||||
post_gain = roundf(post_gain * 100.0f);
|
||||
snprintf_P(myStringBuffer, 15, PSTR("%3.0f %%"), post_gain);
|
||||
infoArr.add(myStringBuffer);
|
||||
} else {
|
||||
infoArr = user.createNestedArray(F("Audio Input Level"));
|
||||
}
|
||||
uiDomString = F("<div class=\"slider\"><div class=\"sliderwrap il\"><input class=\"noslide\" onchange=\"requestJson({");
|
||||
uiDomString += FPSTR(_name);
|
||||
uiDomString += F(":{");
|
||||
@@ -1491,6 +1505,7 @@ class AudioReactive : public Usermod {
|
||||
|
||||
JsonObject freqScale = top.createNestedObject("Frequency");
|
||||
freqScale[F("Scale")] = FFTScalingMode;
|
||||
freqScale[F("Profile")] = pinkIndex;
|
||||
|
||||
JsonObject sync = top.createNestedObject("sync");
|
||||
sync[F("port")] = audioSyncPort;
|
||||
@@ -1539,6 +1554,7 @@ class AudioReactive : public Usermod {
|
||||
configComplete &= getJsonValue(top["dynamics"][F("Fall")], decayTime);
|
||||
|
||||
configComplete &= getJsonValue(top["Frequency"][F("Scale")], FFTScalingMode);
|
||||
configComplete &= getJsonValue(top["Frequency"][F("Profile")], pinkIndex);
|
||||
|
||||
configComplete &= getJsonValue(top["sync"][F("port")], audioSyncPort);
|
||||
configComplete &= getJsonValue(top["sync"][F("mode")], audioSyncEnabled);
|
||||
@@ -1581,6 +1597,11 @@ class AudioReactive : public Usermod {
|
||||
oappend(SET_F("addOption(dd,'Square Root (Energy)',3);"));
|
||||
oappend(SET_F("addOption(dd,'Logarithmic (Loudness)',1);"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','Frequency:Profile');"));
|
||||
oappend(SET_F("addOption(dd,'standard',0);"));
|
||||
oappend(SET_F("addOption(dd,'Line-In',1);"));
|
||||
oappend(SET_F("addOption(dd,'IMNP441',2);"));
|
||||
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','sync:mode');"));
|
||||
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||
oappend(SET_F("addOption(dd,'Send',1);"));
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2209061
|
||||
#define VERSION 2209081
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
|
||||
Reference in New Issue
Block a user