Thanks, Kjell!
After a lot of tries, I finally managed to get something working without it sounding like a Geiger counter.
I had to modify the BaseNoteNr, because once the sound is launched with a NoteNr, it can’t be changed afterward.
So here’s my little sound engine toy, based on your example:
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
<OnLoaded>
<ZExpression>
<Expression>
<![CDATA[PlayerSpeed = 0;
PlayerSpeedMin = 55;
PlayerSpeedMax = 200;]]>
</Expression>
</ZExpression>
</OnLoaded>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[if (Accelerate) PlayerSpeed += (PlayerSpeedMax - PlayerSpeed) * App.DeltaTime;
else PlayerSpeed += (PlayerSpeedMin - PlayerSpeed) * 4 * App.DeltaTime;
//trace(intToStr(PlayerSpeed));
Sound_Acceleration.BaseNoteNr = clamp(PlayerSpeed, 0, 100) * 4;
NoiseSound.BaseNoteNr = clamp(PlayerSpeed * 0.4, 0, 80);
Accelerate = 0;]]>
</Expression>
</ZExpression>
<KeyPress Comment="S" Keys="S">
<OnPressed>
<ZExpression Expression="Accelerate = 1;"/>
</OnPressed>
<OnKeyUp>
<ZExpression>
<Expression>
<![CDATA[// Stop sound by setting length to 0.
NoiseSound.Length = 0;]]>
</Expression>
</ZExpression>
</OnKeyUp>
<OnKeyDown>
<ZExpression>
<Expression>
<![CDATA[// Since ZGE doesn't have a INF constant, cast the bits for INF instead.
NoiseSound.Length = reinterpret_cast<float>(0x7F800000);
@PlaySound(
Sound: NoiseSound,
NoteNr: 0,
ByReference: 1
);]]>
</Expression>
</ZExpression>
</OnKeyDown>
</KeyPress>
<KeyPress Comment="D" Keys="D">
<OnPressed>
<ZExpression>
<Expression>
<![CDATA[Accelerate = 1;
if (App.Time > timer_acceleration) {
// To avoid repeting the sound like crazy on high framerate devices
Timer_acceleration = App.Time + 0.01;
// Max volume is low because sounds overlaps and cumulate volume
Sound_Acceleration.Volume = clamp(PlayerSpeed * 0.01, 0, 0.3);
@PlaySound(
Sound: Sound_Acceleration,
NoteNr: 0//clamp(PlayerSpeed, 0, 100) * 4
);
}]]>
</Expression>
</ZExpression>
</OnPressed>
</KeyPress>
</OnUpdate>
<Content>
<Sound Name="NoiseSound" Length="0" Volume="1" BaseNoteNr="22" Osc1Waveform="2"/>
<Sound Name="Sound_Acceleration" Length="0.5" Volume="0.3" BaseNoteNr="220.0001" Osc1Waveform="2" UseFilter="1" FilterCutoff="0.1598" FilterQ="0.7992" Mod0Active="1" Mod0Destination="11" Mod0Amount="1" Mod1Active="1" Mod1Destination="2" Mod1Amount="0.15" Mod2Active="1" Mod2Source="1" Mod2Destination="1" Mod2Amount="1" Env0Active="1" Env0AttackTime="2.12" Env0DecayTime="5" Env0ReleaseTime="5"/>
<Variable Name="timer_acceleration"/>
<Variable Name="PlayerSpeed"/>
<Variable Name="PlayerSpeedMin"/>
<Variable Name="PlayerSpeedMax"/>
<Variable Name="Accelerate" Type="4"/>
</Content>
</ZApplication>
Press D to play the sound the way I used it for years in Omeganaut. I added a timer so that the pitch and volume no longer vary depending on the hardware.
Press S to play your noise sound, with a note effect tied to the acceleration. I’m still unsure how to handle deceleration though.
Should I set the length to 0.5 upon release and add an envelope?
Or should I keep playing the sound constantly, regardless of whether the player is accelerating?
Also, both sounds can play at the same time without issues. So I really wonder why I implemented all those Sound_Channel switches in the first place… I don’t think Sound_Channel does what I originally thought it did
Edit:
By the way, there is a bug in preview mode where, if we run, play the D sound, stop, wait a bit, and run again, the D sound isn't working anymore. It's not always the case. And the only way I managed to recover from that is to close and reopen ZGameEditor...
Edit 2:
I just realized I could do the timer thing simply by setting ReplayDelay:
Code: Select all
@PlaySound(
Sound: Sound_Acceleration,
ReplayDelay: 0.01,
NoteNr: 0
);