Fold soundThing's changes back down, and expose the two new switches
The three changes that went up came back as part of soundThing, along with two more that they made possible. The engine here is now b73e5c0 character for character, except that em-dashes and arrows in comments are written as ASCII because this tree is ASCII only - a local rule, not an improvement, and not sent up. So synth.h's "what was changed" list is gone. There is nothing to list: what has to be kept current is only that if either copy changes, the other one has to be told. ---- What came back ---- A VOICE CAN END ITSELF. Naming the level's source said what shapes a voice; nothing said what ends one, so the only thing that could ever finish one was a key coming up. A game is nearly all one-shots and not one of them wants its length decided by how long a note was held. Exposed as parameter 0x51: 0 gated, 1 triggered. AND A ONE-SHOT IS THE SAME ONE-SHOT TWICE. A triggered voice re-arms its oscillators, and an LFO can be told to start over with each voice - parameter 3 of either LFO. Both halves are needed and the check proves it: with the LFO left free, two triggered hits still differ. Their note warned that whatever applies a patch to a channel has to set these or they hold synthInit's defaults. Checked: Voyager never calls synthSyncVoices, so their 0001 is a no-op here as they predicted, and nothing reaches into an LFO's phase, so the struct split is safe. ---- What it is for ---- Lander's crash is a triggered voice now, so boomOff is gone. Nothing has to remember to end a bang. SoundPatch learnt voice_levelSource, voice_gate and lfo<N>_mode, which the new soundThing writes - without that it would have refused every patch saved from it, since an unknown field stops the tool on purpose. A patch from before those fields still converts, and says in its own comments that it predates the level routing. Three checks, each seen to fail on its own break: a gated voice still sounding with nothing holding it, a triggered one down to nothing with no gate ever dropped, and two hits identical sample for sample. One test bug worth keeping: the first version of the repeatability check struck the second note while the first was still ringing, so what it found and compared as "the second hit" was a point in the middle of the first one's tail. It now looks for sound after SILENCE rather than sound after an offset.
This commit is contained in:
@@ -1026,6 +1026,7 @@ The high nibble says which part of the voice, the low nibble which setting of it
|
||||
| 0x30 - 0x3F | The modulation envelope. |
|
||||
| 0x40 - 0x4F | The filter. |
|
||||
| 0x50 | What shapes the channel's level. |
|
||||
| 0x51 | Whether a note waits to be let go of. |
|
||||
| 0x60 - 0x6F | LFO 0. |
|
||||
| 0x70 - 0x7F | LFO 1. |
|
||||
|
||||
@@ -1062,6 +1063,7 @@ The high nibble says which part of the voice, the low nibble which setting of it
|
||||
| 0 | On, or off at zero. |
|
||||
| 1 | Waveform, from the same six. |
|
||||
| 2 | Rate. |
|
||||
| 3 | 0 free, 1 starts over with every voice. See The Same Sound Twice. |
|
||||
|
||||
Anywhere a setting asks *what modulates* something, the answer is one of these:
|
||||
|
||||
@@ -1107,6 +1109,45 @@ output, so an envelope routed somewhere useful - opening the filter, bending a p
|
||||
has to be shaped like something you would want to hear, and a snare that wants a click of
|
||||
filter sweep and a flat body cannot have both.
|
||||
|
||||
### Struck Or Held:
|
||||
|
||||
Setting 0x51 says whether a note waits to be let go of: **0 gated**, which is how it has always
|
||||
been, and **1 triggered**.
|
||||
|
||||
A gated voice lasts as long as something keeps hold of it. Writing the gate port ends it, and
|
||||
the release begins there. That is what a keyboard is, and it is right for anything a player
|
||||
holds down.
|
||||
|
||||
A triggered voice is struck and then plays its own length. Nothing has to remember to end it,
|
||||
and the gate port need never be written at all. Sustain and release have no meaning in one,
|
||||
because both of them are answers to a question about a key that is not being asked - so in a
|
||||
triggered voice the decay runs to nothing rather than stopping at the sustain level, or a
|
||||
patch with any sustain at all would hold the voice open for ever.
|
||||
|
||||
**A game is nearly all one-shots.** A bang, a pickup, a door: not one of them wants its length
|
||||
decided by how long a note was held, and every one of them would otherwise need a program to
|
||||
come back later and let go of it.
|
||||
|
||||
### The Same Sound Twice:
|
||||
|
||||
Setting 3 of either LFO says whether it starts over when a voice does: **0 free**, which is how
|
||||
it has always been, and **1 retriggered**.
|
||||
|
||||
A free LFO is one cycle running under everything, which is what vibrato across a held chord
|
||||
wants. A retriggered one starts at the beginning of its shape every time a voice begins, and
|
||||
the cycle belongs to the voice rather than to the device - so retriggering costs nothing to a
|
||||
channel not using it.
|
||||
|
||||
This is the other half of a repeatable sound effect, and **neither half is sufficient alone**.
|
||||
A triggered voice re-arms its oscillators, so a hit begins at the same point in its waveform
|
||||
every time and a noise source draws the same noise. But an LFO left free is wherever the wall
|
||||
clock happened to leave it, so the same drum caught at a different moment is still a different
|
||||
drum. Set both and a one-shot is the same one-shot, sample for sample.
|
||||
|
||||
The consequence is worth knowing rather than fixing: a retriggered noise source is *bit*
|
||||
repeatable, so every hit is literally the same noise, the way a sampler is. On a hi-hat that
|
||||
can read as machine-gunny. Where variation is wanted, leave that LFO or that voice free.
|
||||
|
||||
### Knowing When It Has Finished:
|
||||
|
||||
The status port's bit 0 is set while any channel is still sounding, so a routine can wait for
|
||||
|
||||
Reference in New Issue
Block a user