diff --git a/CHANGELOG.md b/CHANGELOG.md index 47940c9..9602f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to PyTheory are documented here. +## 0.25.7 + +- Add `detune` parameter — ±cents oscillator spread on any synth (3 oscillators per note) +- Swing now applies to drum hits (offbeats shift with the groove) +- Improved snare and hi-hat sounds (metallic harmonics, faster attack) + ## 0.25.6 - Swing now applies to drum hits — offbeats shift with the groove, everything locks into the same pocket diff --git a/docs/guide/synths.rst b/docs/guide/synths.rst index fe4934c..316e3ac 100644 --- a/docs/guide/synths.rst +++ b/docs/guide/synths.rst @@ -266,6 +266,42 @@ Name Character ``"none"`` Raw waveform, no amplitude shaping at all =============== ================================================ +Detune +------ + +Any synth can be fattened with the ``detune`` parameter — it renders +three oscillators per note: the center pitch plus one shifted up and +one shifted down by the specified number of cents. The slight frequency +differences create beating and width, like an analog synth with +oscillator drift. + +.. code-block:: python + + # Juno-style analog drift — subtle, warm + pad = score.part("pad", synth="saw", detune=15) + + # Trance supersaw territory — wide, shimmery + lead = score.part("lead", synth="saw", detune=25) + + # Subtle thickening on a bass + bass = score.part("bass", synth="pulse", detune=8) + + # Works on any synth — even FM + bells = score.part("bells", synth="fm", detune=12) + +Detune values: + +- **5–10** = subtle thickening (barely noticeable, just warmer) +- **12–18** = classic analog drift (Juno, Prophet) +- **20–30** = wide and shimmery (trance, EDM) +- **40+** = extreme, almost chorus-like + +This is different from the ``chorus`` effect — detune creates +additional oscillators at render time (three per note), while chorus +processes the audio after rendering with a modulated delay line. +Detune is "wider at the source," chorus is "wider after the fact." +Stack both for maximum fatness. + Choosing Synth and Envelope Combos ---------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 844534e..d365e8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "pytheory" -version = "0.25.6" +version = "0.25.7" description = "Music Theory for Humans" readme = "README.md" license = "MIT" diff --git a/pytheory/__init__.py b/pytheory/__init__.py index 4a42653..25d47a8 100644 --- a/pytheory/__init__.py +++ b/pytheory/__init__.py @@ -1,6 +1,6 @@ """PyTheory: Music Theory for Humans.""" -__version__ = "0.25.6" +__version__ = "0.25.7" from .tones import Tone, Interval from .systems import System, SYSTEMS diff --git a/uv.lock b/uv.lock index 8dea61b..b2b1854 100644 --- a/uv.lock +++ b/uv.lock @@ -707,7 +707,7 @@ wheels = [ [[package]] name = "pytheory" -version = "0.25.6" +version = "0.25.7" source = { editable = "." } dependencies = [ { name = "numeral" },