Checking for sounds' existence in prop routines?

What is the hard rule about checking for sounds’ existence in prop routines?

It seems logical to do, since not everyone might be using a Voicepack in a common folder.
While cleaning my prop up, I’m noticing I have some that check first and provide a beep or something else as fallback., while others assume a sound will be there.
I just want to confirm that assuming is probably an oversight and should be corrected.
For example, checked

      if (SFX_vmend) {
        sound_library_.SayVolumeMenuEnd();
      } else {
        beeper.Beep(0.1, 2000);
        beeper.Beep(0.1, 1000);
      }

vs unchecked

  void ToggleSequentialQuote() {
    sequential_quote_ = !sequential_quote_;
    sound_library_.SayRandom();

Secondly, I wonder where the declarations for these sounds should go.
For example, I have to have EFFECT(volmin) in the prop if a check is made for existence. However, NOT checking doesn’t need that declaration.
So if I change all the calls to sounds to be checked first, it would seem I would need declare all of them in the prop then, such as adding EFFECT(mrandom).

But then i see like mnum

if (&SFX_mnum) {
      sound_library_.SayNumber(id, SAY_WHOLE);
    }

where EFFECT(mnum) is already covered in sound library itself, which brings the question…
should we move all the “custom” sound declarations that already exist as “Say” something in sound library into sound library itself instead of the prop?
Like all these?

EFFECT(vmbegin);    // for Begin Volume Menu
EFFECT(vmend);      // for End Volume Menu
EFFECT(volup);      // for increse volume
EFFECT(voldown);    // for decrease volume
EFFECT(volmin);     // for minimum volume reached
EFFECT(volmax);     // for maximum volume reached

Now that i look further, maybe it would make sense to just check for just one specific sound to determine if there’s a Voicepack/common folder in the font search path, similar to how hybrid_font determines stuff based on lockup or lock, poweron etc…

If we just checked for (SFX_medit), would it be “safe to assume” the rest exist then?
This avoids multiple checks that would muddy up the code, like checking each sound in this

  void ToggleSequentialQuote() {
    sequential_quote_ = !sequential_quote_;
    sound_library_.SayRandom();
    if (sequential_quote_) {
      sound_library_.SayDisabled();
    } else {
      sound_library_.SayEnabled();
    }
  }

would need to be

  void ToggleSequentialQuote() {
    sequential_quote_ = !sequential_quote_;
    if (SFX_mrandom) sound_library_.SayRandom();
    if (sequential_quote_) {
      if (SFX_mdisable) {
        sound_library_.SayDisabled();
      } else {
        beeper.Beep(0.5, 3000);
      }
    } else {
      if (SFX_menable) {
        sound_library_.SayEnabled();
      } else {
        beeper.Beep(0.5, 1000);
    }
  }

as opposed to simpler, easier to read version with a single check like this?

  void ToggleSequentialQuote() {
    sequential_quote_ = !sequential_quote_;
    if (SFX_medit) {
      sound_library_.SayRandom();
      sequential_quote_ ? sound_library_.SayDisabled() : sound_library_.SayEnabled();
    } else {
      beeper.Beep(0.5, sequential_quote_ ? 3000 : 1000);
    }
  }

Also, I will likely be submitting that we introduce “SaySequential”, so it would be even cleaner:

  void ToggleSequentialQuote() {
    sequential_quote_ = !sequential_quote_;
    if (SFX_medit) {
      sequential_quote_ ? sound_library_.SaySequential() : sound_library_.SayRandom();
    } else {
      beeper.Beep(0.5, sequential_quote_ ? 3000 : 1000);
    }
  }

There is a lot of questions here, and I’m not sure if this resolves all of them, but let me start by explaining how I imagine voice packs working…

I imagine that all V2 (or higher) voice packs will come with a config file which specifies the version of the voice pack. When you write a prop (or a menu system, or whatever) you choose which the minimum voice pack version you need, and if no voice pack is found, or the voice pack version is too low, a warning will be played, since not all sounds may be found.

Since V1 sound library files do not come with config files, I’ll probably use the presence of mnum* as a check for this.

While this isn’t implemented yet, I intend to implement it before V8 ships.

No, EFFECT() uses more space than sound library definitions.

tl;dr;

The prop shouldn’t have to check if sound library sounds are available or not, it should be enough to request/require a specific version of the sound library.

Also, if you haven’t seen it:

:astonished:
No I had not seen that! :+1:
I had a curl script that did something similar for the GladOS voice but that was specific to their site.

curl -L --retry 30 --get --fail \
    --data-urlencode "text=hundred. accept. confirm selection. alt color. Auto. maximum clash strength. base color. Battery level. begin. adjust black level. select blade. blast color. Clash detection level. cancel. clash color. edit clash threshold. edit color. color list." \
    -o "02.wav" \
    "https://glados.c-net.org/generate"

I get a bunch of gibberish binary data in the console if I don’t add this in speak.pl:

     open(FILE,">$mp3_out");
    binmode(FILE);  # Treat as binary file
    print FILE $resp;
    close(FILE);
    return $mp3_out;

Sounds like a PR to me.
(I’m guessing you’re running it on windows?)

No, MacOS, Terminal, bash shell.
PR sent