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.
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;
}
1 Like
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…”.
1 Like
confirmed, working spot on.
i spammed for more than a minute with no issues!
man that was one hell of a blaster battle!
ooooo! can you send me them please?! (would put a smile on my dads face!)
1 Like
Great, thanks.
@profezzorn what do you think?
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.
1 Like
@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
@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?
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 } ?
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.
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);
}
}
I mentioned above it’s only going to work on OS6.
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.
2 Likes
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?
It’s absolutely possible, but it’s a little more complicated, and the current code posted in this thread doesn’t do that.
1 Like