# Tessarine

> The everything pitch engine: four voices from three octaves down to three up with fine tune, level, pan and delay each; chord-friendly or single-note mode, formants kept or moved, detune spread and a feedback path that climbs in cascades.

- Engine id: `org.sournd.pitch.tessarine`
- Category: Pitch
- Licence: paid: £2.99 an effect or £4.99 a synth, once (owned for good, with updates), or included in the Everything plan (£14.99 a month)
- Version: 1.0.0
- Latency: 624 samples
- Tail: 15 s
- Sidechain input: no
- Channels: mono or stereo
- Audio demo: https://sournd.com/static/preview/demos/tessarine.mp3 (plucked chords, default settings)

## Parameters

The id is the C ABI parameter id and the JUCE parameter id (as a decimal string).

| Id | Key | Name | Min | Max | Default | Unit | Taper |
|---|---|---|---|---|---|---|---|
| 0 | `voice1_semitones` | Voice 1 pitch | -36 | 36 | 12 | st | linear |
| 1 | `voice1_cents` | Voice 1 fine | -100 | 100 | 0 | cents | linear |
| 2 | `voice1_level` | Voice 1 level | 0 | 100 | 100 | % | linear |
| 3 | `voice1_pan` | Voice 1 pan | -100 | 100 | -25 | % | linear |
| 4 | `voice1_delay_ms` | Voice 1 delay | 0 | 500 | 0 | ms | linear |
| 5 | `voice2_semitones` | Voice 2 pitch | -36 | 36 | -12 | st | linear |
| 6 | `voice2_cents` | Voice 2 fine | -100 | 100 | 0 | cents | linear |
| 7 | `voice2_level` | Voice 2 level | 0 | 100 | 70 | % | linear |
| 8 | `voice2_pan` | Voice 2 pan | -100 | 100 | 25 | % | linear |
| 9 | `voice2_delay_ms` | Voice 2 delay | 0 | 500 | 0 | ms | linear |
| 10 | `voice3_semitones` | Voice 3 pitch | -36 | 36 | 7 | st | linear |
| 11 | `voice3_cents` | Voice 3 fine | -100 | 100 | 0 | cents | linear |
| 12 | `voice3_level` | Voice 3 level | 0 | 100 | 0 | % | linear |
| 13 | `voice3_pan` | Voice 3 pan | -100 | 100 | 0 | % | linear |
| 14 | `voice3_delay_ms` | Voice 3 delay | 0 | 500 | 0 | ms | linear |
| 15 | `voice4_semitones` | Voice 4 pitch | -36 | 36 | 19 | st | linear |
| 16 | `voice4_cents` | Voice 4 fine | -100 | 100 | 0 | cents | linear |
| 17 | `voice4_level` | Voice 4 level | 0 | 100 | 0 | % | linear |
| 18 | `voice4_pan` | Voice 4 pan | -100 | 100 | 0 | % | linear |
| 19 | `voice4_delay_ms` | Voice 4 delay | 0 | 500 | 0 | ms | linear |
| 20 | `mode` | Mode | 0 | 1 | 0 | - | linear |
| 21 | `formant` | Formant keep | 0 | 100 | 0 | % | linear |
| 22 | `spread_cents` | Spread | 0 | 50 | 0 | cents | linear |
| 23 | `feedback` | Feedback | 0 | 70 | 0 | % | linear |
| 24 | `feedback_ms` | Feedback delay | 10 | 500 | 150 | ms | log |
| 25 | `low_cut_hz` | Low cut | 10 | 400 | 20 | Hz | log |
| 26 | `mix` | Mix | 0 | 100 | 50 | % | linear |
| 27 | `output_db` | Output | -24 | 12 | 0 | dB | linear |

## Use it in JUCE

CMake ([quick start](/docs/juce/index.md)):

```cmake
juce_add_module(path/to/sournd_engine)
target_include_directories(MyPlugin PRIVATE path/to/include)
target_link_libraries(MyPlugin PRIVATE sournd_engine path/to/libsournd_cabi.a)
```

C++:

```cpp
#include <sournd_engine/sournd_engine.h>

sournd::SourndEngine engine { "org.sournd.pitch.tessarine" };
juce::AudioProcessorValueTreeState parameters { *this, nullptr, "Parameters",
    sournd::SourndEngineParameters::createLayout (engine) };
sournd::SourndEngineParameters bridge { engine, parameters };

// prepareToPlay
engine.prepare ({ sampleRate, (juce::uint32) maximumBlock, 2 });
bridge.prepare (sampleRate);
setLatencySamples ((int) engine.latency());

// processBlock
bridge.apply ((uint32_t) buffer.getNumSamples());
juce::dsp::AudioBlock<float> block { buffer };
engine.process (juce::dsp::ProcessContextReplacing<float> { block });

// get/setStateInformation: hold getCallbackLock() around saveState / loadState,
// so state work never overlaps processBlock (full example: /docs/juce/)
```

Plain C:

```c
sournd_engine *e = NULL;
if (sournd_engine_create("org.sournd.pitch.tessarine", &e) == SOURND_OK) {
    sournd_engine_prepare(e, 48000.0, 512);
    sournd_engine_set_param(e, 0, 12); /* Voice 1 pitch */
    sournd_engine_process(e, in, out, 2, frames);
    sournd_engine_destroy(e);
}
```

## How it is made

Original sOURnd design blending general techniques: a sinusoidal phase vocoder on the analytic signal with a low-delay asymmetric window, whole-lobe resynthesis, transient phase reset and cepstral formant keeping (poly mode); pitch-synchronous overlap-add grains driven by a YIN tracker with full-rate refinement (mono mode); equal-power panning, per-voice delay lines and a soft-limited feedback loop through the shifter. Ranges informed by our own measurements of octave and pitch pedals.

## Ask your AI

Paste this into your coding assistant:

```text
Add the sournd engine org.sournd.pitch.tessarine to my JUCE plugin. Follow https://sournd.com/docs/juce/index.md
and the engine reference at https://sournd.com/engines/tessarine/index.md. Expose every parameter through APVTS.
```
