crates/veilvoice-core/src/modulation.rs
veilvoice-core · 323 lines · read the source here · or on GitHub
Cryptographically-seeded modulation of the effect parameters.
The pitch and formant ratios are never constant: a ChaCha20 CSPRNG picks a new random target every frames_per_target STFT frames, and a one-pole filter glides continuously toward it. Because the transform is therefore non-stationary and unpredictable, an attacker cannot "undo" it by assuming a single fixed shift: there is no single shift to undo, and the target sequence is unknowable without the seed (which never leaves the process and is zeroized on drop).
The seed does not stay put either. It is rolled forward every couple of seconds by default (see Modulator::reseed), so the stream driving any given stretch of audio is closed off permanently once that stretch is past.
In plain words
The amount by which the voice is altered is never held still. It drifts, constantly and unpredictably.
The drift comes from the same kind of random number generator used for encryption, so it cannot be guessed, worked out from what came before, or reproduced by somebody who has the recording. It slides between values rather than jumping, so nothing about it can be heard.
This is what stops the transform from being reversed by anybody who works out the settings, because there is no single setting to work out.
WHAT THIS FILE CONTAINS
323 lines defining 9 functions (5 public), 3 types and 0 constants. Everything below is read out of the source, so it cannot disagree with the code.
The types it owns.
struct Paramline 36 · One smoothly-varying parameter bounded to lo, hi.struct ModValuesline 76 · The values handed to the spectral transform for one frame.struct Modulatorline 84 · Non-stationary parameter generator.
What happens when it runs. These are the ways in: public, and nothing else in this file calls them, so they are what an outside caller reaches first.
Modulator::from_seedline 96 · Build from an explicit 32-byte seed (deterministic; used by tests and by session-key-derived seeding).
reachesnewModulator::fill_phase_offsetsline 115 · The 32 fixed per-bin phase offsets consumer needs are derived from the same stream; expose a helper that fills out with values in [0, 2π).Modulator::reseedline 143 · Roll onto a fresh seed, drawn from the current stream.Modulator::draw_framesline 164 · Draw a whole number of frames uniformly from lo..=hi.Modulator::next_frameline 174 · Advance one STFT frame and return the parameters to apply.
WHAT CALLS WHAT
The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.
The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
n_new["Param::new<br/>line 47"]
n_retarget["Param::retarget<br/>line 61"]
n_step["Param::step<br/>line 68"]
n_from_seed(["Modulator::from_seed<br/>line 96"])
n_fill_phase_offsets(["Modulator::fill_phase_offsets<br/>line 115"])
n_reseed(["Modulator::reseed<br/>line 143"])
n_draw_frames(["Modulator::draw_frames<br/>line 164"])
n_next_frame(["Modulator::next_frame<br/>line 174"])
n_drop["Modulator::drop<br/>line 188"]
n_from_seed --> n_new
click n_new href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L47" "open the source"
click n_retarget href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L61" "open the source"
click n_step href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L68" "open the source"
click n_from_seed href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L96" "open the source"
click n_fill_phase_offsets href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L115" "open the source"
click n_reseed href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L143" "open the source"
click n_draw_frames href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L164" "open the source"
click n_next_frame href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L174" "open the source"
click n_drop href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-core/src/modulation.rs#L188" "open the source"
classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
class n_from_seed,n_fill_phase_offsets,n_reseed,n_draw_frames,n_next_frame entry
classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
class n_new,n_retarget,n_step,n_drop helper
This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.
ITEMS
| Item | Line | Documentation |
|---|---|---|
Param struct | 36 | One smoothly-varying parameter bounded to lo, hi. |
Param::new fn | 47 | Start in the middle of the range, so the first frames are not a slide from an edge the caller never asked for. |
Param::retarget fn | 61 | Draw the next value to move towards. |
Param::step fn | 68 | Move one step of the way towards the target and report where that is. |
ModValues pub struct | 76 | The values handed to the spectral transform for one frame. |
Modulator pub struct | 84 | Non-stationary parameter generator. |
Modulator::from_seed pub fn | 96 | Build from an explicit 32-byte seed (deterministic; used by tests and by session-key-derived seeding). |
Modulator::fill_phase_offsets pub fn | 115 | The 32 fixed per-bin phase offsets consumer needs are derived from the same stream; expose a helper that fills out with values in [0, 2π). |
Modulator::reseed pub fn | 143 | Roll onto a fresh seed, drawn from the current stream. |
Modulator::draw_frames pub fn | 164 | Draw a whole number of frames uniformly from lo..=hi. |
Modulator::next_frame pub fn | 174 | Advance one STFT frame and return the parameters to apply. |
Modulator::drop fn | 188 |