AR sound sync - make sequence checks user configurable
to support scenarios where several sending nodes are needed.
This commit is contained in:
@@ -111,6 +111,7 @@
|
|||||||
|
|
||||||
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 its 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 udpSyncConnected = false; // UDP connection status -> true if connected to multicast group
|
static bool udpSyncConnected = false; // UDP connection status -> true if connected to multicast group
|
||||||
|
|
||||||
#define NUM_GEQ_CHANNELS 16 // number of frequency channels. Don't change !!
|
#define NUM_GEQ_CHANNELS 16 // number of frequency channels. Don't change !!
|
||||||
@@ -1577,6 +1578,7 @@ class AudioReactive : public Usermod {
|
|||||||
if(receivedPacket->frameCounter > lastFrameCounter) sequenceOK = true; // sequence OK
|
if(receivedPacket->frameCounter > lastFrameCounter) sequenceOK = true; // sequence OK
|
||||||
if((lastFrameCounter < 12) && (receivedPacket->frameCounter > 248)) sequenceOK = false; // prevent sequence "roll-back" due to late packets (1->254)
|
if((lastFrameCounter < 12) && (receivedPacket->frameCounter > 248)) sequenceOK = false; // prevent sequence "roll-back" due to late packets (1->254)
|
||||||
if((lastFrameCounter > 248) && (receivedPacket->frameCounter < 12)) sequenceOK = true; // handle roll-over (255 -> 0)
|
if((lastFrameCounter > 248) && (receivedPacket->frameCounter < 12)) sequenceOK = true; // handle roll-over (255 -> 0)
|
||||||
|
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" - its 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
|
||||||
@@ -2415,7 +2417,10 @@ class AudioReactive : public Usermod {
|
|||||||
if (audioSyncEnabled && udpSyncConnected && (millis() - last_UDPTime < AUDIOSYNC_IDLE_MS)) {
|
if (audioSyncEnabled && udpSyncConnected && (millis() - last_UDPTime < AUDIOSYNC_IDLE_MS)) {
|
||||||
if (receivedFormat == 1) infoArr.add(F(" v1"));
|
if (receivedFormat == 1) infoArr.add(F(" v1"));
|
||||||
if (receivedFormat == 2) infoArr.add(F(" v2"));
|
if (receivedFormat == 2) infoArr.add(F(" v2"));
|
||||||
if (receivedFormat == 3) infoArr.add(F(" v2+"));
|
if (receivedFormat == 3) {
|
||||||
|
if (audioSyncSequence) infoArr.add(F(" v2+")); // Sequence checking enabled
|
||||||
|
else infoArr.add(F(" v2"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(WLED_DEBUG) || defined(SR_DEBUG) || defined(SR_STATS)
|
#if defined(WLED_DEBUG) || defined(SR_DEBUG) || defined(SR_STATS)
|
||||||
@@ -2567,6 +2572,7 @@ class AudioReactive : public Usermod {
|
|||||||
JsonObject sync = top.createNestedObject("sync");
|
JsonObject sync = top.createNestedObject("sync");
|
||||||
sync[F("port")] = audioSyncPort;
|
sync[F("port")] = audioSyncPort;
|
||||||
sync[F("mode")] = audioSyncEnabled;
|
sync[F("mode")] = audioSyncEnabled;
|
||||||
|
sync[F("check_sequence")] = audioSyncSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2635,6 +2641,7 @@ class AudioReactive : public Usermod {
|
|||||||
|
|
||||||
configComplete &= getJsonValue(top["sync"][F("port")], audioSyncPort);
|
configComplete &= getJsonValue(top["sync"][F("port")], audioSyncPort);
|
||||||
configComplete &= getJsonValue(top["sync"][F("mode")], audioSyncEnabled);
|
configComplete &= getJsonValue(top["sync"][F("mode")], audioSyncEnabled);
|
||||||
|
configComplete &= getJsonValue(top["sync"][F("check_sequence")], audioSyncSequence);
|
||||||
|
|
||||||
return configComplete;
|
return configComplete;
|
||||||
}
|
}
|
||||||
@@ -2813,7 +2820,12 @@ class AudioReactive : public Usermod {
|
|||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
oappend(SET_F("addOption(dd,'Receive or Local',6);")); // AUDIOSYNC_REC_PLUS
|
oappend(SET_F("addOption(dd,'Receive or Local',6);")); // AUDIOSYNC_REC_PLUS
|
||||||
#endif
|
#endif
|
||||||
oappend(SET_F("addInfo('AudioReactive:sync:mode',1,'<br> Sync audio data with other WLEDs');"));
|
// check_sequence: Receiver skips out-of-sequence packets when enabled
|
||||||
|
oappend(SET_F("dd=addDropdown('AudioReactive','sync:check_sequence');"));
|
||||||
|
oappend(SET_F("addOption(dd,'Off',0);"));
|
||||||
|
oappend(SET_F("addOption(dd,'On',1);"));
|
||||||
|
|
||||||
|
oappend(SET_F("addInfo('AudioReactive:sync:check_sequence',1,'<i>when receiving</i> ☾<br> Sync audio data with other WLEDs');")); // must append this to the last field of 'sync'
|
||||||
|
|
||||||
oappend(SET_F("addInfo('AudioReactive:digitalmic:type',1,'<i>requires reboot!</i>');")); // 0 is field type, 1 is actual field
|
oappend(SET_F("addInfo('AudioReactive:digitalmic:type',1,'<i>requires reboot!</i>');")); // 0 is field type, 1 is actual field
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|||||||
Reference in New Issue
Block a user