Bugfix: make UDP sound sync work in AP mode
- the connected() method only get called once a Wifi STA connection is established. UDP Sound Sync should also work when sender is in AP Mode. - added a few comments that should help to understand the code structure.
This commit is contained in:
parent
36e10539e0
commit
77ace76e32
@ -24,7 +24,7 @@
|
|||||||
// #define MIC_LOGGER // MIC sampling & sound input debugging (serial plotter)
|
// #define MIC_LOGGER // MIC sampling & sound input debugging (serial plotter)
|
||||||
// #define FFT_SAMPLING_LOG // FFT result debugging
|
// #define FFT_SAMPLING_LOG // FFT result debugging
|
||||||
// #define SR_DEBUG // generic SR DEBUG messages
|
// #define SR_DEBUG // generic SR DEBUG messages
|
||||||
// #define NO_MIC_LOGGER // exclude MIC_LOGGER from SR_DEBUG
|
|
||||||
|
|
||||||
#ifdef SR_DEBUG
|
#ifdef SR_DEBUG
|
||||||
#define DEBUGSR_PRINT(x) Serial.print(x)
|
#define DEBUGSR_PRINT(x) Serial.print(x)
|
||||||
@ -103,6 +103,7 @@ static void autoResetPeak(void); // peak auto-reset function
|
|||||||
////////////////////
|
////////////////////
|
||||||
// Begin FFT Code //
|
// Begin FFT Code //
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
|
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
|
||||||
// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2
|
||||||
#define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc), and an a few other speedups
|
#define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc), and an a few other speedups
|
||||||
@ -135,7 +136,6 @@ static float windowWeighingFactors[samplesFFT] = {0.0f};
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try and normalize fftBin values to a max of 4096, so that 4096/16 = 256.
|
// Try and normalize fftBin values to a max of 4096, so that 4096/16 = 256.
|
||||||
// Oh, and bins 0,1,2 are no good, so we'll zero them out.
|
|
||||||
static float fftCalc[NUM_GEQ_CHANNELS] = {0.0f};
|
static float fftCalc[NUM_GEQ_CHANNELS] = {0.0f};
|
||||||
static float fftAvg[NUM_GEQ_CHANNELS] = {0.0f}; // Calculated frequency channel results, with smoothing (used if dynamics limiter is ON)
|
static float fftAvg[NUM_GEQ_CHANNELS] = {0.0f}; // Calculated frequency channel results, with smoothing (used if dynamics limiter is ON)
|
||||||
#ifdef SR_DEBUG
|
#ifdef SR_DEBUG
|
||||||
@ -172,7 +172,7 @@ static float fftAddAvg(int from, int to) {
|
|||||||
return result / float(to - from + 1);
|
return result / float(to - from + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FFT main code
|
// FFT main task
|
||||||
void FFTcode(void * parameter)
|
void FFTcode(void * parameter)
|
||||||
{
|
{
|
||||||
DEBUGSR_PRINT("FFT started on core: "); DEBUGSR_PRINTLN(xPortGetCoreID());
|
DEBUGSR_PRINT("FFT started on core: "); DEBUGSR_PRINTLN(xPortGetCoreID());
|
||||||
@ -417,6 +417,10 @@ static void autoResetPeak(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// usermod class //
|
||||||
|
////////////////////
|
||||||
|
|
||||||
//class name. Use something descriptive and leave the ": public Usermod" part :)
|
//class name. Use something descriptive and leave the ": public Usermod" part :)
|
||||||
class AudioReactive : public Usermod {
|
class AudioReactive : public Usermod {
|
||||||
|
|
||||||
@ -533,6 +537,10 @@ class AudioReactive : public Usermod {
|
|||||||
static const char UDP_SYNC_HEADER_v1[];
|
static const char UDP_SYNC_HEADER_v1[];
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// Debug support //
|
||||||
|
////////////////////
|
||||||
void logAudio()
|
void logAudio()
|
||||||
{
|
{
|
||||||
#ifdef MIC_LOGGER
|
#ifdef MIC_LOGGER
|
||||||
@ -604,6 +612,10 @@ class AudioReactive : public Usermod {
|
|||||||
} // logAudio()
|
} // logAudio()
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// Audio Processing //
|
||||||
|
//////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A "PI controller" multiplier to automatically adjust sound sensitivity.
|
* A "PI controller" multiplier to automatically adjust sound sensitivity.
|
||||||
*
|
*
|
||||||
@ -698,7 +710,7 @@ class AudioReactive : public Usermod {
|
|||||||
last_soundAgc = soundAgc;
|
last_soundAgc = soundAgc;
|
||||||
} // agcAvg()
|
} // agcAvg()
|
||||||
|
|
||||||
|
// post-processing and filtering of MIC sample (micDataReal) from FFTcode()
|
||||||
void getSample()
|
void getSample()
|
||||||
{
|
{
|
||||||
float sampleAdj; // Gain adjusted sample value
|
float sampleAdj; // Gain adjusted sample value
|
||||||
@ -793,6 +805,26 @@ class AudioReactive : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// UDP Sound Sync //
|
||||||
|
//////////////////////
|
||||||
|
|
||||||
|
// try to establish UDP sound sync connection
|
||||||
|
void connectUDPSoundSync(void) {
|
||||||
|
// This function tries to establish a UDP sync connection if needed
|
||||||
|
// necessary as we also want to transmit in "AP Mode", but the standard "connected()" callback only reacts on STA connection
|
||||||
|
static unsigned long last_connection_attempt = 0;
|
||||||
|
|
||||||
|
if ((audioSyncPort <= 0) || ((audioSyncEnabled & 0x03) == 0)) return; // Sound Sync not enabled
|
||||||
|
if (udpSyncConnected) return; // already connected
|
||||||
|
if (!(apActive || interfacesInited)) return; // neither AP nor other connections availeable
|
||||||
|
if (millis() - last_connection_attempt < 15000) return; // only try once in 15 seconds
|
||||||
|
|
||||||
|
// if we arrive here, we need a UDP connection but don't have one
|
||||||
|
last_connection_attempt = millis();
|
||||||
|
connected(); // try to start UDP
|
||||||
|
}
|
||||||
|
|
||||||
void transmitAudioData()
|
void transmitAudioData()
|
||||||
{
|
{
|
||||||
if (!udpSyncConnected) return;
|
if (!udpSyncConnected) return;
|
||||||
@ -820,12 +852,10 @@ class AudioReactive : public Usermod {
|
|||||||
return;
|
return;
|
||||||
} // transmitAudioData()
|
} // transmitAudioData()
|
||||||
|
|
||||||
|
|
||||||
static bool isValidUdpSyncVersion(const char *header) {
|
static bool isValidUdpSyncVersion(const char *header) {
|
||||||
return strncmp_P(header, PSTR(UDP_SYNC_HEADER), 6) == 0;
|
return strncmp_P(header, PSTR(UDP_SYNC_HEADER), 6) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool receiveAudioData() // check & process new data. return TRUE in case that new audio data was received.
|
bool receiveAudioData() // check & process new data. return TRUE in case that new audio data was received.
|
||||||
{
|
{
|
||||||
if (!udpSyncConnected) return false;
|
if (!udpSyncConnected) return false;
|
||||||
@ -875,6 +905,10 @@ class AudioReactive : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// usermod functions//
|
||||||
|
//////////////////////
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//Functions called by WLED or other usermods
|
//Functions called by WLED or other usermods
|
||||||
|
|
||||||
@ -967,6 +1001,7 @@ class AudioReactive : public Usermod {
|
|||||||
disableSoundProcessing = true;
|
disableSoundProcessing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enabled) connectUDPSoundSync();
|
||||||
initDone = true;
|
initDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,6 +1012,11 @@ class AudioReactive : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void connected()
|
void connected()
|
||||||
{
|
{
|
||||||
|
if (udpSyncConnected) { // clean-up: if open, close old UDP sync connection
|
||||||
|
udpSyncConnected = false;
|
||||||
|
fftUdp.stop();
|
||||||
|
}
|
||||||
|
|
||||||
if (audioSyncPort > 0 && (audioSyncEnabled & 0x03)) {
|
if (audioSyncPort > 0 && (audioSyncEnabled & 0x03)) {
|
||||||
#ifndef ESP8266
|
#ifndef ESP8266
|
||||||
udpSyncConnected = fftUdp.beginMulticast(IPAddress(239, 0, 0, 1), audioSyncPort);
|
udpSyncConnected = fftUdp.beginMulticast(IPAddress(239, 0, 0, 1), audioSyncPort);
|
||||||
@ -1079,6 +1119,8 @@ class AudioReactive : public Usermod {
|
|||||||
autoResetPeak(); // auto-reset sample peak after strip minShowDelay
|
autoResetPeak(); // auto-reset sample peak after strip minShowDelay
|
||||||
if (!udpSyncConnected) udpSamplePeak = false; // reset UDP samplePeak while UDP is unconnected
|
if (!udpSyncConnected) udpSamplePeak = false; // reset UDP samplePeak while UDP is unconnected
|
||||||
|
|
||||||
|
connectUDPSoundSync(); // ensure we have a connection - if needed
|
||||||
|
|
||||||
// UDP Microphone Sync - receive mode
|
// UDP Microphone Sync - receive mode
|
||||||
if ((audioSyncEnabled & 0x02) && udpSyncConnected) {
|
if ((audioSyncEnabled & 0x02) && udpSyncConnected) {
|
||||||
// Only run the audio listener code if we're in Receive mode
|
// Only run the audio listener code if we're in Receive mode
|
||||||
@ -1196,6 +1238,10 @@ class AudioReactive : public Usermod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// Settings and Info Page //
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||||
* 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.
|
||||||
|
Loading…
Reference in New Issue
Block a user