When would this ever be called?

@profezzorn I’m still fooling around with the manual blade array switching and integrating it to work WITH constant Blade ID active. I’m down to just ironing out which sound is played when.

In trying to have it play a bladein/out sound EVERY time there’s a physical blade inserted or removed, (provided the sounds exist), I find this is getting in the way:

  // Must be called from loop()
  void PollScanId() {
    if (find_blade_again_pending_) {
      find_blade_again_pending_ = false;
      int noblade_level_before = current_config->ohm / NO_BLADE;
      FindBladeAgain();
      int noblade_level_after = current_config->ohm / NO_BLADE;

      if (noblade_level_before < noblade_level_after) {
        SaberBase::DoBladeDetect(false);
      } else if(noblade_level_before > noblade_level_after) {
        SaberBase::DoBladeDetect(true);
      } else {
	SaberBase::DoNewFont();
      }
    }
  }

That last call to DoNewFont() at the end is in an else condition.
With the current code, how could the change of a blade in or out result in the new array value NOT being < or > than the previous?

Suffice it to say, that is exactly the scenario I am working with, as a manual switch may very well cause the “coming from” and “going to” array to be the same.
But in the current structure of the code, I am wondering why this is here?

Would it make sense to add a check here for bladein/out sounds existence and play the appropriate one based on whether the array is >= NO_BLADE , and THEN fallback to font.wav?

Something like:

      if (noblade_level_before < noblade_level_after) {
        SaberBase::DoBladeDetect(false);
      } else if(noblade_level_before > noblade_level_after) {
        SaberBase::DoBladeDetect(true);
      } else if (SFX_bladein) {
        hybrid_font.SB_BladeDetect(!(id() >= NO_BLADE));
      } else {
        SaberBase::DoNewFont();
      }

It’s not the array value that is being compared, it’s the array value divided by NO_BLADE.
So 0 means 0…NO_BLADE-1, 1 means NO_BLADE…2NO_BLADE-1 and 2 means 2NO_BLADE…3*NO_BLADE-1, etc. (2 * NO_BLADE is intended to mean no blade and no hilt.)

So if the noblade value goes down, that means that we went from some entry with a higher NO_BLADE multiplier, to an entry with a lower NO_BLADE multiplier. This usually means that we went from NO_BLADE to an entry with a regular value. (0 * NO_BLADE) In this case we play bladein.wav

If the noblade value goes up, then we went from a regular value to a NO_BLADE value. (Or from NO_BLADE to NO_BLADE * 2) In this case we play bladeout.wav

If you go from a regular entry to another regular entry (or from one NO_BLADE entry to another NO_BLADE entry[1]), then the blade was not inserted, and not removed, so we just play “font.wav”.

[1] Yes, it’s possible to have multiple NO_BLADE entries, because NO_BLADE is added to the regular blade ID, so you could have something like NO_BLADE+2000 as the blade ID and NO_BLADE+5000 for another blade ID.

If the noblade value didn’t change, then blade ID changed without a blade being inserted or removed, so why would we play bladein.wav ?

well now I have to wrap my head around this again.
I suppose I didn’t take into account the possibility of two or more NO_BLADE states.
Additionally, I must have done something weird because I have a basic call to hybrid_font.PlayPolyphonic(array), and it shows it played in serial monitor,
17:56:23.617 -> unit = 0 vol = 0.50, Playing commonBU/array/array03.wav
but it actually didn’t.
How could that be? Nothing interrupted it either, just no sound for that event.
I also noticed that it does play if the blade is On().
I think I’ve made spaghetti over here and need to start over.

This call doesn’t happen to be right before switching fonts, does it?

grrr. yes it does I think, I’ll look again, thanks.
“the sound system is murdered when you switch presets”

Going off the original topic here, but confirming that the order of operations was the issue. I was trying to use a helper function to keep things neat, and then an “if you can play this sound, do it, then SetPreset(), otherwise do something else” way of things, but that means playing array.wav before SetPreset

  bool PlayArraySound(size_t selected_array_sound) {
    if (SFX_array) {
      SFX_array.Select(selected_array_sound);
      hybrid_font.PlayPolyphonic(&SFX_array);
      return true;
    }
    return false;
  }

// more code here
if (PlayArraySound(current_config - blades)) {
      SetPreset(0, false);
    } else {
      SetPreset(0, true);
    }

It needs to just be this instead and it works right

    if (SFX_array) {
      SetPreset(0, false);
      SFX_array.Select(current_config - blades);
      hybrid_font.PlayPolyphonic(&SFX_array);
    } else {
      SetPreset(0, true);
    }

That’s kind of the original question. In what case could that happen?
I guess we’re talking like chassis in/out, or crystal in/out as other things that can insert and remove, so not specifically a blade.

so if we added custom sounds to the prop to handle those things like
EFFECT(chassisin) etc…
and then set up a switch with the actual resistor values for the arrays, like

    int chosen_array = current_config->ohm;
    switch (chosen_array) {
        case 64000:
            // code to play chassisin.wav
            break;
        case 6400:
            // sode to play crystalin.wav
            break;
    }

would that work ok? I suppose we’d need a method to know when it’s “out” though.

I always imagined that there would be no need for a “chassisin.wav”, because you would just set up a separate font for the “chassis.= yes, blade = no” case, and in that font, bladein.wav would be played when the chassis is inserted.

Recently though, the discussion has been about how to avoid all this font customization and have a specific sound for each state (array entry) which is not how I imagined it would work. Not saying that either way is wrong, I’m just saying that’s the assumption that’s in the code right now.

It seems super-weird to me to hard-code ohm values in the prop. Seems like it would only work for one specific config file. But sure, it would work

Agreed. ok so that’s what I was hoping. We’re on the same page.
Since this is all pretty customized stuff, I feel it’s on the user to set some things up so that they work, not necessarily the responsibility of the code to handle every possible situation. That would get unwieldy quickly.
Of course the code can be helpful and work accordingly, but it’s certainly not unreasonable to have the font used for a purpose be modified to work with said purpose (ie: bladein.wav is made into an appropriate desired sound.)
I mean, for a long time we were using “force” sounds to play “quotes”, so this is really no different.

But then that brings up the same initial question again.
What scenario would cause the Blade ID to be changed if it wasn’t a blade being inserted or removed? I can’t think of any, which is why I thought anytime best_config != last read best_config must mean a blade was in/out.
I guess i should read that thread about NO_BLADE * 2 and what was happening with all that.

Here are some scenarios I can dream up:

  1. There are no NO_BLADE entries.
  2. User or prop has some custom things for re-detecting the blade (a button that calls FindBladeAgain, possibly with a fake blade ID class…)
  3. Using RFID to switch crystals (which currently has no method for detecting that the crystal has been removed without adding extra wires.)
  4. Anything that uses blade ID for something we haven’t thought of yet.
  5. User switches blade faster than blade ID scan interval.
1 Like

This made me laugh.
That would be a user error. The user should know to go slow enough to change blade.

  1. user error

:slight_smile:

2 Likes