41d65d6346284ff5789483c31da521cbbb22baa1
5
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ce1c0517aa |
M3: an instrument for each voice
Play loads a patch per channel before a note is played: an oboe for the
melody, strings under it, a square wave for the bass and a kalimba for
the arpeggio. It reads a count and that many parameter and value pairs -
the format SoundPatch writes - and understands nothing else about them,
which keeps SoundPatch the only thing that knows what soundThing's JSON
means.
FOUR PATCHES CAN BE UP AT ONCE, and that is the whole rung. It is the
first use of
|
||
|
|
388faafd04 |
A thruster you can hear, and a latch on arriving and leaving
Three patches, and the last of the sounds that were asked for. The thruster bangs when it lights and rumbles while it burns. The rumble is this game's first HELD note: its gate goes down when a thruster lights and does not come up until every one is out. Only the edges matter - a rumble restruck every frame would never get past its own attack, and a bang struck every frame is a buzz - and the condition is the flames': a held button with a dry tank is a pilot doing nothing. Arriving latches two notes quickly. Middle C then the C above for taking hold of the station, the same pair reversed for letting go, and two octaves lower for the ground - the same shape in a different register, because setting down and taking hold are the same kind of event. The second note is PENDING rather than played: at an undocking the pilot is mid-burn, and stopping the world for an eighth of a second to fit a note in would be felt as the controls sticking. Where the game is stopping anyway, runPend simply pumps it out. Four channels for five sounds. The bang and the latch share one, because a lander arriving either arrives or does not, and a crash ends the run. That leaves the thruster its two, which it needs: a held note struck on the same channel as the ignition bang would cut the bang off at the moment it was meant to be heard. ---- A held note outlives the loop that was holding it ---- Landing while the thruster was still down ended the flying and then waited to be told the message had been read, so the frame that would have noticed the button coming up never ran. The engine roared under the verdict and went on roaring until the machine stopped. Anything that stops to wait hushes it now, and forgets last frame with it, so a thruster still held when the waiting ends counts as lighting again. ---- Three checks that had to be rebuilt around the new noise ---- A landing is not silent any more, so the crash is measured against the second BEFORE it rather than against a quiet landing. The dust samples moved eight frames later, because the latch plays first. And the warning check lost its measure twice: counting bursts could not tell a beep from a nag, and measuring total length stopped working the day the thruster got a rumble. It burns, stops, and listens AFTER - warned once there is nothing left, nagging the last beep is still fading. Nought against 5,679. |
||
|
|
6fe898b5fc |
A quarter-tank warning that says it once, and a gauge that keeps saying it
Two halves of the same number. The warning is the moment it happened and the colour is how things stand: it fires on the way down through a quarter of a tank and then holds its peace, and the gauge stays red until a base fills the lander up, which also allows the warning again. Once, because a lander is at its most careful in the last few seconds before it touches, and something repeating in its ear through that is not a warning, it is a distraction. Checked where the fuel actually moves rather than once a frame - the tank only changes in takeFuel and payFuel, so there is nowhere else it can cross a threshold. Channel two, with the crash on three. Separate channels rather than one reused, because a crash while the warning is still sounding should not cut it off, and on a machine with four voices there is no reason to be clever. Half and a tenth are the obvious next thresholds and are deliberately not here: one is enough to find out whether being told at all is welcome. ---- And the crash sound is the one that was designed for it ---- Crash.json, which carries voice_gate itself, so the program's own trigger write is gone - it would have masked a deliberate choice rather than backing one up. The note moved from 24 to 60 by ear, and the comment saying it was low went with it. ---- A check that could not tell a beep from a nag ---- Counting bursts of sound cannot: without the latch the warning fires every tick the tank drops, far faster than the sound decays, so the beeps run into each other and a burst counter sees one long burst either way. It measures the LENGTH now - 26,944 samples against 490,348 - which is the difference between six tenths of a second and ten seconds of it. |
||
|
|
de765267c5 |
Lunar Porter's crash is a designed sound now, not a guessed one
Crash1.json, made in soundThing and converted by SoundPatch. Two noise oscillators fifteen cents apart, a filter opened 11.6 kHz by the modulation envelope, and the LEVEL shaped by that same envelope rather than by the amplitude one - which is exactly the freedom the routed level was for, and not a thing the engine could express a week ago. It peaks at 10,501 and is gone in about six tenths of a second, inside the eight tenths the pieces are in the air. The guessed one wandered between 1600 and 8200 and sounded like a drain. The patch predates the gate field, so the program's own trigger write is what makes it a one-shot - which is the argument for having put it there rather than leaving it to the patch. LowFuel.json is here too, saved from the newer soundThing with the gate and LFO mode in it, and is not wired to anything yet. Both JSONs live beside the tables they produce. The build has never needed soundThing and still does not, but a sound can now be regenerated, or simply read, without going to find the editor first. |
||
|
|
a8b6b09a59 |
SoundPatch: design a sound where it can be heard, then convert it
The bang was guessed at directly in bytes and came out as a low gurgle, which is what guessing at bytes gets you: a cutoff of 40 looks small and is 57 Hz, so the filter sweep ended almost shut. Voyager's sound device is soundThing's voice engine with the editor taken off, so a patch designed in soundThing - where there is a screen, a keyboard and a pair of ears - makes the same sound here. What differs is only how it arrives. SoundPatch converts one into the other. Every parameter the device takes is a documented function of a natural value and all of them invert: times are squared into four seconds, cutoff and rate are exponential, depths and detune are centred on 128. It writes a table of a count and that many parameter and value pairs, and playPatch hands it to the device - so every sound after this costs a table and a call rather than forty lines of its own. Two things the conversion has to say out loud. soundThing has no field for the level routing, because there it is always the amplitude envelope, so the table says so explicitly - a channel keeps its patch between notes and a leftover from a previous one would otherwise be carried in. And a field the tool does not recognise STOPS it: a patch format that has moved on would otherwise produce a table that quietly means something else. THE BUILD DOES NOT DEPEND ON IT. soundThing lives in its own repository and is not needed to build anything here; the tables are checked in and the tool is for when a sound is being changed. Lander's crash now plays Kick808 as a stand-in until a bang is designed for it, and the difference is the point: the hand-guessed patch wandered between 1600 and 8200 for eight tenths of a second, and this decays 3492, 2743, 2037, 1515, 1040, 614, 87, nothing. The docs check caught the tool count in two manuals, which is what it is for. |