@@ -2335,31 +2335,18 @@ bool Audio::pauseResume() {
23352335bool  Audio::playChunk () {
23362336    //  If we've got data, try and pump it out..
23372337    int16_t  sample[2 ];
2338-     /*  VU Meter ************************************************************************************************************/ 
2339-     /*  По мотивам https://github.com/schreibfaul1/ESP32-audioI2S/pull/170/commits/6cce84217e5bc8f2f8925936affc84576932a29b */ 
2340-     uint8_t  maxl = 0 , maxr = 0 ; 
2341-     uint8_t  minl = 0xFF , minr = 0xFF ;
2342-     /* *********************************************************************************************************** VU Meter */ 
23432338    if (getBitsPerSample () == 8 ) {
23442339        if (getChannels () == 1 ) {
23452340            while (m_validSamples) {
23462341                uint8_t  x =  m_outBuff[m_curSample] & 0x00FF ;
23472342                uint8_t  y = (m_outBuff[m_curSample] & 0xFF00 ) >> 8 ;
23482343                sample[LEFTCHANNEL]  = x;
23492344                sample[RIGHTCHANNEL] = x;
2350-                 if (sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
2351-                 if (sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
2352-                 if (sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
2353-                 if (sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
23542345                while (1 ) {
23552346                    if (playSample (sample)) break ;
23562347                } //  Can't send?
23572348                sample[LEFTCHANNEL]  = y;
23582349                sample[RIGHTCHANNEL] = y;
2359-                 if (sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
2360-                 if (sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
2361-                 if (sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
2362-                 if (sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
23632350                while (1 ) {
23642351                    if (playSample (sample)) break ;
23652352                } //  Can't send?
@@ -2380,19 +2367,13 @@ bool Audio::playChunk() {
23802367                    sample[LEFTCHANNEL]  = xy;
23812368                    sample[RIGHTCHANNEL] = xy;
23822369                }
2383-                 if (sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
2384-                 if (sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
2385-                 if (sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
2386-                 if (sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
23872370                while (1 ) {
23882371                    if (playSample (sample)) break ;
23892372                } //  Can't send?
23902373                m_validSamples--;
23912374                m_curSample++;
23922375            }
23932376        }
2394-         vuLeft = maxl - minl;
2395-         vuRight = maxr - minr;
23962377        m_curSample = 0 ;
23972378        return  true ;
23982379    }
@@ -2401,10 +2382,6 @@ bool Audio::playChunk() {
24012382            while (m_validSamples) {
24022383                sample[LEFTCHANNEL]  = m_outBuff[m_curSample];
24032384                sample[RIGHTCHANNEL] = m_outBuff[m_curSample];
2404-                 if (sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
2405-                 if (sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
2406-                 if (sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
2407-                 if (sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
24082385                if (!playSample (sample)) {
24092386                    log_e (" can't send" 
24102387                    return  false ;
@@ -2425,17 +2402,11 @@ bool Audio::playChunk() {
24252402                    sample[LEFTCHANNEL] = xy;
24262403                    sample[RIGHTCHANNEL] = xy;
24272404                }
2428-                 if (sample[LEFTCHANNEL] > maxl ) maxl = sample[LEFTCHANNEL];
2429-                 if (sample[RIGHTCHANNEL] > maxr ) maxr = sample[RIGHTCHANNEL];
2430-                 if (sample[LEFTCHANNEL] < minl ) minl = sample[LEFTCHANNEL];
2431-                 if (sample[RIGHTCHANNEL] < minr ) minr = sample[RIGHTCHANNEL];
24322405                playSample (sample);
24332406                m_validSamples--;
24342407                m_curSample++;
24352408            }
24362409        }
2437-         vuLeft = maxl - minl;
2438-         vuRight = maxr - minr;
24392410        m_curSample = 0 ;
24402411        return  true ;
24412412    }
@@ -2444,10 +2415,86 @@ bool Audio::playChunk() {
24442415    stopSong ();
24452416    return  false ;
24462417}
2418+ 
2419+ /* 
2420+  * Shamelessly borrowed from @schreibfaul1 https://github.com/schreibfaul1/ESP32-audioI2S/blob/1296374fc513a6d6bfaa3b1ca08f6ba938b18d99/src/Audio.cpp#L5030 
2421+  */  
2422+ void  Audio::_computeVUlevel (int16_t  sample[2 ]) {
2423+   if (!config.store .vumeter ) return ;
2424+   static  uint8_t  sampleArray[2 ][4 ][8 ] = {0 };
2425+   static  uint8_t  cnt0 = 0 , cnt1 = 0 , cnt2 = 0 , cnt3 = 0 , cnt4 = 0 ;
2426+   static  bool     f_vu = false ;
2427+ 
2428+   auto  avg = [&](uint8_t * sampArr) { //  lambda, inner function, compute the average of 8 samples
2429+     uint16_t  av = 0 ;
2430+     for (int  i = 0 ; i < 8 ; i++) { av += sampArr[i]; }
2431+     return  av >> 3 ;
2432+   };
2433+ 
2434+   auto  largest = [&](uint8_t * sampArr) { //  lambda, inner function, compute the largest of 8 samples
2435+     uint16_t  maxValue = 0 ;
2436+     for (int  i = 0 ; i < 8 ; i++) {
2437+       if (maxValue < sampArr[i]) maxValue = sampArr[i];
2438+     }
2439+     return  maxValue;
2440+   };
2441+ 
2442+   if (cnt0 == 64 ) {
2443+     cnt0 = 0 ;
2444+     cnt1++;
2445+   }
2446+   if (cnt1 == 8 ) {
2447+     cnt1 = 0 ;
2448+     cnt2++;
2449+   }
2450+   if (cnt2 == 8 ) {
2451+     cnt2 = 0 ;
2452+     cnt3++;
2453+   }
2454+   if (cnt3 == 8 ) {
2455+     cnt3 = 0 ;
2456+     cnt4++;
2457+     f_vu = true ;
2458+   }
2459+   if (cnt4 == 8 ) { cnt4 = 0 ; }
2460+ 
2461+   if (!cnt0) { //  store every 64th sample in the array[0]
2462+     sampleArray[LEFTCHANNEL][0 ][cnt1] = abs (sample[LEFTCHANNEL] >> 7 );
2463+     sampleArray[RIGHTCHANNEL][0 ][cnt1] = abs (sample[RIGHTCHANNEL] >> 7 );
2464+   }
2465+   if (!cnt1) { //  store argest from 64 * 8 samples in the array[1]
2466+     sampleArray[LEFTCHANNEL][1 ][cnt2] = largest (sampleArray[LEFTCHANNEL][0 ]);
2467+     sampleArray[RIGHTCHANNEL][1 ][cnt2] = largest (sampleArray[RIGHTCHANNEL][0 ]);
2468+   }
2469+   if (!cnt2) { //  store avg from 64 * 8 * 8 samples in the array[2]
2470+     sampleArray[LEFTCHANNEL][2 ][cnt3] = largest (sampleArray[LEFTCHANNEL][1 ]);
2471+     sampleArray[RIGHTCHANNEL][2 ][cnt3] = largest (sampleArray[RIGHTCHANNEL][1 ]);
2472+   }
2473+   if (!cnt3) { //  store avg from 64 * 8 * 8 * 8 samples in the array[3]
2474+     sampleArray[LEFTCHANNEL][3 ][cnt4] = avg (sampleArray[LEFTCHANNEL][2 ]);
2475+     sampleArray[RIGHTCHANNEL][3 ][cnt4] = avg (sampleArray[RIGHTCHANNEL][2 ]);
2476+   }
2477+   if (f_vu) {
2478+     f_vu = false ;
2479+     vuLeft = avg (sampleArray[LEFTCHANNEL][3 ]);
2480+     if (vuLeft>config.vuThreshold )  config.vuThreshold  = vuLeft;
2481+     vuRight = avg (sampleArray[RIGHTCHANNEL][3 ]);
2482+     if (vuRight>config.vuThreshold ) config.vuThreshold  = vuRight;
2483+   }
2484+   cnt1++;
2485+ }
2486+ 
2487+ uint16_t  Audio::get_VUlevel (uint16_t  dimension){
2488+   if (!config.store .vumeter  || config.vuThreshold ==0 ) return  0 ;
2489+   uint8_t  L = map (vuLeft, config.vuThreshold , 0 , 0 , dimension);
2490+   uint8_t  R = map (vuRight, config.vuThreshold , 0 , 0 , dimension);
2491+   return  (L << 8 ) | R;
2492+ }
24472493// ---------------------------------------------------------------------------------------------------------------------
24482494
24492495void  Audio::loop () {
24502496    if (!m_f_running) {
2497+       vuLeft=0 ; vuRight=0 ;
24512498      vTaskDelay (2 );
24522499      return ;
24532500    }
@@ -4563,7 +4610,7 @@ bool Audio::playSample(int16_t sample[2]) {
45634610    sample = IIR_filterChain1 (sample);
45644611    sample = IIR_filterChain2 (sample);
45654612    // -------------------------------------------
4566- 
4613+      _computeVUlevel (sample); 
45674614    uint32_t  s32 = Gain (sample); //  vosample2lume;
45684615
45694616    if (m_f_internalDAC) {
0 commit comments