# ProffieOS v7.x feature discussions - freeing wavplayer

**URL:** <https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350>\
**Category:** Off-topic\
**Created:** [February 3, 2022, 4:19am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350 "2022-02-03T04:19:28Z")\
**Posts on this page:** 12\
**Page:** 3

<div class="post-metadata">

**Author:** ![NoSloppy](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/nosloppy/32/3865_2.png) [@NoSloppy](https://crucible.hubbe.net/u/NoSloppy)\
**Post date:** [February 5, 2022, 3:08am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/42 "2022-02-05T03:08:04Z")

</div>

I think I have it ironed out. Freezing prevented, tests flawlessly for me with a drumroll style clash test of like 1000 clashes. Please test.

```auto
RefPtr<BufferedWavPlayer> PlayPolyphonic(Effect* f) {
    EnableAmplifier();
    if (!f->files_found()) return RefPtr<BufferedWavPlayer>(nullptr);
    RefPtr<BufferedWavPlayer> player = GetFreeWavPlayer();
    if (!player) {
      STDOUT.println("Out of WAV players! Getting more...");
      float oldest_ = 0;
      uint32_t kill_ = 0;
  // check wavplayers, rule out hum and smoothswings then kill oldest one 
      for (size_t i = 0; i < NELEM(wav_players); i++) {
        if (wav_players[i].isPlaying() && wav_players[i].current_file_id().GetEffect() == f) {
            float pos = wav_players[i].pos();
            if (pos > oldest_) {
              oldest_ = pos;
              kill_ = i;
            }    
        } else {
          // unsuccessful acquisition. Let's try again.
          if (i == 6) return player;
        }
      }
        if (wav_players[kill_].pos() > .002) {
          wav_players[kill_].set_fade_time(0.001);
          wav_players[kill_].FadeAndStop();
          STDOUT << "Killing off " << wav_players[kill_].filename() << "\n";
          while(wav_players[kill_].isPlaying()) {
  #ifdef VERSION_MAJOR >= 4
            armv7m_core_yield();
  #endif
          }
        }
        player = GetFreeWavPlayer();
    }
    player->set_volume_now(font_config.volEff / 16.0f);
    player->PlayOnce(f);
    current_effect_length_ = player->length();
    return player;
  }

```

---

<div class="post-metadata">

**Author:** ![A\_Rogue\_Child](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/a_rogue_child/32/4449_2.png) [@A\_Rogue\_Child](https://crucible.hubbe.net/u/A_Rogue_Child)\
**Post date:** [February 5, 2022, 3:37am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/43 "2022-02-05T03:37:26Z")

</div>

I’ll throw it in tomorrow, both batteries are dead anyhow.

\*I’m also still laughing too hard at being able to toss in the Tron Font sounds for the effect with Bit going “Yes” and “No” and the look on the wife’s face when it kept going “YesYesYesYesNoYesYesYes…”.

---

<div class="post-metadata">

**Author:** ![Driftrotor](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/driftrotor/32/379_2.png) [@Driftrotor](https://crucible.hubbe.net/u/Driftrotor)\
**Post date:** [February 5, 2022, 3:40am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/44 "2022-02-05T03:40:01Z")

</div>

confirmed, working spot on.  
i spammed for more than a minute with no issues!  
man that was one hell of a blaster battle!

> [@A\_Rogue\_Child](#):
>
> Tron Font sounds for the effect with Bit going “Yes” and “No”

ooooo! can you send me them please?! (would put a smile on my dads face!)

---

<div class="post-metadata">

**Author:** ![NoSloppy](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/nosloppy/32/3865_2.png) [@NoSloppy](https://crucible.hubbe.net/u/NoSloppy)\
**Post date:** [February 5, 2022, 3:44am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/45 "2022-02-05T03:44:22Z")

</div>

> [@Driftrotor](#):
>
> confirmed, working spot on.  
> i spammed for more than a minute with no issues!  
> man that was one hell of a blaster battle!

Great, thanks.  
@profezzorn what do you think?

---

<div class="post-metadata">

**Author:** ![astromech](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/astromech/32/52_2.png) [@astromech](https://crucible.hubbe.net/u/astromech)\
**Post date:** [February 5, 2022, 12:25pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/46 "2022-02-05T12:25:01Z")

</div>

So, I realised last night I gave my USB cable to a friend for their Proffie saber and have one on order. I got the posh right angle ribbon cable so have to wait a bit.

---

<div class="post-metadata">

**Author:** ![profezzorn](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/profezzorn/32/8_2.png) [@profezzorn](https://crucible.hubbe.net/u/profezzorn)\
**Post date:** [February 5, 2022, 6:37pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/47 "2022-02-05T18:37:59Z")

</div>

> [@NoSloppy](#):
>
> @profezzorn what do you think?

Time for a PR?

---

<div class="post-metadata">

**Author:** ![A\_Rogue\_Child](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/a_rogue_child/32/4449_2.png) [@A\_Rogue\_Child](https://crucible.hubbe.net/u/A_Rogue_Child)\
**Post date:** [February 5, 2022, 9:17pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/48 "2022-02-05T21:17:44Z")

</div>

@astromech Off-topic but you’re gonna like it. Makes flashing the board so much easier.

@NoSloppy I’ll retest w the latest revision today/tonight if you still need. LMK

---

<div class="post-metadata">

**Author:** ![A\_Rogue\_Child](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/a_rogue_child/32/4449_2.png) [@A\_Rogue\_Child](https://crucible.hubbe.net/u/A_Rogue_Child)\
**Post date:** [February 5, 2022, 11:19pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/49 "2022-02-05T23:19:45Z")

</div>

@NoSloppy I’m getting an error report for 5.9  
\*\*Edit: It’s not due to the prop file mod as questioned below.  
Did I replace/insert it wrong?

```auto
Arduino: 1.8.20 Hourly Build 2021/12/20 07:34 (Mac OS X), Board: "Proffieboard V2, Serial + WebUSB, SDCARD (SPI), 80 MHz, Smallest Code"

In file included from /Users/revo/ProffieBoards/ProffieOS_5.9_RevoModded/ProffieOS/sound/sound.h:77,
                 from /Users/revo/ProffieBoards/ProffieOS_5.9_RevoModded/ProffieOS/ProffieOS.ino:347:
/Users/revo/ProffieBoards/ProffieOS_5.9_RevoModded/ProffieOS/sound/hybrid_font.h: In member function 'RefPtr<BufferedWavPlayer> HybridFont::PlayPolyphonic(Effect*)':
/Users/revo/ProffieBoards/ProffieOS_5.9_RevoModded/ProffieOS/sound/hybrid_font.h:188:58: error: 'class BufferedWavPlayer' has no member named 'current_file_id'
  188 | if (wav_players[i].isPlaying() && wav_players[i].current_file_id().GetEffect() == f) {
      | ^ ~~~~~~~~~~~~~~
exit status 1
Error compiling for board Proffieboard V2.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

\*Did I miss a } ?

```auto
 RefPtr<BufferedWavPlayer> PlayPolyphonic(Effect* f) {
    EnableAmplifier();
    if (!f->files_found()) return RefPtr<BufferedWavPlayer>(nullptr);
    RefPtr<BufferedWavPlayer> player = GetFreeWavPlayer();
    if (!player) {
      STDOUT.println("Out of WAV players! Getting more...");
      float oldest_ = 0;
      uint32_t kill_ = 0;
  // check wavplayers, rule out hum and smoothswings then kill oldest one 
      for (size_t i = 0; i < NELEM(wav_players); i++) {
        if (wav_players[i].isPlaying() && wav_players[i].current_file_id().GetEffect() == f) {
            float pos = wav_players[i].pos();
            if (pos > oldest_) {
              oldest_ = pos;
              kill_ = i;
            }    
        } else {
          // unsuccessful acquisition. Let's try again.
          if (i == 6) return player;
        }
      }
        if (wav_players[kill_].pos() > .002) {
          wav_players[kill_].set_fade_time(0.001);
          wav_players[kill_].FadeAndStop();
          STDOUT << "Killing off " << wav_players[kill_].filename() << "\n";
          while(wav_players[kill_].isPlaying()) {
  #ifdef VERSION_MAJOR >= 4
            armv7m_core_yield();
  #endif
          }
        }
        player = GetFreeWavPlayer();
    }
    player->set_volume_now(font_config.volEff / 16.0f);
    player->PlayOnce(f);
    current_effect_length_ = player->length();
    return player;
  }

```

Here’s what it ended up being patched in for the section. Lines 81-234. \*I don’t think my 5.9 mods affect this since it was a button and sound font route change only to the prop file.

```auto
FontConfigFile font_config;

// Monophonic sound fonts are the most common.
// These fonts are fairly simple, as generally only one sound is
// played at a time. It starts with the "poweron" sound and when
// that runs out, we gaplessly transition to the "hum" sound.
//
// When an effect happens, like "clash", we do a short cross-fade
// to transition to the new sound, then we play that sound until
// it ends and gaplessly transition back to the hum sound.
class HybridFont : public SaberBase {
public:
  HybridFont() : SaberBase(NOLINK) { }
  void Activate() {
    SetupStandardAudio();
    font_config.ReadInCurrentDir("config.ini");
    STDOUT.print("Activating ");
    // TODO: Find more reliable way to figure out if it's a monophonic or polyphonic font!!!!
    if (SFX_in || SFX_out) {
      monophonic_hum_ = false;
    } else {
      monophonic_hum_ = SFX_poweron || SFX_poweroff || SFX_pwroff || SFX_blast;
    }
    guess_monophonic_ = false;
    if (monophonic_hum_) {
      if (SFX_clash || SFX_blaster || SFX_swing) {
        if (SFX_humm) {
	  monophonic_hum_ = false;
          guess_monophonic_ = false;
          STDOUT.print("plecter polyphonic");
        } else {
          guess_monophonic_ = true;
          STDOUT.print("monophonic");
        }
      } else {
        guess_monophonic_ = false;
        STDOUT.print("hybrid");
      }
    } else {
      guess_monophonic_ = false;
      STDOUT.print("polyphonic");
    }

    STDOUT.println(" font.");
    SaberBase::Link(this);
    SetHumVolume(1.0);
    state_ = STATE_OFF;
  }

  enum State {
    STATE_OFF,
    STATE_OUT,
    STATE_HUM_FADE_IN,
    STATE_HUM_ON,
    STATE_HUM_FADE_OUT,
  };

  void Deactivate() {
    lock_player_.Free();
    hum_player_.Free();
    next_hum_player_.Free();
    swing_player_.Free();
    SaberBase::Unlink(this);
    state_ = STATE_OFF;
  }

  RefPtr<BufferedWavPlayer> hum_player_;
  RefPtr<BufferedWavPlayer> next_hum_player_;
  RefPtr<BufferedWavPlayer> swing_player_;
  RefPtr<BufferedWavPlayer> lock_player_;

  void PlayMonophonic(Effect* f, Effect* loop) {
    EnableAmplifier();
    if (!next_hum_player_) {
      next_hum_player_ = GetFreeWavPlayer();
      if (!next_hum_player_) {
        STDOUT.println("Out of WAV players!");
        return;
      }
    }
    if (hum_player_) {
      hum_player_->set_fade_time(0.003);
      hum_player_->FadeAndStop();
      hum_player_.Free();
      next_hum_player_->set_volume_now(0);
      next_hum_player_->set_fade_time(0.003);
      next_hum_player_->set_volume(font_config.volEff / 16.0f);
    } else {
      next_hum_player_->set_volume_now(font_config.volEff / 16.0f);
    }
    hum_player_ = next_hum_player_;
    next_hum_player_.Free();
    hum_player_->PlayOnce(f);
    current_effect_length_ = hum_player_->length();
    if (loop) hum_player_->PlayLoop(loop);
  }

 RefPtr<BufferedWavPlayer> PlayPolyphonic(Effect* f) {
    EnableAmplifier();
    if (!f->files_found()) return RefPtr<BufferedWavPlayer>(nullptr);
    RefPtr<BufferedWavPlayer> player = GetFreeWavPlayer();
    if (!player) {
      STDOUT.println("Out of WAV players! Getting more...");
      float oldest_ = 0;
      uint32_t kill_ = 0;
  // check wavplayers, rule out hum and smoothswings then kill oldest one 
      for (size_t i = 0; i < NELEM(wav_players); i++) {
        if (wav_players[i].isPlaying() && wav_players[i].current_file_id().GetEffect() == f) {
            float pos = wav_players[i].pos();
            if (pos > oldest_) {
              oldest_ = pos;
              kill_ = i;
            }    
        } else {
          // unsuccessful acquisition. Let's try again.
          if (i == 6) return player;
        }
      }
        if (wav_players[kill_].pos() > .002) {
          wav_players[kill_].set_fade_time(0.001);
          wav_players[kill_].FadeAndStop();
          STDOUT << "Killing off " << wav_players[kill_].filename() << "\n";
          while(wav_players[kill_].isPlaying()) {
  #ifdef VERSION_MAJOR >= 4
            armv7m_core_yield();
  #endif
          }
        }
        player = GetFreeWavPlayer();
    }
    player->set_volume_now(font_config.volEff / 16.0f);
    player->PlayOnce(f);
    current_effect_length_ = player->length();
    return player;
  }

  void Play(Effect* monophonic, Effect* polyphonic) {
    if (polyphonic->files_found()) {
      PlayPolyphonic(polyphonic);
    } else if (SFX_humm) {
      PlayPolyphonic(monophonic);
    } else {
      PlayMonophonic(monophonic, &SFX_hum);
    }
  }

  void PlayCommon(Effect* effect) {
    if (guess_monophonic_) {
      PlayMonophonic(effect, &SFX_hum);
    } else {
      PlayPolyphonic(effect);
    }
  }

```

---

<div class="post-metadata">

**Author:** ![NoSloppy](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/nosloppy/32/3865_2.png) [@NoSloppy](https://crucible.hubbe.net/u/NoSloppy)\
**Post date:** [February 6, 2022, 1:05am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/50 "2022-02-06T01:05:29Z")

</div>

I mentioned above it’s only going to work on OS6.

---

<div class="post-metadata">

**Author:** ![A\_Rogue\_Child](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/a_rogue_child/32/4449_2.png) [@A\_Rogue\_Child](https://crucible.hubbe.net/u/A_Rogue_Child)\
**Post date:** [February 6, 2022, 3:04am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/51 "2022-02-06T03:04:27Z")

</div>

Tested in both boards just now, works perfect. Celebrated by Arg-ifying TheMaw.

Awesome work man, I clicked the heck out of the aux button and no lockup squee.

---

<div class="post-metadata">

**Author:** ![Driftrotor](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/driftrotor/32/379_2.png) [@Driftrotor](https://crucible.hubbe.net/u/Driftrotor)\
**Post date:** [February 7, 2022, 9:01am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/52 "2022-02-07T09:01:52Z")

</div>

got an interesting occurrence when testing something one the saber.  
i did the usual spamming of the aux button to show my son and then retracted the blade (pow) but no in.wav played.  
tested this a few times and it seems that in.wav does not play unless the oldest blast.wav has finished playing.  
i know in normal use this would not present itself as a blaster battle normally ends with a “pose of power stance!” for dramatic effect of course! and then retract the blade.

is it possible to have the wav player drop the oldest one in favour for the in.wav?

---

<div class="post-metadata">

**Author:** ![profezzorn](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/profezzorn/32/8_2.png) [@profezzorn](https://crucible.hubbe.net/u/profezzorn)\
**Post date:** [February 7, 2022, 9:13am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/53 "2022-02-07T09:13:00Z")

</div>

It’s absolutely possible, but it’s a little more complicated, and the current code posted in this thread doesn’t do that.

[Previous page](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350.md?page=2)
