@@ -120,14 +120,14 @@ class VUMeter
120120 //
121121 // Draw i-th pixel in row y
122122
123- void DrawVUPixels (std::shared_ptr<GFXBase> pGFXChannel , int i, int yVU, int fadeBy = 0 , const CRGBPalette16 * pPalette = nullptr )
123+ virtual void DrawVUPixels (std::vector<std:: shared_ptr<GFXBase>> & GFX , int i, int yVU, int fadeBy = 0 , const CRGBPalette16 * pPalette = nullptr )
124124 {
125125 if (g_Analyzer.MicMode () == PeakData::PCREMOTE)
126126 pPalette = &vuPaletteBlue;
127127
128- int xHalf = pGFXChannel ->width ()/2 ;
129- pGFXChannel ->setPixel (xHalf-i-1 , yVU, ColorFromPalette (pPalette ? *pPalette : vu_gpGreen, i*(256 /xHalf)).fadeToBlackBy (fadeBy));
130- pGFXChannel ->setPixel (xHalf+i, yVU, ColorFromPalette (pPalette ? *pPalette : vu_gpGreen, i*(256 /xHalf)).fadeToBlackBy (fadeBy));
128+ int xHalf = GFX[ 0 ] ->width ()/2 ;
129+ GFX[ 0 ] ->setPixel (xHalf-i-1 , yVU, ColorFromPalette (pPalette ? *pPalette : vu_gpGreen, i*(256 /xHalf)).fadeToBlackBy (fadeBy));
130+ GFX[ 0 ] ->setPixel (xHalf+i, yVU, ColorFromPalette (pPalette ? *pPalette : vu_gpGreen, i*(256 /xHalf)).fadeToBlackBy (fadeBy));
131131 }
132132
133133
@@ -140,25 +140,25 @@ class VUMeter
140140
141141 public:
142142
143- inline void EraseVUMeter (std::shared_ptr<GFXBase> pGFXChannel , int start, int yVU) const
143+ virtual inline void EraseVUMeter (std::vector<std:: shared_ptr<GFXBase>> & GFX , int start, int yVU) const
144144 {
145- int xHalf = pGFXChannel ->width ()/2 ;
145+ int xHalf = GFX[ 0 ] ->width ()/2 ;
146146 for (int i = start; i <= xHalf; i++)
147147 {
148- pGFXChannel ->setPixel (xHalf-i, yVU, CRGB::Black);
149- pGFXChannel ->setPixel (xHalf-1 +i, yVU, CRGB::Black);
148+ GFX[ 0 ] ->setPixel (xHalf-i, yVU, CRGB::Black);
149+ GFX[ 0 ] ->setPixel (xHalf-1 +i, yVU, CRGB::Black);
150150 }
151151 }
152152
153- void DrawVUMeter (std::shared_ptr<GFXBase> pGFXChannel , int yVU, const CRGBPalette16 * pPalette = nullptr )
153+ virtual void DrawVUMeter (std::vector<std:: shared_ptr<GFXBase>> & GFX , int yVU = 0 , const CRGBPalette16 * pPalette = nullptr )
154154 {
155155 const int MAX_FADE = 256 ;
156156
157- int xHalf = pGFXChannel ->width ()/2 -1 ;
157+ int xHalf = GFX[ 0 ] ->width ()/2 -1 ;
158158 int bars = g_Analyzer._VURatioFade / 2.0 * xHalf;
159159 bars = min (bars, xHalf);
160160
161- EraseVUMeter (pGFXChannel , bars, yVU);
161+ EraseVUMeter (GFX , bars, yVU);
162162
163163 if (bars >= iPeakVUy)
164164 {
@@ -173,21 +173,74 @@ class VUMeter
173173 if (iPeakVUy > 1 )
174174 {
175175 int fade = MAX_FADE * (millis () - msPeakVU) / (float ) MS_PER_SECOND * 2 ;
176- DrawVUPixels (pGFXChannel , iPeakVUy, yVU, fade);
177- DrawVUPixels (pGFXChannel , iPeakVUy-1 , yVU, fade);
176+ DrawVUPixels (GFX , iPeakVUy, yVU, fade);
177+ DrawVUPixels (GFX , iPeakVUy-1 , yVU, fade);
178178 }
179179
180180 for (int i = 0 ; i < bars; i++)
181- DrawVUPixels (pGFXChannel , i, yVU, i > bars ? 255 : 0 , pPalette);
181+ DrawVUPixels (GFX , i, yVU, i > bars ? 255 : 0 , pPalette);
182182 }
183183};
184184
185+ class VUMeterVertical : public VUMeter
186+ {
187+ private:
188+ virtual inline void EraseVUMeter (std::vector<std::shared_ptr<GFXBase>> & GFX, int start, int yVU) const
189+ {
190+ for (int i = start; i <= GFX[0 ]->width (); i++)
191+ for (auto & device : GFX)
192+ device->setPixel (i, yVU, CRGB::Black);
193+ }
194+
195+ // DrawVUPixels
196+ //
197+ // Draw i-th pixel in row y
198+
199+ virtual void DrawVUPixels (std::vector<std::shared_ptr<GFXBase>> & GFX, int i, int yVU, int fadeBy = 0 , const CRGBPalette16 * pPalette = nullptr ) override
200+ {
201+ for (auto & device : GFX)
202+ device->setPixel (i, yVU, ColorFromPalette (pPalette ? *pPalette : vu_gpGreen, i*256 /GFX[0 ]->width ()).fadeToBlackBy (fadeBy));
203+ }
204+
205+ public:
206+ void DrawVUMeter (std::vector<std::shared_ptr<GFXBase>> & GFX, int yVU = 0 , const CRGBPalette16 * pPalette = nullptr )
207+ {
208+ const int MAX_FADE = 256 ;
209+
210+ int size = GFX[0 ]->width ();
211+ int bars = g_Analyzer._VURatioFade / 2.0 * size;
212+ bars = min (bars, size);
213+
214+ EraseVUMeter (GFX, bars, yVU);
215+
216+ if (bars >= iPeakVUy)
217+ {
218+ msPeakVU = millis ();
219+ iPeakVUy = bars;
220+ }
221+ else if (millis () - msPeakVU > MS_PER_SECOND / 2 )
222+ {
223+ iPeakVUy = 0 ;
224+ }
225+
226+ if (iPeakVUy > 1 )
227+ {
228+ int fade = MAX_FADE * (millis () - msPeakVU) / (float ) MS_PER_SECOND * 2 ;
229+ DrawVUPixels (GFX, iPeakVUy, yVU, fade);
230+ DrawVUPixels (GFX, iPeakVUy-1 , yVU, fade);
231+ }
232+
233+ for (int i = 0 ; i < bars; i++)
234+ DrawVUPixels (GFX, i, yVU, i > bars ? 255 : 0 , pPalette);
235+ }
236+ };
237+
185238class VUMeterEffect : virtual public VUMeter, public LEDStripEffect
186239{
187240public:
188241 virtual void Draw () override
189242 {
190- DrawVUMeter (g (), 0 );
243+ DrawVUMeter (g_ptrSystem-> EffectManager (). GetBaseGraphics (), 0 );
191244 }
192245
193246 VUMeterEffect () : LEDStripEffect(EFFECT_STRIP_VUMETER, " VUMeter" )
@@ -205,6 +258,28 @@ class VUMeterEffect : virtual public VUMeter, public LEDStripEffect
205258 }
206259};
207260
261+ class VUMeterVerticalEffect : virtual public VUMeterVertical, public LEDStripEffect
262+ {
263+ public:
264+ virtual void Draw () override
265+ {
266+ DrawVUMeter (g_ptrSystem->EffectManager ().GetBaseGraphics (), 0 );
267+ }
268+
269+ VUMeterVerticalEffect () : LEDStripEffect(EFFECT_STRIP_VUMETER_VERTICAL, " Vertical VUMeter" )
270+ {
271+ }
272+
273+ VUMeterVerticalEffect (const JsonObjectConst& jsonObject)
274+ : LEDStripEffect(jsonObject)
275+ {
276+ }
277+
278+ bool SerializeToJSON (JsonObject& jsonObject) override
279+ {
280+ return true ;
281+ }
282+ };
208283// SpectrumAnalyzerEffect
209284//
210285// An effect that draws an audio spectrum analyzer on a matrix. It is assumed that the
@@ -779,4 +854,64 @@ class SpectrumBarEffect : public LEDStripEffect, public BeatEffectBase
779854 }
780855};
781856
857+ // AudioSpikeEffect [MATRIX EFFECT]
858+ //
859+ // Simply displays the raw audio sample buffer as a waveform
860+
861+ class AudioSpikeEffect : public LEDStripEffect
862+ {
863+ protected:
864+
865+ public:
866+
867+ AudioSpikeEffect (const String & pszFriendlyName)
868+ : LEDStripEffect(EFFECT_MATRIX_AUDIOSPIKE, pszFriendlyName)
869+ {
870+ }
871+
872+ AudioSpikeEffect (const JsonObjectConst& jsonObject)
873+ : LEDStripEffect(jsonObject)
874+ {
875+ }
876+
877+ virtual bool SerializeToJSON (JsonObject& jsonObject) override
878+ {
879+ StaticJsonDocument<LEDStripEffect::_jsonSize> jsonDoc;
880+
881+ JsonObject root = jsonDoc.to <JsonObject>();
882+ LEDStripEffect::SerializeToJSON (root);
883+
884+ assert (!jsonDoc.overflowed ());
885+ return jsonObject.set (jsonDoc.as <JsonObjectConst>());
886+ }
887+
888+ virtual size_t DesiredFramesPerSecond () const override
889+ {
890+ return 60 ;
891+ }
892+
893+ virtual void Draw () override
894+ {
895+ fadeAllChannelsToBlackBy (50 );
896+
897+ static int colorOffset = 0 ;
898+ colorOffset+= 4 ;
899+
900+ static int offset = 2 ;
901+
902+ const int16_t * data = g_Analyzer.GetSampleBuffer ();
903+ int lastY = map (data[offset], 0 , 2500 , 0 , MATRIX_HEIGHT);
904+ for (int32_t x = 0 ; x < MATRIX_WIDTH; ++x)
905+ {
906+ byte y1 = map (data[offset+x], 0 , 2500 , 0 , MATRIX_HEIGHT);
907+ CRGB color = ColorFromPalette (spectrumBasicColors, (y1 * 4 ) + colorOffset, 255 , NOBLEND);
908+ g ()->drawLine (x, lastY, x+1 , y1, color);
909+ lastY = y1;
910+ }
911+ offset += MATRIX_WIDTH;
912+ if (offset + MATRIX_WIDTH > g_Analyzer.GetSampleBufferSize ())
913+ offset = 2 ;
914+ }
915+ };
916+
782917#endif
0 commit comments