Skip to content

Commit

Permalink
Merge branch 'dev' into dev-ac-merge-a890823
Browse files Browse the repository at this point in the history
  • Loading branch information
THATDONFC committed Jul 11, 2022
2 parents 00138dd + 7476b71 commit e3a074d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 10 deletions.
30 changes: 24 additions & 6 deletions wled00/audio_reactive.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "audio_source.h"

static AudioSource *audioSource;
static volatile bool disableSoundProcessing = false; // if true, sound processing (FFT, filters, AGC) will be suspended. "volatile" as its shared between tasks.

// ALL AUDIO INPUT PINS DEFINED IN wled.h AND CONFIGURABLE VIA UI

Expand All @@ -36,10 +37,12 @@ static AudioSource *audioSource;
#define DEBUGSR_PRINTF(x...)
#endif

// #define MIC_LOGGER
// #define MIC_LOGGER // define for MIC input debugging (serial plotter)
// #define MIC_SAMPLING_LOG
// #define FFT_SAMPLING_LOG

// hackers corner
//#define USE_FILTER_OF_DEATH // experimental: use very strict filters, to make effects move really slow'n'smooth. Currently the result is lagging behind considerably
//#define MAJORPEAK_SUPPRESS_NOISE // define to activate a dirty hack that ignores the lowest + hightest FFT bins

constexpr i2s_port_t I2S_PORT = I2S_NUM_0;
Expand Down Expand Up @@ -238,7 +241,14 @@ void getSample() {
}
if (sampleMax < 0.5) sampleMax = 0.0;


#if defined(USE_FILTER_OF_DEATH)
// note to self: This causes lagging. Need a **second-order** exponential filter here.
sampleAvg = ((sampleAvg * 511.0) + sampleAdj) / 512.0;
#else
sampleAvg = ((sampleAvg * 15.0) + sampleAdj) / 16.0; // Smooth it out over the last 16 samples.
#endif


/*---------DEBUG---------*/
DEBUGSR_PRINT("\t"); DEBUGSR_PRINT(sample);
Expand Down Expand Up @@ -350,11 +360,17 @@ void agcAvg() {
// update global vars ONCE - multAgc, sampleAGC, rawSampleAgc
multAgc = multAgcTemp;
rawSampleAgc = 0.8 * tmpAgc + 0.2 * (float)rawSampleAgc;


// update smoothed AGC sample
#if defined(USE_FILTER_OF_DEATH)
sampleAgc = sampleAgc + (agcSampleSmooth[AGC_preset] * (1.0/32.0)) * (tmpAgc - sampleAgc);
#else
if(fabs(tmpAgc) < 1.0)
sampleAgc = 0.5 * tmpAgc + 0.5 * sampleAgc; // fast path to zero
else
sampleAgc = sampleAgc + agcSampleSmooth[AGC_preset] * (tmpAgc - sampleAgc); // smooth path
#endif

userVar0 = sampleAvg * 4;
if (userVar0 > 255) userVar0 = 255;
Expand Down Expand Up @@ -432,9 +448,11 @@ void FFTcode( void * parameter) {
delay(1); // DO NOT DELETE THIS LINE! It is needed to give the IDLE(0) task enough time and to keep the watchdog happy.
// taskYIELD(), yield(), vTaskDelay() and esp_task_wdt_feed() didn't seem to work.

// Only run the FFT computing code if we're not in Receive mode
if (audioSyncEnabled & (1 << 1))
// Only run the FFT computing code if we're not in "realime mode" or in Receive mode
if (disableSoundProcessing || (audioSyncEnabled & (1 << 1))) {
delay(7); // release CPU - delay is implemeted using vTaskDelay()
continue;
}
audioSource->getSamples(vReal, samplesFFT);

// old code - Last sample in vReal is our current mic sample
Expand Down Expand Up @@ -620,16 +638,16 @@ void FFTcode( void * parameter) {
void logAudio() {
#ifdef MIC_LOGGER

//Serial.print("micReal:"); Serial.print(micDataReal); Serial.print("\t");
Serial.print("micReal:"); Serial.print(micDataReal); Serial.print("\t");
//Serial.print("micData:"); Serial.print(micData); Serial.print("\t");
//Serial.print("micDataSm:"); Serial.print(micDataSm); Serial.print("\t");
//Serial.print("micIn:"); Serial.print(micIn); Serial.print("\t");
//Serial.print("micLev:"); Serial.print(micLev); Serial.print("\t");
//Serial.print("sample:"); Serial.print(sample); Serial.print("\t");
//Serial.print("sampleAvg:"); Serial.print(sampleAvg); Serial.print("\t");
Serial.print("sampleReal:"); Serial.print(sampleReal); Serial.print("\t");
//Serial.print("sampleReal:"); Serial.print(sampleReal); Serial.print("\t");
//Serial.print("sampleMax:"); Serial.print(sampleMax); Serial.print("\t");
Serial.print("multAgc:"); Serial.print(multAgc, 4); Serial.print("\t");
//Serial.print("multAgc:"); Serial.print(multAgc, 4); Serial.print("\t");
Serial.print("sampleAgc:"); Serial.print(sampleAgc); Serial.print("\t");
Serial.println(" ");

Expand Down
4 changes: 2 additions & 2 deletions wled00/audio_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class I2SSource : public AudioSource {
AudioSource(sampleRate, blockSize, lshift, mask) {
_config = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = _sampleRate,
.sample_rate = _sampleRate, // "narrowing conversion" warning can be ignored here - our _sampleRate is never bigger that INT32_MAX
.bits_per_sample = I2S_SAMPLE_RESOLUTION,
.channel_format = I2S_MIC_CHANNEL,
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
Expand Down Expand Up @@ -415,7 +415,7 @@ class I2SAdcSource : public I2SSource {
I2SSource(sampleRate, blockSize, lshift, mask){
_config = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),
.sample_rate = _sampleRate,
.sample_rate = _sampleRate, // "narrowing conversion" warning can be ignored here - our _sampleRate is never bigger that INT32_MAX
.bits_per_sample = I2S_SAMPLE_RESOLUTION,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
Expand Down
44 changes: 43 additions & 1 deletion wled00/usermod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

// This gets called once at boot. Do all initialization that doesn't depend on network here
void userSetup() {
disableSoundProcessing = true; // just to be safe
// Reset I2S peripheral for good measure
i2s_driver_uninstall(I2S_NUM_0);
periph_module_reset(PERIPH_I2S0_MODULE);
Expand Down Expand Up @@ -67,6 +68,8 @@ void userSetup() {
1, // Priority of the task
&FFT_Task, // Task handle
0); // Core where the task should run

disableSoundProcessing = false; // let it run
}

// This gets called every time WiFi is (re-)connected. Initialize own network interfaces here
Expand All @@ -76,7 +79,46 @@ void userConnected() {
// userLoop. You can use "if (WLED_CONNECTED)" to check for successful connection
void userLoop() {

if (!(audioSyncEnabled & (1 << 1))) { // Only run the sampling code IF we're not in Receive mode
// suspend local sound processing when "real time mode" is active (E131, UDP, ADALIGHT, ARTNET)
if ( (realtimeOverride == REALTIME_OVERRIDE_NONE)
&&( (realtimeMode == REALTIME_MODE_GENERIC)
||(realtimeMode == REALTIME_MODE_E131)
||(realtimeMode == REALTIME_MODE_UDP)
||(realtimeMode == REALTIME_MODE_ADALIGHT)
||(realtimeMode == REALTIME_MODE_ARTNET) ) )
{
#ifdef WLED_DEBUG
if ((disableSoundProcessing == false) && (audioSyncEnabled == 0)) { // we just switched to "disabled"
DEBUG_PRINTLN("[AS userLoop] realtime mode active - audio processing suspended.");
DEBUG_PRINTF( " RealtimeMode = %d; RealtimeOverride = %d\n", int(realtimeMode), int(realtimeOverride));
}
#endif
disableSoundProcessing = true;
} else {
#ifdef WLED_DEBUG
if ((disableSoundProcessing == true) && (audioSyncEnabled == 0)) { // we just switched to "disabled"
DEBUG_PRINTLN("[AS userLoop] realtime mode ended - audio processing resumed.");
DEBUG_PRINTF( " RealtimeMode = %d; RealtimeOverride = %d\n", int(realtimeMode), int(realtimeOverride));
}
#endif
if ((disableSoundProcessing == true) && (audioSyncEnabled == 0)) lastTime = millis(); // just left "realtime mode" - update timekeeping
disableSoundProcessing = false;
}

if (audioSyncEnabled & (1 << 1)) disableSoundProcessing = true; // make sure everything is disabled IF in audio Receive mode
if (audioSyncEnabled & (1 << 0)) disableSoundProcessing = false; // keep running audio IF we're in audio Transmit mode

int userloopDelay = int(millis() - lastTime);
if (lastTime == 0) userloopDelay=0; // startup - don't have valid data from last run.

if ((!disableSoundProcessing) && (!(audioSyncEnabled & (1 << 1)))) { // Only run the sampling code IF we're not in realtime mode and not in audio Receive mode
#ifdef WLED_DEBUG
// compain when audio userloop has been delayed for long. Currently we need userloop running between 500 and 1500 times per second.
if (userloopDelay > 23) { // should not happen. Expect lagging in SR effects if you see this mesage !!!
DEBUG_PRINTF("[AS userLoop] hickup detected -> was inactive for last %d millis!\n", int(millis() - lastTime));
}
#endif

lastTime = millis();
if (soundAgc > AGC_NUM_PRESETS) soundAgc = 0; // make sure that AGC preset is valid (to avoid array bounds violation)
getSample(); // Sample the microphone
Expand Down
2 changes: 1 addition & 1 deletion wled00/wled.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

// version code in format yymmddb (b = daily build)
#define VERSION 2203191
#define VERSION 2207111

//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG
Expand Down

0 comments on commit e3a074d

Please sign in to comment.