Conversation
…trip into pdpwopr
Pick up main
…trip into pdpwopr
| { | ||
| int iFan = random(0, NUM_FANS); | ||
| int passes = random(1, g_Analyzer._VURatio); | ||
| int passes = random(1, (int)g_Analyzer.VURatio()); |
There was a problem hiding this comment.
Sorry, not familiar with the term. What's wrong here?
There was a problem hiding this comment.
shadow variables are like when you have a variable named passes inside a lower scope that already has a variable named passes. This is legal, but unnecessarily confusing. (References always get the token of closest scope.
for (int i : eyes)
for (int i : more_eyes)
for (int i : still_more_eyes
if (something) return i;
print i;
The last two lines will always refer to something in still_more_eyes[]. It can lead to maintenance hassles. You decide to rename the second varible and 150 lines down you are writing to it and forget to change that reference. Now you're writing to the outer one.
It's nefarious enough that gcc has a collection of -Wshadow warning options.
There was a problem hiding this comment.
I get that, but I guess I just see it? Which variable is duplicated in an inner scope?
There was a problem hiding this comment.
i guess shadows are aliasing as opposed to a brightness alpha spectra
There was a problem hiding this comment.
@davepl It's passes. It's redefined in a for loop that compares its indexer variable with a passes that's defined in an outer context.
| { // reference them in g_Analyzer | ||
| }; | ||
| #ifndef NUM_BANDS | ||
| #define NUM_BANDS 16 // Default value for projects without audio |
There was a problem hiding this comment.
Consider describing why we need bands in a file named "sound" in a block "!ENABLE_AUDIO"
| static constexpr size_t _sampling_period_us = PERIOD_FROM_FREQ(SAMPLING_FREQUENCY); | ||
| static inline size_t SamplingPeriodMicros() | ||
| { | ||
| return (size_t)PERIOD_FROM_FREQ(SAMPLING_FREQUENCY); |
There was a problem hiding this comment.
P_F_F() is only used twice, and both in integer context. Why not just make it in inline function that's strongly typed?
| if (frameMax > _energyMaxEnv) | ||
| _energyMaxEnv = frameMax; | ||
| else | ||
| _energyMaxEnv = std::max(ENERGY_MIN_ENV, _energyMaxEnv * ENERGY_ENV_DECAY); |
There was a problem hiding this comment.
Is this block actually:
eME = std::max({E_M_E, frameMax, _eME * E_E_D});
There was a problem hiding this comment.
So much for passive voice.
"Please replace with the clearer, and possibly more efficent as we have a 'max' opcode, suggestion."
There was a problem hiding this comment.
I admit I haven't reasoned through all the code that determines frameMax to determine if what follows will ever happen, but the outcome of the current logic differs from std::max({_energyMaxEnv, frameMax, _energyMaxEnv * ENERGY_ENV_DECAY}) if frameMax is smaller than energyMaxEnv * ENERGY_ENV_DECAY.
There was a problem hiding this comment.
Ah, now that I can get behind. Thank you. The key isn't using the second max to enforce a maximum, it's to enforce that the decayed rate never falls below MIN_ENV. I saw "max" and was reading that this was computing a maximum of a big number. It's just the maximum of a small number. Got it.
Withdrawn.
| _vPeaks[i] = 0.0f; | ||
| float vNorm = _vPeaks[b] * invEnv; | ||
| if (vNorm > vMaxNorm) | ||
| vMaxNorm = vNorm; |
There was a problem hiding this comment.
Is this vMaxNorm = max_element(_vpeaks) * invEnv?
(Technically not as there are some differences in the overflow case, but I suspect if you're overflowing floats in this, you're living wrong.
| ESP_ERROR_CHECK( i2s_start(I2S_NUM_0) ); | ||
|
|
||
| #else | ||
| #elif ELECROW || USE_I2S_AUDIO |
There was a problem hiding this comment.
While you're in the mode to test all the things AND have your head around config, if you can figure out what "ELECTROW" really really means here and can push I2S_foo_PIN into that config file and OUT of this code, that'd be great. Similarly, if yo can fold this case and the MESMERIZER/SPECTRUM . I whacked one of three nearly identical copies of this, but lacked the confidence/background to get it down to one. I don't think they're really different enough to to be two different blocks just to set the pin number via pin_config block
| _vPeaks[i] = _Peaks._Level[i]; | ||
| float sum = 0.0f; | ||
| for (int i = 0; i < NUM_BANDS; i++) | ||
| sum += _vPeaks[i]; |
There was a problem hiding this comment.
Can this be done in one pass?
float sum = 0.0f;
for (int i = 0; i < NUM_BANDS; ++i) {
_vPeaks[i] = _Peaks._Level[i];
sum += _vPeaks[i];
}
| #elif USE_M5 | ||
| _MicMode = PeakData::M5; | ||
| #else | ||
| _MicMode = PeakData::MESMERIZERMIC; |
There was a problem hiding this comment.
Naming nit that's always bugged me: Is the else really "MESMERIZER" or is it "everything else"?
There was a problem hiding this comment.
It's really "setups that run analog audio to a GPIO rather than an I2S source". But that's usually a mesmerizer, unless it's an umbrella :-)
There was a problem hiding this comment.
In your garage, that may well be true. When someone else is trying to figure out what their prefab boad with a mic should map to or are soldering up a board of their own and trying to decide between an INMP441 or a MAX4466, it's probably not obvious to them that they need to send this code down the path named "mesmerizer" for an analog mic and "not m5 and not mesmerizer" for the 441.
We know these things were named for whatever you were building at the time, but it's an challenge to the DIY'ers in our discussion groups to get audio going.
| sum += _Peaks[i]; | ||
|
|
||
| // Scale it so that it is not always in the top red | ||
| sum += _Peaks._Level[i]; |
There was a problem hiding this comment.
There are lots of these loops that can be:
float sum = std::accumulate(_Peaks._Level, _Peaks._Level + NUM_BANDS, 0.0f);
There was a problem hiding this comment.
Are you certain /Ofast isn't already that clever? Would be good to know. I don't mind optimizing it, but it's more readable expressed as two passes.
There was a problem hiding this comment.
It can't be that clever under the "as if" rule. It would have to prove that sum never overflows. Poking it, range analysis also seems to factor in, though I think it can prove that sum isn't aliased and that the arrays don't overlap, but you can see foryourself:
https://godbolt.org/z/x8e9xnPf1
Unfortunately, teh zero-overhead-loop end label is eaten by Goldbolt. There's an open BR on that at compiler-explorer/compiler-explorer#6496. Because this code is so trivial, if you know the return value (tally) is in a2, just imagine every add with a destination of a2 to be followed by the closes preceeding LOOP insn and it'll all make sense.
Even without that, it's hopefully clear that in a code path where fps matters, one loop over NUM_BANDS is better than two loops over NUM_BANDS.
|
There are two distinctly different "passes", as I said. On inside the loop,
one just above it.
…On Sun, Aug 10, 2025, 10:17 PM David W Plummer ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In include/effects/strip/faneffects.h
<#740 (comment)>
:
> for (int iPass = 0; iPass < passes; iPass++)
{
int iFan = random(0, NUM_FANS);
- int passes = random(1, g_Analyzer._VURatio);
+ int passes = random(1, (int)g_Analyzer.VURatio());
I get that, but I guess I just see it? Which variable is duplicated in an
inner scope?
—
Reply to this email directly, view it on GitHub
<#740 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACCSD34V6V7WCQ36LHTD22T3NADLLAVCNFSM6AAAAACDP66VSCVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTCMBTHEYDONZWGE>
.
You are receiving this because you commented.Message ID:
***@***.***
com>
|
|
I see iPass, iFan, and passes. One of each. Which is the shadow of what?
…-Dave
On Aug 10, 2025, at 9:25 PM, Ghosteyezzzz ***@***.***> wrote:
@Thermotronica commented on this pull request.
In include/effects/strip/faneffects.h <#740 (comment)>:
> for (int iPass = 0; iPass < passes; iPass++)
{
int iFan = random(0, NUM_FANS);
- int passes = random(1, g_Analyzer._VURatio);
+ int passes = random(1, (int)g_Analyzer.VURatio());
i guess shadows are aliasing as opposed to a brightness alpha spectra
—
Reply to this email directly, view it on GitHub <#740 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AA4HCF4N26Z7BQJPGNKA2WD3NALNHAVCNFSM6AAAAACDP66VSCVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTCMBUGAYDSNJZHA>.
You are receiving this because you authored the thread.
|
|
“In code not visible here”. That’s the key point. I see it if I go look in the actual file, but thought we were talking about the exceprt, do didn’t see it. Will fix!
… On Aug 11, 2025, at 8:03 AM, Rutger van Bergen ***@***.***> wrote:
@rbergen commented on this pull request.
In include/effects/strip/faneffects.h <#740 (comment)>:
> for (int iPass = 0; iPass < passes; iPass++)
{
int iFan = random(0, NUM_FANS);
- int passes = random(1, g_Analyzer._VURatio);
+ int passes = random(1, (int)g_Analyzer.VURatio());
@davepl <https://github.com/davepl> It's passes. It's redefined in a for loop that compares its indexer variable with a passes that's defined in an outer context.
—
Reply to this email directly, view it on GitHub <#740 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AA4HCF7Y35HHIPU6BTR7FUD3NCWFTAVCNFSM6AAAAACDP66VSCVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTCMBWGMZDMOBTHE>.
You are receiving this because you were mentioned.
|
|
These e-mail responses at the end of the comment chain always get me... I agree the limited scope of the code that is commented on doesn't help. (But in a very pedantic stance I do have to note that the |
Pull pdpwopr changes into my audio branch
This reverts commit e0e93f8.
Description
Replaces the old SoundAnalyzer class with a new interface and implementation. Updates all callers to use the new interface.
mainas the target branch.