# 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:** 20\
**Page:** 1

<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 3, 2022, 4:19am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/1 "2022-02-03T04:19:28Z")

</div>

Topic: Freeing a wavplayer when we run out. (such as spamming blasts).  
Ideally, this would be the oldest triggered effect that is not hum, swingl, or swingh.

I thought I’d take a crack at this, but I’m doing something wrong when getting a currently occupied player because I still get ‘nothin’ reported.  
But I should be on the right track?  
Shouldn’t be a big deal to do, right?

```auto
  RefPtr<BufferedWavPlayer> PlayPolyphonic(Effect* f) {
    EnableAmplifier();
    if (!f->files_found()) return RefPtr<BufferedWavPlayer>(nullptr);
    RefPtr<BufferedWavPlayer> player = GetFreeWavPlayer();
    if (player) {
      player->set_volume_now(font_config.volEff / 16.0f);
      player->PlayOnce(f);
      current_effect_length_ = player->length();
    } else {
STDOUT.println(" ************************** Out of WAV players! Getting more...I think.");
      RefPtr<BufferedWavPlayer> effect = GetWavPlayerPlaying(f);
      effect->set_fade_time(0.003);
      effect->FadeAndStop();
      effect.Free();
STDOUT.println(" ************************** ok freed?");
      player = GetFreeWavPlayer();
      if (player) {
STDOUT.println(" ************************** Found freed player, about to 2nd attempt to player->PlayOnce().");
        player->set_volume_now(font_config.volEff / 16.0f);
        player->PlayOnce(f);
        current_effect_length_ = player->length();
      } else {
STDOUT.println(" ************************** I got nothin. returning nothin.");
      }
    }
    return player;
  }

```

The 2nd attempt to play is to prevent a dead click while we “reload” this time around.

---

<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 3, 2022, 6:24pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/2 "2022-02-03T18:24:50Z")

</div>

First of all, when this calls GetWavPlayerPlaying() it’s not necessarily finding the _oldest_ one.  
However, the reason it probably doesn’t work is because GetFreeWavPlayer() won’t return a wav player that is playing a sound. And since you set fade time to 3 milliseconds, the wav player you’re trying to free won’t actually be free until 3 milliseconds later.

There is also a question of which is worse. Aborting a sound can make it sound terrible, but if we’re just cutting off the very end of it, it might be fine. Maybe we would need a per-effect value that specifies how far into the sound we need to be before it’s ok to abort it?

---

<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 3, 2022, 8:59pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/3 "2022-02-03T20:59:03Z")

</div>

This is not right. Non-pointer type and other problems, but is something like this a way to find the oldest playing non-hum/SS player?

```auto
    float oldest_ = 0;
    float kill_;
// check wavplayers and rule out hum and smoothswings
    for (size_t i = 0; i < NELEM(wav_players); i++) {
      if (wav_players[i].current_file_id().GetEffect() == f) {
        float pos = wav_players[i]->pos();
        if (pos > oldest_) {
          oldest_ = pos;
          kill_ = wav_players[i]
        }   
      }
    }

```

where kill would then be faded and stopped.  
Oh yeah, is fade time .0000001 fast enough?

---

<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 3, 2022, 9:14pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/4 "2022-02-03T21:14:18Z")

</div>

Something like that should work.

There is no fade time that is fast enough. We either have to call Stop() on it (which I don’t recommend) or wait for it (which can be problematic too).

---

<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 3, 2022, 9:55pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/6 "2022-02-03T21:55:52Z")

</div>

> [@profezzorn](#):
>
> There is no fade time that is fast enough.

So doesn’t FadeandStop() happen, then we come back and do Free() before we move on?  
Wondering why it would make the 2nd attempt before Free() is done.

---

<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 3, 2022, 10:00pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/7 "2022-02-03T22:00:23Z")

</div>

How about just hurrying up the wait? Could we skip to the end by setting position to length minus 2 ms, fade for 1ms then stop and free?

```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...I think.");
      float oldest_ = 0;
      float kill_;
  // check wavplayers, rule out hum and smoothswings
  // then kill oldest one by skipping to eof
      for (size_t i = 0; i < NELEM(wav_players); i++) {
        if (wav_players[i].current_file_id().GetEffect() == f) {
          float pos = wav_players[i]->pos();
          if (pos > oldest_) {
            oldest_ = pos;
            kill_ = wav_players[i]
          }   
        }
      }
      if (kill_->pos() > .002) {
        kill_.pos() = kill_->length() - .002;
        kill_->set_fade_time(0.001);
        kill_->FadeAndStop();
        kill_.Free();
        player = GetFreeWavPlayer();
      }
    }

    player->set_volume_now(font_config.volEff / 16.0f);
    player->PlayOnce(f);
    current_effect_length_ = player->length();
    return player;
  }

```

Would you be willing to sort out the RefPtr and type errors in this “theoretical” flow?  
I know it doesn’t like `float pos = wav_players[i]->pos();`

---

<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 3, 2022, 10:42pm UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/8 "2022-02-03T22:42:18Z")

</div>

Setting the position doesn’t change anything, it would just create a “click” in the sound.  
If we had a time machine we could go back and start the fade 3 milliseconds ago, which would be handy, but unfortunately I’m all out of flux capacitors.

Try replacing`wav_players[i]->whatever` with `wav_players[i].wavever`.  
`wav_players[i]` is not a pointer.

---

<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 4, 2022, 1:55am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/9 "2022-02-04T01:55:30Z")

</div>

So are you saying the best we could shoot for is fade and stop asap and just minimize the “lag” ?  
I can’t fix the errors so I’m at a stopping point right now.

---

<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 4, 2022, 2:10am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/10 "2022-02-04T02:10:40Z")

</div>

The simplest option is to set the ramp-down time to something short, then call FadeAndStop() then do something like:

```auto
   while(kill_->isPlaying()) {
#ifdef VERSION_MAJOR >= 4
     armv7m_core_yield();
#endif
  }

```

This will make PlayPolyphonic take more time, since we’re waiting for the player to finish playing, but that just might be worth it.

A more complex solution would be to trigger a callback/event when a player becomes available and do the playback then.

---

<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 4, 2022, 2:50am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/11 "2022-02-04T02:50:37Z")

</div>

By Jove, this works! Thanks!

```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].current_file_id().GetEffect() == f) {
          float pos = wav_players[i].pos();
          if (pos > oldest_) {
            oldest_ = pos;
            kill_ = i;
          }   
        }
      }
      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;
  }

```

Output showing what was played and that the first played gets killed:  
(I removed unrelated messages like ‘Playing swingl’ )

```auto
21:39:57.449 -> unit = 0 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst07.wav
21:39:57.449 -> channels: 1 rate: 44100 bits: 16
21:39:57.903 -> unit = 4 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst05.wav
21:39:57.903 -> channels: 1 rate: 44100 bits: 16
21:39:58.256 -> unit = 5 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst07.wav
21:39:58.256 -> channels: 1 rate: 44100 bits: 16
21:39:58.535 -> unit = 6 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst01.wav
21:39:58.569 -> channels: 1 rate: 44100 bits: 16
21:39:58.842 -> ************************** Out of WAV players! Getting more...
21:39:58.842 -> *************************** Killing off aa_Juansith/Red_Five/blst/blst07.wav
21:39:58.842 -> unit = 0 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst05.wav
21:39:58.842 -> channels: 1 rate: 44100 bits: 16

21:40:01.849 -> unit = 0 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst02.wav
21:40:01.849 -> channels: 1 rate: 44100 bits: 16
21:40:02.137 -> unit = 4 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst03.wav
21:40:02.137 -> channels: 1 rate: 44100 bits: 16
21:40:02.391 -> unit = 5 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst08.wav
21:40:02.391 -> channels: 1 rate: 44100 bits: 16
21:40:02.607 -> unit = 6 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst01.wav
21:40:02.607 -> channels: 1 rate: 44100 bits: 16
21:40:02.890 -> ************************** Out of WAV players! Getting more...
21:40:02.890 -> *************************** Killing off aa_Juansith/Red_Five/blst/blst02.wav
21:40:02.890 -> unit = 0 vol = 0.50, Playing aa_Juansith/Red_Five/blst/blst05.wav
21:40:02.890 -> channels: 1 rate: 44100 bits: 16

21:44:48.148 -> EVENT: Clash ON millis=311740
21:44:48.148 -> unit = 6 vol = 0.50, Playing aa_Juansith/Red_Five/clsh/clsh09.wav
21:44:48.148 -> channels: 1 rate: 44100 bits: 16
21:44:48.402 -> EVENT: Clash ON millis=312007
21:44:48.402 -> unit = 4 vol = 0.50, Playing aa_Juansith/Red_Five/clsh/clsh06.wav
21:44:48.402 -> channels: 1 rate: 44100 bits: 16
21:44:48.684 -> EVENT: Clash ON millis=312277
21:44:48.684 -> unit = 5 vol = 0.50, Playing aa_Juansith/Red_Five/clsh/clsh09.wav
21:44:48.684 -> channels: 1 rate: 44100 bits: 16
21:44:48.958 -> EVENT: Clash ON millis=312551
21:44:48.958 -> unit = 0 vol = 0.50, Playing aa_Juansith/Red_Five/clsh/clsh19.wav
21:44:48.958 -> channels: 1 rate: 44100 bits: 16
21:44:49.246 -> EVENT: Clash ON millis=312837
21:44:49.246 -> ************************** Out of WAV players! Getting more...
21:44:49.246 -> *************************** Killing off aa_Juansith/Red_Five/clsh/clsh09.wav
21:44:49.246 -> unit = 6 vol = 0.50, Playing aa_Juansith/Red_Five/clsh/clsh12.wav
21:44:49.246 -> channels: 1 rate: 44100 bits: 16
21:44:49.493 -> EVENT: Clash ON millis=313109
21:44:49.493 -> ************************** Out of WAV players! Getting more...
21:44:49.493 -> *************************** Killing off aa_Juansith/Red_Five/clsh/clsh06.wav
21:44:49.529 -> unit = 4 vol = 0.50, Playing aa_Juansith/Red_Five/clsh/clsh09.wav
21:44:49.529 -> channels: 1 rate: 44100 bits: 16
21:44:49.773 -> EVENT: Clash ON millis=313376
21:44:49.773 -> ************************** Out of WAV players! Getting more...
21:44:49.773 -> *************************** Killing off aa_Juansith/Red_Five/clsh/clsh09.wav
21:44:49.773 -> unit = 5 vol = 0.50, Playing aa_Juansith/Red_Five/clsh/clsh10.wav
21:44:49.808 -> channels: 1 rate: 44100 bits: 16

```

---

<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 4, 2022, 3:04am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/12 "2022-02-04T03:04:11Z")

</div>

Video. I don’t think buttons can even spam this fast, and it’s handled great!

[![](https://img.youtube.com/vi/M1R25apdK0g/maxresdefault.jpg "Blast spamming ProffieOS no duds, no lag.") ](https://www.youtube.com/watch?v=M1R25apdK0g)

---

<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 4, 2022, 4:40am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/13 "2022-02-04T04:40:55Z")

</div>

So this is the good case though.  
What happens if you tried to do this with like force quotes or something long?  
I’m not sure if we can just make this the default for everything all the time.

---

<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 4, 2022, 5:54am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/14 "2022-02-04T05:54:34Z")

</div>

Works like a charm. I have a 7 second Death Star Destruction and “Use the force, Luke” as force01 and force02. I spammed the bejeezus out of it for 10 secs straight and it consistently played something on each command.

---

<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 4, 2022, 5:55am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/15 "2022-02-04T05:55:38Z")

</div>

Ok, but did it sound good? Or could you hear stuff getting interrupted?

---

<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 4, 2022, 6:02am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/16 "2022-02-04T06:02:55Z")

</div>

It does not sound…NOT ok. Ya know, it sounds like triggering the same 2 sounds million times.  
Use the…use the.force force boom boom use use the force Luke.  
It sounds like expected. Blaster block sounds seem “all there”, nothing unnatural about lost tail ends at all in perception.  
In my opinion it’s right, and with the goal being to HAVE an event on button press, not “duds”, it’s working great here. No pops or clicks, no gaps, and crazy good in the responsive department.  
Of course someone else should try it. Results may vary? But looking good to me.

---

<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 4, 2022, 6:04am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/17 "2022-02-04T06:04:34Z")

</div>

Aaaaaaand as soon as I hit return on that post and used the actual saber buttons for more testing. I got a NULL POINTER and squee of death. ☹

_Edit_- one time occurance so far.

---

<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 4, 2022, 7:17am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/18 "2022-02-04T07:17:13Z")

</div>

@Afrojedi @A_Rogue_Child @Driftrotor @astromech  
You guys are usually down for testing things. Anyone feel like swapping out lines 233-243 in sound/hybrid\_font.h with the last posted code block above and see how it does for you?

---

<div class="post-metadata">

**Author:** ![Afrojedi](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/afrojedi/32/218_2.png) [@Afrojedi](https://crucible.hubbe.net/u/Afrojedi)\
**Post date:** [February 4, 2022, 7:19am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/19 "2022-02-04T07:19:45Z")

</div>

I would love to but my usb connector still needs to be fixed. so i won’t be able to flash my saber.

---

<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 4, 2022, 7:21am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/20 "2022-02-04T07:21:14Z")

</div>

I thought you had more than one saber by now?

---

<div class="post-metadata">

**Author:** ![Afrojedi](https://crucible.hubbe.net/user_avatar/crucible.hubbe.net/afrojedi/32/218_2.png) [@Afrojedi](https://crucible.hubbe.net/u/Afrojedi)\
**Post date:** [February 4, 2022, 7:25am UTC](https://crucible.hubbe.net/t/proffieos-v7-x-feature-discussions-freeing-wavplayer/1350/21 "2022-02-04T07:25:52Z")

</div>

yeah I should but my workbench was taken over. so i kind of stopped, i need to get back on it. but being a big woose doesn’t help.

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