{"id":13730502,"url":"https://github.com/sudara/melatonin_parameters","last_synced_at":"2025-04-09T23:02:27.051Z","repository":{"id":66377522,"uuid":"355996157","full_name":"sudara/melatonin_parameters","owner":"sudara","description":"Parameter behavior and formatting for JUCE","archived":false,"fork":false,"pushed_at":"2025-02-20T21:58:02.000Z","size":86,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T00:51:22.165Z","etag":null,"topics":["cplusplus","juce","juce-framework"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sudara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-08T17:31:12.000Z","updated_at":"2025-02-20T21:58:05.000Z","dependencies_parsed_at":"2024-01-06T13:08:36.547Z","dependency_job_id":"1f9bbe35-a7d1-4ec6-af6a-c63e563be604","html_url":"https://github.com/sudara/melatonin_parameters","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_parameters","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_parameters/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_parameters/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sudara%2Fmelatonin_parameters/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sudara","download_url":"https://codeload.github.com/sudara/melatonin_parameters/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248125581,"owners_count":21051768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cplusplus","juce","juce-framework"],"created_at":"2024-08-03T02:01:15.755Z","updated_at":"2025-04-09T23:02:27.004Z","avatar_url":"https://github.com/sudara.png","language":"C++","funding_links":[],"categories":["Testing"],"sub_categories":[],"readme":"# Melatonin Parameters\n\nA very basic C++ JUCE module that contains\n\n1. A logarithmic `NormalizableRange` \"factory\" that accepts an exponent value to toy with the amount of skew.\n2. `stringFromTimeValue` and `timeValueFromString` helpers for parameters that behave in a user-friendly way.\n3. Tests for the above written in [Catch2](https://github.com/catchorg/Catch2).\n\nThese are the parameter behaviors I want by default. Having something like this in JUCE proper probably makes sense.\n\n## How to use\n\nIf you are a solo coder using Projucer, you could git clone and then manually add this module your project via the UI.\n\nI'm not a fan of copying and pasting dependencies (IMO that's one of reasons we can't have nice things in C++). Assuming you use git and want/have modules in a `modules` folder in your project, this will set you up with a git submodule tracking the `main` branch:\n```\ngit submodule add -b main https://github.com/sudara/melatonin_parameters modules/melatonin_parameters\ngit commit -m \"Added melatonin_parameters submodule.\"\n```\n\nWhen you want to update melatonin_parameters, you can now run\n```\ngit submodule update --remote --merge modules/melatonin_parameters\n```\n\nIf you use CMake, you can inform JUCE about the module in your `CMakeLists.txt`:\n```\njuce_add_module(\"modules/melatonin_parameters\")\n```\n\nzzzzzz.... Wake me up when C++ has widely supported package management plzthxbai.\n\n## Running tests\n\nCatch2 tests are in `melatonin_parameters.cpp` surrounded by `if RUN_MELATONIN_TESTS`\n\nAssuming you use CMake:\n\n1. Have Catch2 setup in your project. See [pamplejuce](https://github.com/sudara/pamplejuce).\n   \n2. Add the module as above\n\n3. Add the preprocessor flag to the test binary with: \n   \n`target_compile_definitions(Tests PRIVATE RUN_MELATONIN_TESTS=1)` \n\nwhere `Tests` is the name of your test binary.\n\n## Logarithmic Range\n\nIt has a default exponent setting of 6:\n\n```cpp\njuce::AudioParameterFloat (\"release\", \"Release\", logarithmicRange (0, 15.0f), 0.1f),\n```\n\nA custom exponent of 10 might be a sensible value for frequency:\n\n```cpp\njuce::AudioParameterFloat (\"frequency\", \"Frequency\", logarithmicRange (20.0f, 20000.0f, 10.0f), 0.1f),\n```\n\n## Reversed Logarithmic Range\n\nWhen you want the slider to be reversed in direction. The arguments are still in the same order, lowest possibility first.\n\n```cpp\njuce::AudioParameterFloat (\"release\", \"Release\", reversedLogarithmicRange (0, 15.0f), 0.1f),\n```\n\n### Why\n\n[Auditory perception of time and frequency is logarithmic](https://en.wikipedia.org/wiki/Weber–Fechner_law), so it's a good default for many knobs in audio.\n\nImagine a release knob. The first little bit of the knob, you'd probably want some fine control over 0-100ms to craft short release times. Maybe by the time you get to the middle of the knob it's at 1s. And then the rest of the knob can handle 1-10s, where granularity is much less important.\n\n### Implementation\n\n[![Screenshot 2021-04-08 Linear to logarithmic range conversion - Safari](https://user-images.githubusercontent.com/472/114071474-73822e00-98a1-11eb-95a3-405faae1e768.jpg)](https://www.desmos.com/calculator/qkc6naksy5)\n\nThe math can be viewed at [this desmos link](https://www.desmos.com/calculator/qkc6naksy5).\n\n\u003cdetails\u003e\n\nGithub can't render latex, but here's the latex formulas in case the desmos link goes away.\n\nFrom a normalized 0-1 to an unnormalized y0 to y1:\n```\ny_{0}\\ +\\frac{2^{kx}-1}{2^{k}-1}\\left(y_{1}-y_{0}\\right)\n\n```\n\nTo a normalized 0-1 from an unnormalized y0 to y1\n```\n\\frac{\\log_{2}\\left(\\frac{x-y_{0}}{y_{1}-y_{0}}\\left(2^{k}-1\\right)+1\\right)}{k}\n```\n\n\u003c/details\u003e\n\nUnderstanding the math is a bit of a pain, but the core idea is to be able to translate to and from any logarithmic range to JUCE's normalized 0-1 range.\n\nSee the references for more detail. Other solutions I ran into had oddities such as not allowing the logarithmic minimum to be 0 (as it would result in division by 0).\n\nI went back to the math to cook up something that I could understand, where the range could start at 0, and where the exponential-ness (skew) and starting positions could be adjusted.\n\n\n## stringFromTimeValue and timeValueFromString\n\n### How to use\n\n```cpp\njuce::AudioParameterFloat\u003e (\"delay\", \"Delay\", logarithmicRange(0.0f, 1.0f), 0.0f, juce::String(), juce::AudioProcessorParameter::genericParameter, stringFromTimeValue, timeValueFromString)\n```\n\n### Why?\nIn JUCE, parameters don't \"know\" what units they are nor how to display them. Even though most plugins will have similar values such as frequency and time and \"note value\", the formatting display of those values is up to the user; there are no out of the box defaults.\n\n## stringFromTimeValue Implementation\n\nThis is is optimized for normal person usability, *not* for accuracy. \n\n1. Under 0.5s, values are displayed as ms with NO decimal places. It will look like `1ms`, `5ms`, etc.\n2. Excess 0s are removed. `1.00` is displayed as `1s`\n3. A max of two digits after the decimal place. `1.111` will display as `1.11`.\n\n## timeValueFromString Implementation\n\n1. Values can be with or without decimal\n\n1. `ms` and `s` are accepted as units: `0ms`, `11.1ms`, `100ms`, `1.0s`, `15.98s` are all valid.\n\n3. Without a unit, single digits or a decimal place will trigger seconds conversion: `1` or `1.` or `1.0` \n   \n4. Without a unit, double and triple digits convert to ms. \n   \nSee the tests for more detail.\n\n## References\n\n* https://github.com/ffAudio/foleys_gui_magic/blob/master/Helpers/foleys_Conversions.h#L41\n* https://forum.juce.com/t/logarithmic-slider-for-frequencies-iir-hpf/37569/21\n* https://forum.cockos.com/showpost.php?p=2017848\u0026postcount=11\n\n## TODO\n\n* Implement and test snapToLegalValue\n* Implement versioning to make it safer to use via CMake\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudara%2Fmelatonin_parameters","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsudara%2Fmelatonin_parameters","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsudara%2Fmelatonin_parameters/lists"}