Not so crazy - OLED durations from sound file length

So I’m working on blaster stuff, and additional images for OLED.
Particularly, Self-destruct. I thought it would make sense to have the duration listen to the file length instead of a fixed ProffieOSDestructImageDuration for example, because different fonts can have different sounds.
Having a hard time figuring this out.
I guess I just don’t know the right things to call.

GetCurrentEffectLength(); seems to return a different file’s time than the one triggered in the prop’s SB_EFFECT, and I can’t figure out how to print the current effect to see which it’s getting from.
I can print the length, but not which effect.
This is what I’ve tried in ssd1306.h:

  void SB_Effect(EffectType effect, float location) override {
    switch (effect) {
// other cases are all here
      case EFFECT_USER1: {
        float len = hybrid_font.GetCurrentEffectLength();
        ShowFile(&IMG_destruct, len * 1000);
        STDOUT.println(len);
       // ShowFile(&IMG_destruct, font_config.ProffieOSDestructImageDuration);
        return;
      }
        break;

      default: break;
    }
  }

The triggered sound, destruct.wav, is 10 seconds long. But I’m getting a returned len of like 1.2 or .82… and whatison shows the last few played might be getting chosen (like boot or out, which are more like those lengths).
Best I can think is that GetCurrentEffectLength(); is too early and not picking up the destruct.wav from EFFECT_USER1. Would it need to wait a moment?
Other attempts like:
STDOUT.println(current_effect_);' STDOUT.println(GetEffect()); STDOUT.println(GetName());`
don’t work due to template parameters and other errors.
Other ways involve too specific things that would depend on the user having the file defined in a prop with EFFECT(destruct); and susequently play the wav directly, like I tried something like:

        if (SFX_destruct) {                                                          // cant depend on this being declared in prop
          ShowFile(&IMG_destruct, 1000 * hybrid_font.PlayPolyphonic(&SFX_destruct)->length());
        } else {
          ShowFile(&IMG_destruct, font_config.ProffieOSDestructImageDuration);
        }

Just missing a piece or two to this puzzle, while trying to keep in mind that it needs to be kept generic enough that any blaster prop can still work with it,
and doesn’t take up memory for all users if not needed.
Any insight would be appreciated to get cool stuff working!

You have to change SB_Effect to SB_Effect2 to get access to the sound lengths.
After you do that, you can find the sound length in SaberBase::sound_length and the file number (if you need it) in SaberBase::sound_number.

Thanks, but I’m not that smart. No idea about SB_Effect2, but this works, thanks!

  void SB_Effect2(EffectType effect, float location) override {
    switch (effect) {
      case EFFECT_USER1: {
         ShowFile(&IMG_destruct, SaberBase::sound_length * 1000);
          return;
      }
    }
  } 

So now the question is, since this has a specific new IMG file, if this were to be officially submitted, do you think USER1 is right, or would a more descriptive, specific EFFECT be better, such as EFFECT_DESTRUCT ? (Trying to not unnecessarily use memory)

The backstory here is I made this work both ways - as is now as a one-shot thing, and also a version using the LOCKUP_ARMED version that detonator had already laid out. (with some modification since there’s no button being held, it’s a set-it-and-run-away sort of thing)
However, I think it’s great to be able to auto-time the blade effect for the overload to the sound using WavLen, which I couldn’t do with the Lockup version.
SO since no button held for lockup and no WavLen, I am leaning toward this one-shot route.

How about using OffType::OFF_BLAST ?
This is what the detonator prop uses to blow itself up.
Seems like if you make the self-destruct work similar to the detonator, then if someone puts a display on a detonator, that will work too.

Welll for the blaster prop, I removed Off(OFF_BLAST); and just stuck in

         case NEXT_ACTION_BLOW:
        hybrid_font.PlayCommon(&SFX_boom);
          break;

so the user doesn’t need to manually power on the blaster after boom…it’s just still on and ready to go. Not logical since it’s in smithereens at that point, but ¯_(ツ)_/¯

I can PR some stuff for review if that’s cool

Doesn’t that mean that if your blaster has a hum, it will continue after blowing up?

Sure, but I won’t merge it until I’m semi-confident that there aren’t more OLED fixes needed for 6.x.
(This would be come a 7.x feature, so there is no rush…)

Yeah… I guess since I bothered making power on/off always available, might as well use it.
Off(OFF_BLAST) it is!

@profezzorn here’s what I got.

.

Trying to figure out how to show the font image on preset change, but since it’s already on it doesn’t want to do it.

I also forked the blaster prop. added in volume menu, on demand battery level with spoken battery level, quote player, couple other things too. Calling it blaster_BC for now. Of course, no time frame. PR primarily for review and tips and tricks you might have for now. Thanks.

1 Like

Continuing on this effort.
Is there any reason you can think why this isn’t working?
You had said preon should just always auto sync to the sound, so the SB_Effect2() part could just be:

      case EFFECT_PREON:
        ShowFile(&IMG_preon, round(SaberBase::sound_length * 1000));                                                                      
        return;

but it doesn’t show for the duration. In fact, I removed the default duration set in saber base, and there’s no entry in the font config.ini, so I have no idea where it’s getting it’s duration from, but it ends before a long preon finishes the sound.

Meanwhile, this postoff works perfectly, and if preon is done the same way, it does as well.

      case EFFECT_POSTOFF:
        dur = (font_config.ProffieOSPstoffImageDuration == 0) ? SaberBase::sound_length * 1000 : font_config.ProffieOSPstoffImageDuration;
        ShowFile(&IMG_pstoff, round(dur));                                                                                                
        return;

I don’t see a reason why the second one would work and the first one wouldn’t. Maybe the reason is in some piece of code that you haven’t shown…

oops. had a non-looping image for preon.
works as intended…when you do it right.

1 Like

So now that looping images can sync to wav file length, maybe phase 2 of this could be making non-looping animations work as well by altering the frames per second?
Could we do some math and figure out how to do that in this part?

Seems weird to alter the FPS, but I suppose it might work in some cases.
I was thinking that it might be cool to have an option to have a non-looping animation interrupted when the wav is done though. (Without changing the frame rate.)

Well the goal would be primarily to have non-looped animated images for timed events (like in.wav retraction animations) be able to sync. So that a depleting bar, or spinning thing comes to a stop etc… could do it in time with the sound ending.
So they should complete, not be interrupted.
Think of like a self destruct sound that builds up an “overload” progress bar.
If there are different length sounds, the bar would need to adjust so it finishes at the right time.

We also have the ability to create one animation per wav file and link them.
It’s obviously more complicated, and if done by hand, a lot more labor-intensive. But doing it that way would let you sync up the self destruct with the actual explosion, rather than the length of the file.

Maybe some python scripts? Like, I’m imagining a tool that can take a list of files and a pattern for how to generate the animation from those files, then it would find the point of highest volume in the wav file and generate an animation based on that.

Does file type matter as far as keeping sequence of effects?
Like would
clsh01.bmp
clsh02.bmp
clsh03.PBM
work?
I can’t test at the moment.
I ask because I have never had success making non-looping .bmp files.
PBM seems to be the only way.

It matters, all files belonging to the same effect are assumed to follow the same pattern.

I can look into the non-looping bmp problem.