diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b22ee5..6b07299 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: run: | python -m pip install -q -i https://test.pypi.org/simple/ \ --extra-index-url https://pypi.org/simple/ \ - "omnipython-audiodsp>=0.6.13.dev7" numpy pytest ruff==0.17.1 + "omnipython-audiodsp>=0.6.13.dev8" numpy pytest ruff==0.17.1 python -m pip list 2>/dev/null | grep -iE "^(omnipython-audiodsp|numpy|pytest|ruff) " - name: Lint diff --git a/.github/workflows/publish-release-packages.yml b/.github/workflows/publish-release-packages.yml index 02b3e30..0d6ad4d 100644 --- a/.github/workflows/publish-release-packages.yml +++ b/.github/workflows/publish-release-packages.yml @@ -39,7 +39,7 @@ jobs: run: | python -m pip install -q -i https://test.pypi.org/simple/ \ --extra-index-url https://pypi.org/simple/ \ - "omnipython-audiodsp>=0.6.13.dev7" numpy pytest + "omnipython-audiodsp>=0.6.13.dev8" numpy pytest python -m pip install -q --no-deps -e . - name: The faces carry this version run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 42ef55a..3fc3786 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,12 @@ All notable changes to `audioinstruments` are recorded here. - StateVariableMono has twelve patches, from Fat Bass and Brass Stab to Notch Pad and Squelch Zap, and `examples/state_variable_mono_demo.py` plays them. Patch 0 is the Init patch as it was. +- StateVariableMono's eleven patches after Init are about 5 dB louder, to sit with the other + module voices. +- StateVariableMono's fast filter sweeps open as fast on the graph as on the rack, by setting + audiodsp's new `BIQUAD_RAMP` to one frame on its filters. Every patch's sound moves a little on + the graph, Init included, and most on the fast sweeps of Fat Bass, Brass Stab, Nasal Reed, Wobble Bass + and Squelch Zap. An audiodsp without the option plays as before. - MonoOne has twelve patches, from Fat Bass and Sync Lead to Metal Bell and Wind, and `examples/mono_one_demo.py` plays them. Patch 0 is the Init patch as it was. - WestCoastSynth has twelve patches, from Soft Ping and Water Drops to Glass Chime and Wandering Fold, diff --git a/ROADMAP.md b/ROADMAP.md index 9f9296e..294ce30 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -24,9 +24,6 @@ Planned work, in rough order: - Notes on their own frame with the graph on the audio pump. A note played in a turn lands at the next block; with `audiograph` setting a value at a frame inside a block, `schedulable` can be True and a sequencer can time notes. -- StateVariableMono's filter envelope opening as fast on the graph as on the rack, once - audiodsp's `BIQUAD` node can take a new cutoff at once instead of walking to it over - 20 ms. The patches in `tests/test_module_patches.py`'s `FAST_SWEEP` then lose their waiver. - Polyphony beyond the first cut: portamento between voices, growing a pool past the voices it was built with, one pool shared by several instruments, and notes queued on an `audiopump.Events` for frame-exact diff --git a/lib/audioinstruments/_rack/modules/state_variable_mono.py b/lib/audioinstruments/_rack/modules/state_variable_mono.py index 77625e3..51370a1 100644 --- a/lib/audioinstruments/_rack/modules/state_variable_mono.py +++ b/lib/audioinstruments/_rack/modules/state_variable_mono.py @@ -66,7 +66,7 @@ class StateVariableMono(Module): "env1_sustain": 0.1, "env2_decay": 0.3, "env2_sustain": 0.92, - "volume": 0.99, + "volume": 1.081, }, ), ( @@ -85,7 +85,7 @@ class StateVariableMono(Module): "env2_attack": 0.03, "env2_decay": 0.35, "env2_sustain": 0.95, - "volume": 1.06, + "volume": 1.148, }, ), ( @@ -106,7 +106,7 @@ class StateVariableMono(Module): "env2_attack": 0.7, "env2_decay": 1.2, "env2_sustain": 1.0, - "volume": 1.01, + "volume": 1.093, }, ), ( @@ -127,7 +127,7 @@ class StateVariableMono(Module): "env2_attack": 0.3, "env2_decay": 0.9, "env2_sustain": 1.0, - "volume": 0.97, + "volume": 1.053, }, (("lfo_tri", "vco1_pw"),), ), @@ -147,7 +147,7 @@ class StateVariableMono(Module): "env1_sustain": 0.5, "env2_decay": 0.4, "env2_sustain": 1.0, - "volume": 0.96, + "volume": 1.043, }, ), ( @@ -165,7 +165,7 @@ class StateVariableMono(Module): "env2_attack": 0.5, "env2_decay": 1.0, "env2_sustain": 1.0, - "volume": 1.0, + "volume": 1.083, }, ), ( @@ -183,7 +183,7 @@ class StateVariableMono(Module): "env1_sustain": 0.0, "env2_decay": 0.25, "env2_sustain": 0.55, - "volume": 1.1, + "volume": 1.18, }, ), ( @@ -205,7 +205,7 @@ class StateVariableMono(Module): "env2_attack": 0.02, "env2_decay": 0.3, "env2_sustain": 1.0, - "volume": 1.03, + "volume": 1.113, }, ), ( @@ -224,7 +224,7 @@ class StateVariableMono(Module): "env1_sustain": 0.7, "env2_decay": 0.4, "env2_sustain": 1.0, - "volume": 1.0, + "volume": 1.083, }, ), ( @@ -243,7 +243,7 @@ class StateVariableMono(Module): "env1_sustain": 1.0, "env2_decay": 0.3, "env2_sustain": 1.0, - "volume": 0.97, + "volume": 1.053, }, ), ( @@ -260,7 +260,7 @@ class StateVariableMono(Module): "env1_sustain": 0.0, "env2_decay": 0.25, "env2_sustain": 0.7, - "volume": 1.03, + "volume": 1.133, }, ), ) @@ -544,6 +544,11 @@ def fragment(self, f): f.set(node, ag.BIQUAD_Q, 0.7071) f.set(node, ag.BIQUAD_GAIN_DB, 0.0) f.set(node, ag.BIQUAD_MIX, 1.0) + # The rack's filter takes a new cutoff at once, and a fast envelope moves it every + # block: walk to each in one frame, so a sweep opens as fast here. An audiodsp too + # old to have this walks for 20 ms and plays the same notes a little duller. + if hasattr(ag, "BIQUAD_RAMP"): + f.set(node, ag.BIQUAD_RAMP, 0.0) self._n_vcf = f.add(ag.MIX, (b_lp, b_hp, b_bp), f.output(self.vcf_out)) b_vcv = f.buffer() diff --git a/pyproject.toml b/pyproject.toml index de2a05c..5a2ed6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ keywords = ["instruments", "synthesizer", "eurorack", "audio", "dsp", "micropython", "midi"] dependencies = [ "numpy>=1.20", - "omnipython-audiodsp>=0.6.13.dev7", + "omnipython-audiodsp>=0.6.13.dev8", ] [project.optional-dependencies] diff --git a/tests/test_graph_micropython.py b/tests/test_graph_micropython.py index 3bbd6ed..e092af4 100644 --- a/tests/test_graph_micropython.py +++ b/tests/test_graph_micropython.py @@ -24,8 +24,8 @@ #: Voices whose filter cutoff goes through Python's pow every block: the most a sample may #: differ between interpreters, and how many may (of 198144 a channel). The Poly80's moving #: filters measure 3 counts on 5436 samples at the worst of its four phrases. -#: The StateVariableMono measures 1 count on 96 samples, with its VCA 6 dB down. -FLOAT_POW = {"state_variable_mono": (1.0, 128), "poly80": (4.0, 8000)} +#: The StateVariableMono measures 1 count on 144 samples, with its VCA 6 dB down. +FLOAT_POW = {"state_variable_mono": (1.0, 192), "poly80": (4.0, 8000)} CASES = [ ("hybrid_mono", 0), diff --git a/tests/test_graph_state_variable_mono.py b/tests/test_graph_state_variable_mono.py index 3b2030e..c902108 100644 --- a/tests/test_graph_state_variable_mono.py +++ b/tests/test_graph_state_variable_mono.py @@ -19,14 +19,12 @@ graph's 16-bit wires: the VCO mix and the two biquad outputs round to a count on the way into the morph mixer and the VCA. * When Env 1 or the LFO moves the cutoff once a block as the rack does, - ``synthio.Biquad`` in the rack steps direct-form coefficients instantly - without slewing, whereas ``audiograph.BIQUAD`` runs a 20 ms (1024-sample, - ``AUDIODSP_BIQUAD_F32_RAMP_MS``) parameter walk through an internal SVF - topology whenever coefficients move. Because cutoff updates every block - (5.3 ms), the graph filter continuously slews across the 20 ms window. - At slow LFO rates (0.25 Hz) the difference is 19 counts rms (0.84% of - level); at 6 Hz it is 258 counts rms (11% of level) and converges when - modulation settles. Over the note it matches within 11% rms of level. + ``synthio.Biquad`` in the rack takes each new cutoff at once, and the graph's + ``BIQUAD`` walks to it in one frame (``BIQUAD_RAMP`` at 0). Across the moving + cases below that is 4.1 counts rms at the worst, 0.17% of level, and 257 counts + at the worst on the sample a move lands on. An audiodsp with no ``BIQUAD_RAMP`` + walks for 20 ms and restarts the walk each block (5.3 ms), so the filter slews + behind the rack's, up to 11% rms of level, which is the bar here while it works. * Over a phrase with voice steals the held chord matches to 32 counts and 1.5 counts rms. * The LFO's triangle on ``lfo_tri_out`` matches within two counts and the @@ -184,6 +182,46 @@ def test_an_audiograph_without_biquad_leaves_the_voice_on_the_rack(monkeypatch): inst.deinit() +def filter_ramps(): + """Each voice's three biquads' BIQUAD_RAMP, on a fresh StateVariableMono's graph.""" + import audiograph + + inst = adapter.create(48000, voice="state_variable_mono", engine="graph", output="pull") + try: + assert inst.engine == "graph" + return [ + module._fragment.get(node, audiograph.BIQUAD_RAMP) + for module in inst.voice_pool.modules("synth") + for node in (module._n_lp, module._n_hp, module._n_bp) + ] + finally: + inst.deinit() + + +def test_the_filters_walk_for_one_frame_where_audiodsp_can(): + import audiograph + + if not hasattr(audiograph, "BIQUAD_RAMP"): + pytest.skip("this audiodsp has no BIQUAD_RAMP") + assert set(filter_ramps()) == {0.0} + + +def test_an_audiograph_without_the_ramp_still_compiles_the_voice(monkeypatch): + import audiograph + + if not hasattr(audiograph, "BIQUAD_RAMP"): + pytest.skip("this audiodsp has no BIQUAD_RAMP to take away") + ramp = audiograph.BIQUAD_RAMP + monkeypatch.delattr(audiograph, "BIQUAD_RAMP") + inst = adapter.create(48000, voice="state_variable_mono", engine="auto", output="pull") + try: + assert inst.engine == "graph" + module = next(iter(inst.voice_pool.modules("synth"))) + assert module._fragment.get(module._n_lp, ramp) == 20.0 + finally: + inst.deinit() + + # -- the voice -------------------------------------------------------------------------- CLEAN = [ diff --git a/tests/test_module_patches.py b/tests/test_module_patches.py index a2aeb1a..a6a924b 100644 --- a/tests/test_module_patches.py +++ b/tests/test_module_patches.py @@ -54,18 +54,6 @@ "mod", "pedal", ) -#: Patches whose filter envelope sweeps fast from a closed filter. The graph's biquad walks -#: to each new cutoff over 20 ms (``AUDIODSP_BIQUAD_F32_RAMP_MS``), and a cutoff that moves -#: every block starts the walk again, where the rack's ``synthio.Biquad`` takes the new cutoff -#: at once. The attack is duller for it, by more than LEVEL_DB. They compare overall level -#: only, until audiodsp's node can move at once. -FAST_SWEEP = ( - ("state_variable_mono", 1), - ("state_variable_mono", 2), - ("state_variable_mono", 8), - ("state_variable_mono", 10), - ("state_variable_mono", 11), -) def create(name, engine): @@ -197,9 +185,9 @@ def test_a_patch_is_the_same_level_on_rack_and_graph(name, index): assert np.abs(graph).max() < adapter.PCM_SCALE controls = get_module_class(adapter._MODULE_VOICES[name][0]).PRESETS[index][1] noisy = any("noise" in param and value > 0.0 for param, value in controls.items()) - if noisy or (name, index) in OVERALL_ONLY + RANDOM_CABLED + FAST_SWEEP: - # noise through a filter is another noise on each engine, and so is a random voltage, - # and a fast sweep opens slower on the graph's biquad: the overall level only + if noisy or (name, index) in OVERALL_ONLY + RANDOM_CABLED: + # noise through a filter is another noise on each engine, and so is a random voltage: + # the overall level only assert abs(20.0 * np.log10(level / np.sqrt(np.mean(rack**2)))) <= LEVEL_DB else: assert worst_level_db(rack, graph) <= LEVEL_DB diff --git a/tests/traits/state_variable_mono.json b/tests/traits/state_variable_mono.json index 65c62c1..0232749 100644 --- a/tests/traits/state_variable_mono.json +++ b/tests/traits/state_variable_mono.json @@ -229,12 +229,12 @@ "p1.n36.attack_ms": { "kind": "ms", "tol": 6.0, - "value": 20.0 + "value": 18.0 }, "p1.n36.centroid_hz": { "kind": "hz", "tol": 20.0, - "value": 164.839 + "value": 144.072 }, "p1.n36.decay_ms": { "kind": "ms", @@ -244,37 +244,37 @@ "p1.n36.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -7.576 + "value": -7.577 }, "p1.n36.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -14.206 + "value": -14.205 }, "p1.n36.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -22.995 + "value": -22.993 }, "p1.n36.peak_db": { "kind": "db", "tol": 1.0, - "value": -24.594 + "value": -19.247 }, "p1.n36.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": -1202.739 + "value": -1202.753 }, "p1.n36.release_ms": { "kind": "ms", - "tol": 6.9, - "value": 46.0 + "tol": 6.6, + "value": 44.0 }, "p1.n36.sustain_db": { "kind": "db", "tol": 1.0, - "value": -5.1 + "value": -5.482 }, "p1.n60.attack_ms": { "kind": "ms", @@ -284,52 +284,52 @@ "p1.n60.centroid_hz": { "kind": "hz", "tol": 20.0, - "value": 294.375 + "value": 267.383 }, "p1.n60.decay_ms": { "kind": "ms", - "tol": 31.2, - "value": 208.0 + "tol": 25.8, + "value": 172.0 }, "p1.n60.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -11.967 + "value": -11.958 }, "p1.n60.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -23.349 + "value": -23.328 }, "p1.n60.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -35.598 + "value": -35.557 }, "p1.n60.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -82.815 + "value": -82.578 }, "p1.n60.peak_db": { "kind": "db", "tol": 1.0, - "value": -24.026 + "value": -18.61 }, "p1.n60.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": -1202.648 + "value": -1202.663 }, "p1.n60.release_ms": { "kind": "ms", "tol": 6.0, - "value": 36.0 + "value": 34.0 }, "p1.n60.sustain_db": { "kind": "db", "tol": 1.0, - "value": -6.648 + "value": -7.055 }, "p1.n84.attack_ms": { "kind": "ms", @@ -338,8 +338,8 @@ }, "p1.n84.centroid_hz": { "kind": "hz", - "tol": 48.755, - "value": 975.092 + "tol": 43.339, + "value": 866.778 }, "p1.n84.decay_ms": { "kind": "ms", @@ -349,37 +349,37 @@ "p1.n84.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -18.282 + "value": -18.258 }, "p1.n84.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -31.317 + "value": -31.289 }, "p1.n84.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -44.259 + "value": -44.261 }, "p1.n84.peak_db": { "kind": "db", "tol": 1.0, - "value": -24.423 + "value": -18.978 }, "p1.n84.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": -1200.756 + "value": -1200.765 }, "p1.n84.release_ms": { "kind": "ms", "tol": 6.0, - "value": 36.0 + "value": 34.0 }, "p1.n84.sustain_db": { "kind": "db", "tol": 1.0, - "value": -17.116 + "value": -17.532 }, "p1.noise_floor_db": { "kind": "floor_db", @@ -389,7 +389,7 @@ "p1.vel32.centroid_hz": { "kind": "hz", "tol": 20.0, - "value": 294.375 + "value": 267.383 }, "p1.vel32.level_db": { "kind": "db", @@ -399,7 +399,7 @@ "p1.vel80.centroid_hz": { "kind": "hz", "tol": 20.0, - "value": 294.375 + "value": 267.383 }, "p1.vel80.level_db": { "kind": "db", @@ -419,7 +419,7 @@ "p10.n36.centroid_hz": { "kind": "hz", "tol": 20.0, - "value": 267.312 + "value": 263.446 }, "p10.n36.decay_ms": { "kind": "ms", @@ -434,7 +434,7 @@ "p10.n36.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -9.339 + "value": -9.342 }, "p10.n36.h4_db": { "kind": "harmonic_db", @@ -444,12 +444,12 @@ "p10.n36.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -13.919 + "value": -13.918 }, "p10.n36.peak_db": { "kind": "db", "tol": 1.0, - "value": -24.803 + "value": -19.822 }, "p10.n36.pitch_cents": { "kind": "cents", @@ -464,7 +464,7 @@ "p10.n36.sustain_db": { "kind": "db", "tol": 1.0, - "value": -3.232 + "value": -3.277 }, "p10.n60.attack_ms": { "kind": "ms", @@ -473,8 +473,8 @@ }, "p10.n60.centroid_hz": { "kind": "hz", - "tol": 20.752, - "value": 415.047 + "tol": 20.083, + "value": 401.664 }, "p10.n60.decay_ms": { "kind": "ms", @@ -484,27 +484,27 @@ "p10.n60.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -4.399 + "value": -4.4 }, "p10.n60.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -15.029 + "value": -15.028 }, "p10.n60.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -16.196 + "value": -16.198 }, "p10.n60.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -25.772 + "value": -25.775 }, "p10.n60.peak_db": { "kind": "db", "tol": 1.0, - "value": -26.166 + "value": -21.184 }, "p10.n60.pitch_cents": { "kind": "cents", @@ -514,12 +514,12 @@ "p10.n60.release_ms": { "kind": "ms", "tol": 6.0, - "value": 36.0 + "value": 32.0 }, "p10.n60.sustain_db": { "kind": "db", "tol": 1.0, - "value": -1.322 + "value": -1.328 }, "p10.n84.attack_ms": { "kind": "ms", @@ -529,7 +529,7 @@ "p10.n84.peak_db": { "kind": "db", "tol": 1.0, - "value": -29.33 + "value": -24.361 }, "p10.n84.pitch_cents": { "kind": "cents", @@ -539,12 +539,12 @@ "p10.n84.release_ms": { "kind": "ms", "tol": 6.0, - "value": 28.0 + "value": 26.0 }, "p10.n84.sustain_db": { "kind": "db", "tol": 1.0, - "value": -0.621 + "value": -0.609 }, "p10.noise_floor_db": { "kind": "floor_db", @@ -553,8 +553,8 @@ }, "p10.vel32.centroid_hz": { "kind": "hz", - "tol": 20.752, - "value": 415.047 + "tol": 20.083, + "value": 401.664 }, "p10.vel32.level_db": { "kind": "db", @@ -563,8 +563,8 @@ }, "p10.vel80.centroid_hz": { "kind": "hz", - "tol": 20.752, - "value": 415.047 + "tol": 20.083, + "value": 401.664 }, "p10.vel80.level_db": { "kind": "db", @@ -583,8 +583,8 @@ }, "p4.n36.centroid_hz": { "kind": "hz", - "tol": 23.26, - "value": 465.191 + "tol": 22.954, + "value": 459.09 }, "p4.n36.decay_ms": { "kind": "ms", @@ -594,42 +594,42 @@ "p4.n36.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": 0.88 + "value": 0.848 }, "p4.n36.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -4.042 + "value": -4.093 }, "p4.n36.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -9.353 + "value": -9.412 }, "p4.n36.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -12.465 + "value": -12.512 }, "p4.n36.peak_db": { "kind": "db", "tol": 1.0, - "value": -22.638 + "value": -17.657 }, "p4.n36.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": 6.365 + "value": 6.35 }, "p4.n36.release_ms": { "kind": "ms", - "tol": 15.3, - "value": 102.0 + "tol": 13.8, + "value": 92.0 }, "p4.n36.sustain_db": { "kind": "db", "tol": 1.0, - "value": -0.198 + "value": -0.212 }, "p4.n60.attack_ms": { "kind": "ms", @@ -638,8 +638,8 @@ }, "p4.n60.centroid_hz": { "kind": "hz", - "tol": 40.008, - "value": 800.16 + "tol": 39.381, + "value": 787.618 }, "p4.n60.decay_ms": { "kind": "ms", @@ -654,32 +654,32 @@ "p4.n60.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -12.442 + "value": -12.444 }, "p4.n60.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -19.28 + "value": -19.281 }, "p4.n60.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -24.338 + "value": -24.34 }, "p4.n60.peak_db": { "kind": "db", "tol": 1.0, - "value": -23.196 + "value": -18.215 }, "p4.n60.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": 7.241 + "value": 7.184 }, "p4.n60.release_ms": { "kind": "ms", - "tol": 13.2, - "value": 88.0 + "tol": 12.3, + "value": 82.0 }, "p4.n60.sustain_db": { "kind": "db", @@ -688,13 +688,13 @@ }, "p4.n84.attack_ms": { "kind": "ms", - "tol": 22.5, - "value": 150.0 + "tol": 22.8, + "value": 152.0 }, "p4.n84.centroid_hz": { "kind": "hz", - "tol": 75.194, - "value": 1503.875 + "tol": 73.599, + "value": 1471.982 }, "p4.n84.decay_ms": { "kind": "ms", @@ -704,42 +704,42 @@ "p4.n84.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -18.56 + "value": -18.561 }, "p4.n84.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -29.009 + "value": -29.011 }, "p4.n84.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -36.703 + "value": -36.693 }, "p4.n84.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -42.841 + "value": -42.843 }, "p4.n84.peak_db": { "kind": "db", "tol": 1.0, - "value": -29.833 + "value": -24.852 }, "p4.n84.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": 2.23 + "value": 2.224 }, "p4.n84.release_ms": { "kind": "ms", - "tol": 14.1, - "value": 94.0 + "tol": 13.2, + "value": 88.0 }, "p4.n84.sustain_db": { "kind": "db", "tol": 1.0, - "value": -1.954 + "value": -1.953 }, "p4.noise_floor_db": { "kind": "floor_db", @@ -748,8 +748,8 @@ }, "p4.vel32.centroid_hz": { "kind": "hz", - "tol": 40.008, - "value": 800.16 + "tol": 39.381, + "value": 787.618 }, "p4.vel32.level_db": { "kind": "db", @@ -758,8 +758,8 @@ }, "p4.vel80.centroid_hz": { "kind": "hz", - "tol": 40.008, - "value": 800.16 + "tol": 39.381, + "value": 787.618 }, "p4.vel80.level_db": { "kind": "db", @@ -778,8 +778,8 @@ }, "p5.n36.centroid_hz": { "kind": "hz", - "tol": 51.077, - "value": 1021.536 + "tol": 50.884, + "value": 1017.676 }, "p5.n36.decay_ms": { "kind": "ms", @@ -794,7 +794,7 @@ "p5.n36.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -6.057 + "value": -6.058 }, "p5.n36.h4_db": { "kind": "harmonic_db", @@ -804,12 +804,12 @@ "p5.n36.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -14.013 + "value": -14.014 }, "p5.n36.peak_db": { "kind": "db", "tol": 1.0, - "value": -25.329 + "value": -20.348 }, "p5.n36.pitch_cents": { "kind": "cents", @@ -818,13 +818,13 @@ }, "p5.n36.release_ms": { "kind": "ms", - "tol": 7.8, - "value": 52.0 + "tol": 6.6, + "value": 44.0 }, "p5.n36.sustain_db": { "kind": "db", "tol": 1.0, - "value": -0.723 + "value": -0.759 }, "p5.n60.attack_ms": { "kind": "ms", @@ -833,8 +833,8 @@ }, "p5.n60.centroid_hz": { "kind": "hz", - "tol": 73.564, - "value": 1471.28 + "tol": 73.219, + "value": 1464.377 }, "p5.n60.decay_ms": { "kind": "ms", @@ -844,12 +844,12 @@ "p5.n60.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -6.214 + "value": -6.215 }, "p5.n60.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -6.099 + "value": -6.1 }, "p5.n60.h4_db": { "kind": "harmonic_db", @@ -864,7 +864,7 @@ "p5.n60.peak_db": { "kind": "db", "tol": 1.0, - "value": -25.595 + "value": -20.614 }, "p5.n60.pitch_cents": { "kind": "cents", @@ -873,8 +873,8 @@ }, "p5.n60.release_ms": { "kind": "ms", - "tol": 6.6, - "value": 44.0 + "tol": 6.0, + "value": 40.0 }, "p5.n60.sustain_db": { "kind": "db", @@ -888,8 +888,8 @@ }, "p5.n84.centroid_hz": { "kind": "hz", - "tol": 118.413, - "value": 2368.254 + "tol": 117.877, + "value": 2357.537 }, "p5.n84.decay_ms": { "kind": "ms", @@ -904,12 +904,12 @@ "p5.n84.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -9.616 + "value": -9.617 }, "p5.n84.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -18.252 + "value": -18.251 }, "p5.n84.h5_db": { "kind": "harmonic_db", @@ -919,7 +919,7 @@ "p5.n84.peak_db": { "kind": "db", "tol": 1.0, - "value": -26.463 + "value": -21.482 }, "p5.n84.pitch_cents": { "kind": "cents", @@ -928,8 +928,8 @@ }, "p5.n84.release_ms": { "kind": "ms", - "tol": 6.6, - "value": 44.0 + "tol": 6.0, + "value": 40.0 }, "p5.n84.sustain_db": { "kind": "db", @@ -943,8 +943,8 @@ }, "p5.vel32.centroid_hz": { "kind": "hz", - "tol": 73.564, - "value": 1471.28 + "tol": 73.219, + "value": 1464.377 }, "p5.vel32.level_db": { "kind": "db", @@ -953,8 +953,8 @@ }, "p5.vel80.centroid_hz": { "kind": "hz", - "tol": 73.564, - "value": 1471.28 + "tol": 73.219, + "value": 1464.377 }, "p5.vel80.level_db": { "kind": "db", @@ -973,8 +973,8 @@ }, "p6.n36.centroid_hz": { "kind": "hz", - "tol": 180.953, - "value": 3619.063 + "tol": 180.932, + "value": 3618.633 }, "p6.n36.decay_ms": { "kind": "ms", @@ -984,17 +984,17 @@ "p6.n36.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -23.263 + "value": -23.264 }, "p6.n36.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -10.956 + "value": -10.957 }, "p6.n36.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -11.446 + "value": -11.445 }, "p6.n36.h5_db": { "kind": "harmonic_db", @@ -1004,22 +1004,22 @@ "p6.n36.peak_db": { "kind": "db", "tol": 1.0, - "value": -24.439 + "value": -19.458 }, "p6.n36.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": 7.788 + "value": 7.803 }, "p6.n36.release_ms": { "kind": "ms", - "tol": 15.0, - "value": 100.0 + "tol": 13.8, + "value": 92.0 }, "p6.n36.sustain_db": { "kind": "db", "tol": 1.0, - "value": -2.514 + "value": -2.53 }, "p6.n60.attack_ms": { "kind": "ms", @@ -1028,8 +1028,8 @@ }, "p6.n60.centroid_hz": { "kind": "hz", - "tol": 231.721, - "value": 4634.425 + "tol": 231.725, + "value": 4634.493 }, "p6.n60.decay_ms": { "kind": "ms", @@ -1039,37 +1039,37 @@ "p6.n60.h2_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -26.576 + "value": -26.575 }, "p6.n60.h3_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -19.712 + "value": -19.713 }, "p6.n60.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -19.254 + "value": -19.255 }, "p6.n60.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -18.633 + "value": -18.632 }, "p6.n60.peak_db": { "kind": "db", "tol": 1.0, - "value": -23.895 + "value": -18.914 }, "p6.n60.pitch_cents": { "kind": "cents", "tol": 3.0, - "value": 12.807 + "value": 12.797 }, "p6.n60.release_ms": { "kind": "ms", - "tol": 10.8, - "value": 72.0 + "tol": 10.2, + "value": 68.0 }, "p6.n60.sustain_db": { "kind": "db", @@ -1083,8 +1083,8 @@ }, "p6.n84.centroid_hz": { "kind": "hz", - "tol": 266.662, - "value": 5333.246 + "tol": 266.63, + "value": 5332.598 }, "p6.n84.decay_ms": { "kind": "ms", @@ -1104,22 +1104,22 @@ "p6.n84.h4_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -11.145 + "value": -11.146 }, "p6.n84.h5_db": { "kind": "harmonic_db", "tol": 1.5, - "value": -13.19 + "value": -13.191 }, "p6.n84.peak_db": { "kind": "db", "tol": 1.0, - "value": -22.218 + "value": -17.237 }, "p6.n84.release_ms": { "kind": "ms", - "tol": 14.4, - "value": 96.0 + "tol": 14.1, + "value": 94.0 }, "p6.n84.sustain_db": { "kind": "db", @@ -1133,8 +1133,8 @@ }, "p6.vel32.centroid_hz": { "kind": "hz", - "tol": 231.721, - "value": 4634.425 + "tol": 231.725, + "value": 4634.493 }, "p6.vel32.level_db": { "kind": "db", @@ -1143,8 +1143,8 @@ }, "p6.vel80.centroid_hz": { "kind": "hz", - "tol": 231.721, - "value": 4634.425 + "tol": 231.725, + "value": 4634.493 }, "p6.vel80.level_db": { "kind": "db",