尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
Norilsk: a firmware for the M-VAVE FM-1 for ambient hellscapes, barren and grim atmospheres and noise -- everything drawn at random, wired at random, torn apart at will.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A firmware for the M-VAVE FM-1 for inhospitable soundscapes.
Norilsk is not made for musical niceties. There are no pretty chords here, no polite arpeggios, no presets that flatter. It is made for ambient hellscapes and barren, grim atmospheres: drones that never resolve, textures that corrode as they hold, noise that does not apologise. Sound for places nobody should have to live in.
It is named after Norilsk, the nickel-smelting city above the Arctic Circle: built by prisoners of the Gulag, closed to outsiders, sunk in polar night for weeks each winter, its air thick with sulphur dioxide, its rivers turned red by the works upstream. Every sound here is drawn at random, wired at random into effects drawn at random, and torn apart at will: as fit for noise experiments as for slow, dark ambient.
Website, browser installer and session backup: https://nzimas.github.io/norilsk/
State: build 48. Each build is described in CHANGELOG.md. Norilsk was called Molecular until build 17.
SHIFT is the rightmost black key. Black keys are contextual: a key with a job in the current view glows dimly (lit when on); a key with none does nothing and stays dark. "Hold" means 0.8 s unless stated otherwise.
| To | Do this |
|---|---|
| Choose generator 1, 2 or 3 (keys play it) | Press FX, SEL or ENV |
| Choose effect slot (lane) 1, 2 or 3 | Press LFO, EDIT or GLO |
| Mute or unmute a slot | Hold its button |
| Mute fade in / fade out of a generator (OFF to 60 s) | SHIFT + its button, let go: its page. KNOB 1 MUTE FADE IN, KNOB 2 MUTE FADE OUT. Its button to leave |
| Level / pan of chosen generator (pan moves its lane too) | Turn SELECT / ALGORITHM |
| Link two generators (first modulates second) | Hold SHIFT, hold first generator's button, then hold second's. Repeat to unlink |
| To | Do this |
|---|---|
| Play | White keys: chosen generator, in current scale. Keys playing the scale's root glow dimly |
| Play from a MIDI keyboard or computer | USB or the TRS MIDI IN jack: channels 1, 2, 3 play generators 1, 2, 3; channel 16 the chosen one (GLOBAL SETUP changes them) |
| Change octave (−3 to +3) | OCT− / OCT+ |
| Latch a note | Hold white key, press SHIFT (key stays lit) |
| Release a latched note | Hold SHIFT, press lit key |
| Set root and scale | ARP opens SCALE page: SELECT root, ALGORITHM scale (23). ARP again to leave |
| Random root and scale | SHIFT + ARP (let go at once; held, it opens PRESETS) |
| DISINTEGRATOR of generator being played (0 to 100) | KNOB 1 |
| Master DRIVE (0 off to 100) | SHIFT + KNOB 1 |
| FX MIX of chosen lane, dry to wet | KNOB 2 |
| Delay send / reverb send of generator being played | KNOB 3 / KNOB 4 |
| Output level | MASTER |
| To | Do this |
|---|---|
| New sound for chosen generator (with its lane's effects) | HOME |
| New effect chain for chosen lane | Choose the effect slot, press HOME |
| New, but same family (or same recipe) | SHIFT + HOME |
| Pick a family (generator) or recipe (effect slot) | Hold SHIFT, turn PRESETS: alphabetical list, four per page. Then SHIFT + HOME draws a new one of it |
| Everything new, all six slots | Hold HOME |
| New cables only | 1st black key (REWIRE) |
| New values only (effects), or new sound of same family (generator) | SHIFT + 1st black key (RAND PARAMS) |
| Bias draws towards harsh, torn material | 2nd black key: ABRASIVE path on/off |
| Bias draws towards dark ambient and drones | 3rd black key: DARK path on/off |
| Draw industrial percussion: struck metal, machines | 4th black key: MACHINE path on/off |
| To | Do this |
|---|---|
| Delay settings (TIME, FEEDBACK, DAMP, MIX) | SEQ, then KNOB 1 to 4 |
| Reverb settings (SIZE, DECAY, DAMP, MIX) | SEQ twice, then KNOB 1 to 4 |
| Modulation of chosen slot | SEQ three times. PRESETS picks LFO 1, LFO 2 or route A to H; KNOB 1 to 4 set its values |
| Back to playing | SEQ a fourth time |
| A generator's page (MUTE FADE IN, MUTE FADE OUT) | SHIFT + its button, then KNOB 1 / KNOB 2. Its button to leave |
| Random modulation for chosen slot | SHIFT + SEQ |
| GLOBAL SETUP (MIDI, USB audio) | Hold SHIFT, hold SAVE 0.8 s. PRESETS moves, SAVE chooses, SHIFT + SAVE goes back (from the top: out) |
| To | Do this |
|---|---|
| Record a loop | REC to arm (first note starts it), REC again to end (plays at once) |
| Overdub | REC while loops play |
| Clear loops | Hold REC 1 s |
| VARY on/off | SHIFT + REC |
| Stop or restart loops | PLAY |
| Stop or start all generators' loops | SHIFT + PLAY |
| Take loops out or bring them back | Hold PLAY, press white keys |
| REVERSE, PENDULUM, RANDOM, HALF SPEED, DOUBLE SPEED | Hold PLAY, press 4th to 8th black key (again: off) |
| Move loops one scale step down / up | SHIFT + OCT− / OCT+ (hold a generator's button too for its loops only) |
| To | Do this |
|---|---|
| Open SNAPSHOTS page | SAVE (again, or a slot button, to leave) |
| Recall snapshot | Press and release its white key |
| Store current state | Hold its white key 0.8 s, or move frame with PRESETS and hold SAVE |
| Empty snapshot | Hold SHIFT, hold its white key |
| Morph time (0 to 30 s) | KNOB 1 on SNAPSHOTS page |
| To | Do this |
|---|---|
| Save while playing | Hold SAVE (saves into loaded session; with none loaded, offers first empty slot) |
| Clear: a new session in place of the one loaded | 10th black key (beside SHIFT): NEW SESSION? PRESETS to YES, SAVE. The saved one stays in the flash until you save over it |
| Open SESSIONS list | SHIFT + SAVE (let go at once; held, it opens GLOBAL SETUP) |
| Pick a session | PRESETS |
| Open its page (BACK, LOAD or NEW, SAVE, COPY, DELETE) | SAVE |
| Pick and run a row | PRESETS, then SAVE |
| Go back a level | SHIFT + SAVE |
| To | Do this |
|---|---|
| Open PRESETS for the generator being played | Hold SHIFT, hold ARP 0.8 s |
| Pick a slot (64) | PRESETS |
| Load it into the generator | ARP or SAVE (back to playing) |
| Save the generator into it | Hold ARP or SAVE. Over a full slot: OVERWRITE? PRESETS to YES, ARP |
| Leave | SHIFT + ARP, SHIFT + SAVE or a slot button |
| To | Do this |
|---|---|
| Rescue mode (install again) | Hold OCT− while powering on |
| Chip's own updater | Hold OCT− and OCT+ 5 s |
Norilsk has three generators, three effect slots, a master delay and a plate reverb. I think of the generators as furnaces: each burns a sound. Effect slots are the pipes the sound runs through; delay and reverb are the air the fumes end up in. In practice:
CPU core 1 renders the voices. Core 2 runs the effects, delay and reverb, one block (0.73 ms) behind.
Every sound swells in and keeps moving. However, nothing sounds on once no note is held, latched or looped: released voices fade out within three seconds, and effect slots close two seconds after the last voice. Delay and reverb are the exception: their tails always ring out in full, whatever you let go or mute.
Almost nothing is set by hand at the start. It is drawn at random; your job is to choose, keep, throw again and play. Randomness works at every scale:
Designed for low vision: few words, very large type, high contrast.
Main view is drawn as a place. Smog drifts slowly across the top, with audio load on the left and battery on the right. Below ground, the three effect slots are rusty pipes, one above the other. Each effect is a section between bolted flanges, its name on a dark plate: FLT filter, FLD fold, MU mulaw, SHF shift, MDL modal, STR string, VOX vowel, TAP tape, RVS reverse, SPR spring, GLT glitch, CLD cloud, SCR scream, RNG ring, STV starve, CHB cheb, BNK bank, SMR smear, DIF diffuse, SLW slew, XOR xor, DST dust, WST waveset, XMD xmod, CHS chaos.
Under each name, a band shows the colours of the generators feeding it. Plates fed by the chosen generator are filled with its colour. A section glows hotter while sound passes through it; a muted pipe is cold grey.
At the bottom, the generators are brick furnaces, fire in their mouths in their colours (red, blue, green): brighter while they sound, dark when muted. Chosen slot has a white frame. Cables are not drawn. KNOB 1 shows its value on a full-screen dial.
On the settings pages (DELAY, REVERB, MOD, a generator's page) each setting's name is amber and its value white. The setting just turned is black on white, its name dark amber.
Messages (LANE 2 REWIRED, GEN 1 WIRE, OVERLOAD) cover the top of the screen for a moment. One too wide for a line takes two; a line still too wide drops one size. No word runs off the screen.
Each generator runs an instance of FURNACE, the engine, playing one sound drawn from forty-four families. Four voices are shared by the three generators, and each voice is a complete instance of the engine. Because of this, one sound on two keys never sounds quite the same. Details: FURNACE engine below.
SHIFT + a generator's button, let go, opens its page: GEN 1, GEN 2 or GEN 3 at the top, two settings below.
Each OFF (at once, as before) to 60 s: half-second steps to 10 s, whole seconds above. Both OFF at power-on and in a new session. The fade falls evenly in loudness; the generator's sends to its lane and to the master delay and reverb fade with it. Muted or unmuted again halfway, it turns back from where it is. Kept in snapshots and sessions. A snapshot recalled at once, or a session loaded, sets the mutes at once; a morph glides them over its own time.
The generator's button, or SHIFT + it again, leaves the page. Holding SHIFT with one generator's button and then pressing another still links them (no page).
KNOB 1 while playing sets the DISINTEGRATOR of the generator the keys play, 0 to 100. It is an unstable gate after the sound is made and before its cables, so effects hear it too.
It cuts the sound into pulses of uneven length. Each pulse lets the sound through, gates it down (to silence from 60 upwards), repeats a 10 to 90 ms slice of what was just played, or crushes it (bits and sample rate). A pulse may also throw the dry part across the stereo image.
Higher values give shorter, more irregular pulses, more of them acting, deeper and wider. Every edge is smoothed over about 1.5 ms, so no clicks. At 0 nothing is touched. Each generator keeps its own value in snapshots and sessions.
Ideas from Destroy FX's Skidder and from buffer repeaters; none of their code.
FURNACE started as Tonitor's FM engine and was rebuilt around one goal: sound that is never struck, never still and never exactly the same twice. Struck sound came later, on a path of its own (MACHINE, generation 7).
It works on one voice, one note and one block of 32 samples (0.73 ms at 44.1 kHz) at a time. Everything is integer
maths, because the chip has no floating point; per-sample code runs from RAM. Code: firmware/src/mol.c (voice and
draw), fm6_core.c (operators), wt.c (waves), found_clips.h (found sounds).
Every block goes through these stages, in this order:
A voice ends when its note is released and it has been silent for a quarter of a second, or when operators, body and cloud have nothing left. Separately, generators fade a released voice out within three seconds.
Sixteen 0.6 s clips in flash, 8-bit like the grain buffers, each looping without a seam:
A grain can start anywhere in its clip. Playback rate follows the keys only by a drawn share, so clips are barely
transposed. DEPTHS, AURORA and PLANT take 70 to 100 % of their grains from a clip. Older sounds with a cloud get a
clip one time in three, for 30 to 60 % of their grains. Sources and credits: found/CREDITS.md.
A sound is drawn from four values: family, seed, path and generation. Same values, same sound, bit for bit. This is why sessions store seeds, not sounds. Order of the draw:
A sound keeps the generation it was drawn under, and a generation never changes what it draws. Tests check this with a hash of hundreds of sounds per generation. In practice, a session from an older build sounds exactly as it did. New sounds are always drawn on the newest generation.
| Generation | Added |
|---|---|
| 0 | FM with waves in the operators, grains, twelve families |
| 1 | No pitch bends in bodies (no zaps, no bleeps), tonal ones roughened; no freeze before the body has sounded |
| 2 | Textures and drones only: IMPACT and PULSE no longer drawn; every sound swells in, holds and keeps moving |
| 3 | Hand, grit, eight families |
| 4 | Exciter and body, five families |
| 5 | Found sounds, three families |
| 6 | Eight families; one older sound in four gets other waves (harmonic sets, bells, bent) |
| 7 | Struck: eight families of industrial percussion, drawn only on the MACHINE path. Older families as in 6 |
| 8 | ANVIL, STAMP, RIVET and SHEET strike again while held, on an unstable clock. The rest as in 7 |
| Family | Gen. | What it is |
|---|---|---|
| METAL | 0 | Risset's bells and gongs: many carriers on inharmonic ratios, high partials dying first |
| DRONE | 0 | Slow pairs, near-harmonic, detuned to beat, wandering index |
| BRUIT | 0 | Noise from feedback and high ratios, scattered by a sample-and-hold LFO |
| IMPACT | 0 | Struck body, modulators dying first (not drawn from generation 2) |
| PULSE | 0 | Sound pulsed by its own LFO (not drawn from generation 2) |
| GLASS | 0 | Carriers on bell waves, morphed, barely modulated |
| FORMANT | 0 | CZ approach: carriers bent by their envelopes under a modulator at the fundamental |
| REED | 0 | Saw or square whose width follows its envelope, under a feedback operator |
| CLOUD | 0 | Body under a slow cloud: long grains, pitched, dark, smeared |
| SHATTER | 0 | Body broken into short grains: fast, jittered, reversed, scattered |
| PULSAR | 0 | Sustained body read back one grain per period: formants, sub-harmonics |
| FREEZE | 0 | Body frozen into a cloud a moment after it starts |
| FURNACE | 3 | Low and roaring, crushed, dark cloud over it |
| HUM | 3 | Machine room: carriers fixed near 50 and 100 Hz, beating, XOR'd |
| STATIC | 3 | Feedback noise, crushed hard, stuttering, shattered |
| HOWL | 3 | Formants an octave down under long, dark grains |
| SCRAPE | 3 | Scraping metal: high inharmonic partials, bent grains, held samples |
| DATA | 3 | Glass through bitwise logic, crushed, stuttering, bent pulsars |
| ASH | 3 | Dark drone under sparse, dusty crackle |
| TUNNEL | 3 | Huge dark cloud, fed back, sometimes frozen |
| WIRE | 4 | Stiff wire bowed by friction, operators as the bow arm |
| STEAM |
Four macros, each -64 to 64. At 0 the sound is exactly as drawn. There is no page to set them by hand: the hand moves them, and so do modulation routes (MOD page) aimed at them. Response follows the square root of the knob's travel, so the first part of the turn does the most.
Hand and modulation routes can move the macros at the same time.
Twenty-five effects, two or three per slot. SMEAR to DUST came in build 32, WAVESET, XMOD and CHAOS in build 45; their names are provisional. Delay and plate reverb belong to the master only (since build 30). A session saved with them in a slot loads them as TAPE and SPRING.
| Effect | What it is |
|---|---|
| FILTER | Driven state-variable filter: low-pass, band-pass, high-pass or notch. Resonant to the edge of screaming, never piercing |
| FOLD | Wavefolder, with a second fold and a tone control |
| MULAW | Rate and bit reduction, filter open enough to alias, drive into it |
| SHIFT | Frequency shifter: every partial moved by the same 40 to 900 Hz, tearing the harmony apart |
| MODAL | Three tuned resonators, spread inharmonically, ringing up to Q 325 |
| STRING | Three Karplus-Strong strings on the scale's root, ringing up to 8 s |
| VOWEL | Three formants morphing through vowels, driven |
| TAPE | Echo through a worn head: dropouts, saturation, age, hiss under the sound |
| REVERSE | Windows of the sound played backwards, fed back |
| SPRING | Spring tank, with its chirps |
| GLITCH | Russolo's bent buffers: jumps and stutters through the last 0.74 s, never at another pitch |
| CLOUD | Granular cloud that can freeze what it holds |
| SCREAM | Shaped feedback howl |
| RING | Diode ring modulator modulating itself |
| STARVE | Starved, gated fuzz (after the Fuzz Factory) |
| CHEB | Harmonic re-voicer using Chebyshev polynomials (after Airwindows' Pafnuty) |
| BANK | Inharmonic resonator bank: bar, plate, bell, membrane (after Mutable Instruments' Rings) |
| SMEAR | Sound through twenty random taps, each + or −, over 12 to 46 ms: grainy haze rather than a room (velvet-noise decorrelator) |
| DIFFUSE | Four allpasses in series (lengths from Mutable Instruments' Clouds): blurred edges, no tail of its own |
| SLEW | Limits how far the sound can move in one sample: highs turned into dark, grinding ramps (after Airwindows' Slew) |
| XOR | Sound combined bit by bit (XOR, AND, OR) with itself a moment earlier: broken and digital, but following its shape |
| DUST | Hiss and crackle where the sound moves, none where it is still (after Airwindows' TapeDust) |
| WAVESET | Sound cut at its zero crossings into its own small cycles, replayed a group at a time: repeated, reversed, shuffled or left out (after Trevor Wishart). Grain, never rhythm |
Last three follow what goes in more than their own values: same values on a drone, a cloud and a hiss give three different things.
Thirty-eight recipes decide which effects may stand at each place: SPACE, ECHO, METAL, STRINGS, EROSION, GHOST, SPECTRAL, RESONANT, FOLDS, TELEPHONE, HELL, FACTORY, GLITCH, BROADCAST, ABYSS, RUST, FREEZER, FEEDBACK, FOUNDRY, GONG, SPECTRE, SPUTTER, SMOG, STATIC; with the new effects, SHATTER, MOSAIC, CROSSFIRE, ATTRACTOR, TURBINE.
Twin recipes put one effect twice in a row: MIRRORS (SHIFT), FOLDOVER (FOLD), CLANGOUR (RING), CRUSH (MULAW), OVERTONE (CHEB), SHATTER (WAVESET), CROSSFIRE (XMOD). Second one's values are drawn from the first's and kept apart: shifter going the other way, ring and crusher at another rate, another shape, mode or algorithm. In SWARM (CLOUD), LOOPHOLE (GLITCH), CAVERN (SPRING) and FOG (SMEAR) the second also feeds back into the first. The feedback follows what comes into the lane: no sound in, it dies within about 2 s. Recipe names are provisional.
Every effect falls silent with nothing coming in. None sounds on by itself.
Generator 1 plays through lane 1 only, generator 2 through lane 2, generator 3 through lane 3. Each generator is cabled into the head of its lane, with a small dry share. No cables between lanes. A lane has no pan of its own: it and every effect in it follow its generator's pan (centre, left and right at power-on).
HOME on a generator also draws its lane's chain, so the chain is part of the generator's patch (SHIFT + HOME keeps family and recipe). HOME on an effect slot redraws that lane and keeps its generator. REWIRE inside a lane redraws where the generator enters and which effects also send to the master. Holding HOME draws all three generators and their lanes.
From build 28 to 35 a session could also be MESH: any generator cabled into any effect, effects cabled across slots. In practice it mostly produced smear, so from build 36 there are only lanes. A MESH session loads rewired into lanes, snapshots included, nothing redrawn.
Three black keys bias everything HOME draws, and RAND PARAMS too:
ABRASIVE (2nd black key): gnarly, textural, torn. Favours experimental scenes; harsh families (BRUIT, SHATTER, FURNACE, STATIC, SCRAPE, DATA, METAL); more cables and cross-modulation; torn and crushed recipes; more drive, breakage and crushing in effects.
DARK (3rd black key): dark ambient, drones, introspection, along the lines of Lustmord and the Cold Meat Industry catalogue. Favours the FIELD scene; drones, hums, tunnels, ash and freezes, nothing harsh; spacious and ringing recipes (SPACE, GHOST, ABYSS, FREEZER, RESONANT, GONG and others); darker, less driven values, larger spaces. Also 3 dB quieter.
MACHINE (4th black key): industrial percussion. HOME on a generator draws only the struck families (ANVIL, STAMP, RIVET, SHEET, GEARS, PISTON, RATCHET, FORGE): metal against metal, presses, pistons, gears. No drums. The first four strike at the key, then again while it is held on a very unstable clock: intervals from 40 ms to 2.5 s, clusters, long pauses, each strike at its own level (softer ones darker) -- a percussive texture, nothing to count. The other four are machines: they keep striking on their own while the key is held, each strike a little early or late, the pace wandering, no tempo. Let go, they stop and ring out. (Sounds saved in build 47, generation 7, keep their single strike.) HOME on an effect slot favours rooms, echoes, metal resonances and crushing; not frozen clouds or smoke, which would hold a strike into a drone. The struck families are never drawn on the other paths. SHIFT + HOME on a struck sound keeps its family on any path.
One path at a time. With none on, anything goes (nothing struck). Path is saved with the session and with each snapshot.
Every slot, generator or effect slot, has two LFOs and eight routes, A to H.
SEQ's third page sets them; SHIFT + SEQ draws them at random.
A snapshot is the whole machine. Every slot's sound, effects, values and cables; levels, pans, mutes, mute fades and sends; DISINTEGRATORs; FX MIX; master delay and reverb; modulation; scale and root; octave; path. It also stores how the machine is being played: latched notes, whether each generator's loops are playing, which loops are taken out, their direction and speed, VARY, and moves along the scale. Loop recordings themselves belong to the session. Sixteen snapshots per session.
SAVE opens the SNAPSHOTS page. Release a white key to recall its snapshot. Hold it 0.8 s to store the current state in it. Hold SHIFT as well to empty it.
KNOB 1 on this page sets morph time, 0 to 30 s. A recalled snapshot moves into place over that time. Levels, pans, sends, values and LFOs glide. Sounds cross-fade on voices of their own; effect chains fade out and in, one after the other. Anything without an in-between value switches halfway. The target snapshot's square and key blink until the morph is done.
SHIFT + SAVE opens the SESSIONS list, as on Bigorna: four per page, PRESETS moves through 64 slots. Saved session white, empty slot grey, loaded one marked on its right. SAVE opens the slot's page:
PRESETS moves through the rows, SAVE runs the selected one, SHIFT + SAVE goes back a level. While playing, holding SAVE saves straight into the loaded session. A session holds the machine, its sixteen snapshots, latched notes and every loop, in the FM-1's flash.
Hold SHIFT and hold ARP 0.8 s: the PRESETS page, for the generator being played (its number in its colour at the top right). 64 slots. A preset is one generator's patch: its sound, its lane (effects, values, outs, return), how it is cabled into the lane, its DISINTEGRATOR and its lane's FX MIX. Level, pan, delay and reverb sends, modulation and mute are not part of it: they belong to the mix.
A preset is named by its sound's family and numbered within that family, in slot order: ANVIL 1, ANVIL 2, DRONE 1. Empty slots are grey.
Presets are kept in the flash apart from the sessions, like the global setup, and backed up with them.
Norilsk only writes to blank flash or to its own retired sessions, never over another firmware's data. Other firmware does not return the favour, however: back up your sessions before installing something else.
Each generator has Tonitor's looper: up to ten free-running loops, each on its own clock. No tempo, no grid.
Press REC to arm a loop; the first note starts it. Press REC again to end it; it plays at once. Press REC again while loops play to overdub. A note held across the end of a loop is tied over.
Hold PLAY to show loops on the white keys and take them out or bring them back. This also lights the 4th to 8th black keys: REVERSE, PENDULUM, RANDOM, HALF SPEED, DOUBLE SPEED. SHIFT + OCT moves all loops along the scale; SHIFT + REC turns on VARY.
The website's backup page saves every session on the FM-1 to a file, with the global setup and the presets, and writes them back, from desktop Chrome, Edge or Opera.
From a terminal: tools/fm1_sessions.py lists sessions, tools/fm1_sessions.py save N saves one,
tools/fm1_sessions.py restore FILE writes one back. Page and script only talk to an FM-1 whose USB name is FM-1
Norilsk.
Connected to a computer, the FM-1 is also a class-compliant USB audio interface: no driver needed. It sends 16 bits, 48 kHz (or 44.1 kHz), taken before the MASTER knob: recordings don't follow the headphone level. Code from Tonitor and Bigorna.
GLOBAL SETUP, AUDIO > USB chooses what it sends:
Changing it, the FM-1 leaves USB for a moment and comes back as the new device.
Settings of the machine, not of a session. Hold SHIFT, hold SAVE 0.8 s. PRESETS moves through the list, SAVE chooses or sets, SHIFT + SAVE goes back a level (from the top: out). A slot's button also leaves. Changes are written to the flash on leaving. Sessions and snapshots never change them; the backup page saves them with the sessions.
| Setting | Default |
|---|---|
| MIDI > IN CHAN: GEN 1, 2, 3; AUTO (the generator being played) | 1, 2, 3; 16 |
| MIDI > OUT CHAN: GEN 1, 2, 3 | 1, 2, 3 |
| MIDI > RECEIVE: NOTES, CC | ON, ON |
| MIDI > SEND: NOTES, CC | OFF, OFF |
| MIDI > PORTS: USB IN, TRS IN (the 3.5 mm MIDI IN jack) | ON, ON |
| AUDIO > USB | STEREO |
MIDI in plays each generator on its channel, from USB or the TRS jack. CCs set the generator on that channel:
| CC | Sets |
|---|---|
| 7 | Level |
| 10 | Pan |
| 16 | DISINTEGRATOR |
| 17 | FX MIX of its lane |
| 91 | Reverb send |
| 92 | Delay send |
With SEND on, each generator's notes (keys, loops, MIDI) and those CCs go out on its OUT channel. A note sent on is always sent off on the same channel, even if the setting changes while it sounds. No clock, no transport.
./setup.sh once: a Python environment, JieLi's toolchain and three files of the AC79 SDK (Tonitor's procedure). On
macOS, Docker Desktop must be running to build. Then:
./build.sh
It must print package ... build N with no FAIL. ./install.sh builds and installs over USB; ./install.sh --no-build
installs build/norilsk.fwsc as it is; ./install.sh FILE.fwsc installs another package; ./install.sh --info says
what the connected FM-1 runs.
tests/run_tests.sh
Needs clang and python3 with Pillow. It checks the firmware unit for anything the chip's runtime lacks (no float,
no 64-bit division), renders thousands of sounds (none silent, none clipping, none running away), plays the panel
through the real firmware code, checks every effect falls silent, every recipe fits its slot's memory, snapshots and
morphs land exactly, every message fits the screen, sessions survive power cuts and never touch another firmware's flash, and that the engine's
generations still draw what they drew. Renders land in build/sounds (WAV), the screens in build/screens (PNG). The
website: tools/make_logo.py, tools/make_demos.sh, then tools/make_site.py (into docs/, served by GitHub Pages).
| Path | What |
|---|---|
firmware/src/norilsk.c | the single compilation unit: the sources in order |
firmware/hal/, crt0.S, app.ld, loader/ | the board layer, boot, memory map and update loader (Tonitor's, from Felucca and SLOOP) |
firmware/src/main.c, usb.c, ota.c, recovery.c, lcd.c, gfx.c | boot and interrupts, USB, the installer's handshake, the rescue mode, the screen |
firmware/src/setup.c, midi.c, midi_uart.c | GLOBAL SETUP, MIDI in and out, the TRS MIDI IN jack |
firmware/src/mol.c, fm6_core.c, wt.c | FURNACE: the voice, the grains, the hand, the grit, the families; the FM core; the waves |
firmware/src/gens.c | the three generators: the draw, the voices, the two cores, the DISINTEGRATOR, the mix |
firmware/src/rack.c, reverb.c | the effect slots: the twenty-five effects, the recipes, the paths, the memory, the cables |
firmware/src/mod.c, loop.c, master.c | the modulation; the loopers; the master delay and reverb |
firmware/src/sessions.c, backup.c | sessions, snapshots and the morph; the sessions over USB |
firmware/src/ui.c | the panel and the screen |
tools/ | the build, the installer, the sessions tool, the tables, fonts, logo, demos and website |
tests/host/host.c | the host harness: every test named above, render, one, replay |
docs/ | the website (GitHub Pages); docs/ENGINE.md the engine's first design (0.01) |
site/ | the website's pages, before tools/make_site.py frames them |
The firmware is GPL-3.0-only (LICENSE); fm6_core.c is msfa under Apache-2.0 (LICENSES/); the website and logo
are MIT. See LICENSING.md.
Norilsk is unofficial. It is not made, endorsed or supported by M-VAVE. Installing it replaces the FM-1's firmware and may void any warranty that applies to your device; an interrupted update can leave the FM-1 unable to start until it is recovered. The software comes with no warranty of any kind; you install it entirely at your own risk. Norilsk is named after the city; it has nothing to do with the company that runs its smelters.
| 4 |
| Noise in a pipe closed at one end, hiss beside it |
| CHIMNEY | 4 | Wind in a long open tube, an octave down |
| GIRDER | 4 | Noise in a bar's or plate's modes |
| HULL | 4 | Operators droning in a bell's or hull's modes |
| DEPTHS | 5 | Ice breaking and grinding, ship far above: slow, dark |
| AURORA | 5 | Hiss and radio from above the ice: airy, drifting |
| PLANT | 5 | Hum, ducts, furnace, rain on tin, engines, wires |
| ORGAN | 6 | Organ in a ruin: six carriers on drawbar ratios, held; sometimes sounding in a pipe |
| CHOIR | 6 | Wordless voices: formant-like waves bent by their envelopes, widely detuned, soft cloud |
| FOGHORN | 6 | Saws and squares an octave down, fed back hard, in a closed tube |
| SWARM | 6 | Many high carriers slightly apart, beating: buzzing mass |
| CORONA | 6 | Bell waves high up, cloud pitched an octave and a twelfth above |
| SUBSTRATE | 6 | Squares and saws an octave down, bent; sometimes a pipe's modes |
| GLASSHARP | 6 | Noise drawn around a bell's modes an octave up, long |
| OXIDE | 6 | Corroded metal: bent waves, crushed bits, plant grains |
| ANVIL | 7 | Hammer on an anvil: bright inharmonic partials, a bar or plate ringing a second or two. Scattered strikes while held (8) |
| STAMP | 7 | Press coming down: low thud into a closed tube, dark burst, short. Scattered strikes while held (8) |
| RIVET | 7 | Rivet gun: high, small, a plate, very short; clusters of shots. Scattered strikes while held (8) |
| SHEET | 7 | Metal sheet struck: crowded modes of a hull, wobbling, longer. Scattered strikes while held (8) |
| GEARS | 7 | Gears turning: quick ticks on a small plate in a pattern of teeth, pace wandering. Runs while held |
| PISTON | 7 | Slow thump into a closed tube, a hiss of steam between. Runs while held |
| RATCHET | 7 | Ratchet or chain: irregular clatter on a bar or bell, bounces. Runs while held |
| FORGE | 7 | Drop hammer: slow heavy anvil strikes, each bouncing, ringing long. Runs while held |
| XMOD | Sound against its own copy 1 to 40 ms back: folded, diode ring or Warps' comparator (after Mutable Instruments' Warps) |
| CHAOS | Double-well oscillator pushed by the sound: light, a resonance at a fixed pitch; harder, rough; hardest, jumping between its wells |