@@ -1050,7 +1050,7 @@ class AudioReactive : public Usermod {
10501050 // new "V2" audiosync struct - 44 Bytes
10511051 struct __attribute__ ((packed)) audioSyncPacket { // WLEDMM "packed" ensures that there are no additional gaps
10521052 char header[6 ]; // 06 Bytes offset 0
1053- uint8_t gap1 [2 ]; // gap added by compiler: 02 Bytes, offset 6
1053+ uint8_t pressure [2 ]; // 02 Bytes, offset 6 - sound pressure as fixed point (8bit integer, 8bit fraction)
10541054 float sampleRaw; // 04 Bytes offset 8 - either "sampleRaw" or "rawSampleAgc" depending on soundAgc setting
10551055 float sampleSmth; // 04 Bytes offset 12 - either "sampleAvg" or "sampleAgc" depending on soundAgc setting
10561056 uint8_t samplePeak; // 01 Bytes offset 16 - 0 no peak; >=1 peak detected. In future, this will also provide peak Magnitude
@@ -1065,8 +1065,8 @@ class AudioReactive : public Usermod {
10651065 struct audioSyncPacket_v1 {
10661066 char header[6 ]; // 06 Bytes
10671067 uint8_t myVals[32 ]; // 32 Bytes
1068- int sampleAgc; // 04 Bytes
1069- int sampleRaw; // 04 Bytes
1068+ int32_t sampleAgc; // 04 Bytes
1069+ int32_t sampleRaw; // 04 Bytes
10701070 float sampleAvg; // 04 Bytes
10711071 bool samplePeak; // 01 Bytes
10721072 uint8_t fftResult[16 ]; // 16 Bytes
@@ -1602,6 +1602,14 @@ class AudioReactive : public Usermod {
16021602 transmitData.fftResult [i] = fftResult[i];
16031603 }
16041604
1605+ // WLEDMM transmit soundPressure as 16 bit fixed point
1606+ uint32_t pressure16bit = max (0 .0f , soundPressure) * 256 .0f ; // convert to fixed point, remove negative values
1607+ uint16_t pressInt = pressure16bit / 256 ; // integer part
1608+ uint16_t pressFract = pressure16bit % 256 ; // faction part
1609+ if (pressInt > 255 ) pressInt = 255 ; // saturation at 255
1610+ transmitData.pressure [0 ] = (uint8_t )pressInt;
1611+ transmitData.pressure [1 ] = (uint8_t )pressFract;
1612+
16051613 transmitData.FFT_Magnitude = my_magnitude;
16061614 transmitData.FFT_MajorPeak = FFT_MajorPeak;
16071615
@@ -1622,30 +1630,33 @@ class AudioReactive : public Usermod {
16221630
16231631 bool decodeAudioData (int packetSize, uint8_t *fftBuff) {
16241632 if ((0 == packetSize) || (nullptr == fftBuff)) return false ; // sanity check
1625- audioSyncPacket *receivedPacket = reinterpret_cast <audioSyncPacket*>(fftBuff);
1633+ // audioSyncPacket *receivedPacket = reinterpret_cast<audioSyncPacket*>(fftBuff);
1634+ audioSyncPacket receivedPacket;
1635+ memset (&receivedPacket, 0 , sizeof (receivedPacket)); // start clean
1636+ memcpy (&receivedPacket, fftBuff, min ((unsigned )packetSize, (unsigned )sizeof (receivedPacket))); // don't violate alignment - thanks @willmmiles
16261637
16271638 // validate sequence, discard out-of-sequence packets
16281639 static uint8_t lastFrameCounter = 0 ;
16291640 // add info for UI
1630- if ((receivedPacket-> frameCounter > 0 ) && (lastFrameCounter > 0 )) receivedFormat = 3 ; // v2+
1641+ if ((receivedPacket. frameCounter > 0 ) && (lastFrameCounter > 0 )) receivedFormat = 3 ; // v2+
16311642 else receivedFormat = 2 ; // v2
16321643 // check sequence
16331644 bool sequenceOK = false ;
1634- if (receivedPacket-> frameCounter > lastFrameCounter) sequenceOK = true ; // sequence OK
1635- if ((lastFrameCounter < 12 ) && (receivedPacket-> frameCounter > 248 )) sequenceOK = false ; // prevent sequence "roll-back" due to late packets (1->254)
1636- if ((lastFrameCounter > 248 ) && (receivedPacket-> frameCounter < 12 )) sequenceOK = true ; // handle roll-over (255 -> 0)
1645+ if (receivedPacket. frameCounter > lastFrameCounter) sequenceOK = true ; // sequence OK
1646+ if ((lastFrameCounter < 12 ) && (receivedPacket. frameCounter > 248 )) sequenceOK = false ; // prevent sequence "roll-back" due to late packets (1->254)
1647+ if ((lastFrameCounter > 248 ) && (receivedPacket. frameCounter < 12 )) sequenceOK = true ; // handle roll-over (255 -> 0)
16371648 if (audioSyncSequence == false ) sequenceOK = true ; // sequence checking disabled by user
1638- if ((sequenceOK == false ) && (receivedPacket-> frameCounter != 0 )) { // always accept "0" - its the legacy value
1639- DEBUGSR_PRINTF (" Skipping audio frame out of order or duplicated - %u vs %u\n " , lastFrameCounter, receivedPacket-> frameCounter );
1649+ if ((sequenceOK == false ) && (receivedPacket. frameCounter != 0 )) { // always accept "0" - its the legacy value
1650+ DEBUGSR_PRINTF (" Skipping audio frame out of order or duplicated - %u vs %u\n " , lastFrameCounter, receivedPacket. frameCounter );
16401651 return false ; // reject out-of sequence frame
16411652 }
16421653 else {
1643- lastFrameCounter = receivedPacket-> frameCounter ;
1654+ lastFrameCounter = receivedPacket. frameCounter ;
16441655 }
16451656
16461657 // update samples for effects
1647- volumeSmth = fmaxf (receivedPacket-> sampleSmth , 0 .0f );
1648- volumeRaw = fmaxf (receivedPacket-> sampleRaw , 0 .0f );
1658+ volumeSmth = fmaxf (receivedPacket. sampleSmth , 0 .0f );
1659+ volumeRaw = fmaxf (receivedPacket. sampleRaw , 0 .0f );
16491660#ifdef ARDUINO_ARCH_ESP32
16501661 // update internal samples
16511662 sampleRaw = volumeRaw;
@@ -1658,18 +1669,26 @@ class AudioReactive : public Usermod {
16581669 // If it's true already, then the animation still needs to respond.
16591670 autoResetPeak ();
16601671 if (!samplePeak) {
1661- samplePeak = receivedPacket-> samplePeak >0 ? true :false ;
1672+ samplePeak = receivedPacket. samplePeak >0 ? true :false ;
16621673 if (samplePeak) timeOfPeak = millis ();
16631674 // userVar1 = samplePeak;
16641675 }
16651676 // These values are only computed by ESP32
1666- for (int i = 0 ; i < NUM_GEQ_CHANNELS; i++) fftResult[i] = receivedPacket-> fftResult [i];
1667- my_magnitude = fmaxf (receivedPacket-> FFT_Magnitude , 0 .0f );
1677+ for (int i = 0 ; i < NUM_GEQ_CHANNELS; i++) fftResult[i] = receivedPacket. fftResult [i];
1678+ my_magnitude = fmaxf (receivedPacket. FFT_Magnitude , 0 .0f );
16681679 FFT_Magnitude = my_magnitude;
1669- FFT_MajorPeak = constrain (receivedPacket->FFT_MajorPeak , 1 .0f , 11025 .0f ); // restrict value to range expected by effects
1670- soundPressure = volumeSmth; // substitute - V2 format does not (yet) include this value
1671- agcSensitivity = 128 .0f ; // substitute - V2 format does not (yet) include this value
1672- zeroCrossingCount = receivedPacket->zeroCrossingCount ;
1680+ FFT_MajorPeak = constrain (receivedPacket.FFT_MajorPeak , 1 .0f , 11025 .0f ); // restrict value to range expected by effects
1681+ agcSensitivity = 128 .0f ; // substitute - V2 format does not include this value
1682+ zeroCrossingCount = receivedPacket.zeroCrossingCount ;
1683+
1684+ // WLEDMM extract soundPressure
1685+ if ((receivedPacket.pressure [0 ] != 0 ) || (receivedPacket.pressure [1 ] != 0 )) {
1686+ // found something in gap "reserved2"
1687+ soundPressure = float (receivedPacket.pressure [1 ]) / 256 .0f ; // fractional part
1688+ soundPressure += float (receivedPacket.pressure [0 ]); // integer part
1689+ } else {
1690+ soundPressure = volumeSmth; // fallback
1691+ }
16731692
16741693 return true ;
16751694 }
@@ -1786,36 +1805,23 @@ class AudioReactive : public Usermod {
17861805 um_data->u_type [4 ] = UMT_FLOAT;
17871806 um_data->u_data [5 ] = &my_magnitude; // used (New)
17881807 um_data->u_type [5 ] = UMT_FLOAT;
1789- #ifdef ARDUINO_ARCH_ESP32
17901808 um_data->u_data [6 ] = &maxVol; // assigned in effect function from UI element!!! (Puddlepeak, Ripplepeak, Waterfall)
17911809 um_data->u_type [6 ] = UMT_BYTE;
17921810 um_data->u_data [7 ] = &binNum; // assigned in effect function from UI element!!! (Puddlepeak, Ripplepeak, Waterfall)
17931811 um_data->u_type [7 ] = UMT_BYTE;
1812+ #ifdef ARDUINO_ARCH_ESP32
17941813 um_data->u_data [8 ] = &FFT_MajPeakSmth; // new
17951814 um_data->u_type [8 ] = UMT_FLOAT;
1796- um_data->u_data [9 ] = &soundPressure; // used (New)
1797- um_data->u_type [9 ] = UMT_FLOAT;
1798- um_data->u_data [10 ] = &agcSensitivity; // used (New)
1799- um_data->u_type [10 ] = UMT_FLOAT;
1800- um_data->u_data [11 ] = &zeroCrossingCount;
1801- um_data->u_type [11 ] = UMT_UINT16;
18021815#else
1803- // ESP8266
1804- // See https://github.com/MoonModules/WLED/pull/60#issuecomment-1666972133 for explanation of these alternative sources of data
1805-
1806- um_data->u_data [6 ] = &maxVol; // assigned in effect function from UI element!!! (Puddlepeak, Ripplepeak, Waterfall)
1807- um_data->u_type [6 ] = UMT_BYTE;
1808- um_data->u_data [7 ] = &binNum; // assigned in effect function from UI element!!! (Puddlepeak, Ripplepeak, Waterfall)
1809- um_data->u_type [7 ] = UMT_BYTE;
1810- um_data->u_data [8 ] = &FFT_MajorPeak; // new - substitute for FFT_MajPeakSmth
1816+ um_data->u_data [8 ] = &FFT_MajorPeak; // substitute for 8266
18111817 um_data->u_type [8 ] = UMT_FLOAT;
1812- um_data->u_data [9 ] = &volumeSmth; // used (New) - substitute for soundPressure
1818+ #endif
1819+ um_data->u_data [9 ] = &soundPressure; // used (New)
18131820 um_data->u_type [9 ] = UMT_FLOAT;
1814- um_data->u_data [10 ] = &agcSensitivity; // used (New) - dummy value (128 => 50%)
1821+ um_data->u_data [10 ] = &agcSensitivity; // used (New) - dummy value on 8266
18151822 um_data->u_type [10 ] = UMT_FLOAT;
1816- um_data->u_data [11 ] = &zeroCrossingCount;
1823+ um_data->u_data [11 ] = &zeroCrossingCount; // for auto playlist usermod
18171824 um_data->u_type [11 ] = UMT_UINT16;
1818- #endif
18191825 }
18201826
18211827#ifdef ARDUINO_ARCH_ESP32
@@ -2201,7 +2207,7 @@ class AudioReactive : public Usermod {
22012207 volumeSmth =0 .0f ;
22022208 volumeRaw =0 ;
22032209 my_magnitude = 0.1 ; FFT_Magnitude = 0.01 ; FFT_MajorPeak = 2 ;
2204- soundPressure = 1 .0f ;
2210+ soundPressure = 1 .0f ;
22052211 agcSensitivity = 64 .0f ;
22062212#ifdef ARDUINO_ARCH_ESP32
22072213 multAgc = 1 ;
0 commit comments