I greatly appreciate you taking the time to read this. Throughout development, it has always felt as though I was building this project in a vacuum. Often it feels as though I'm the only person who will ever use this software, and that I am only talking to myself. So, thank you for being here. I hope you find this software useful, and if you have any feedback or suggestions, please don't hesitate to reach out.
OpenMeters is, at its core, the code within
src/visuals/<name>/processor.rs. The quality, rigor, and correctness
of that code is the most important part of this entire project. To
illustrate that importance, I should be able to gesture towards any of
the existing visuals, but in short:
- The spectrogram faithfully implements linear, log, and ERB frequency scaling, and, most importantly, Auger and Flandrin's method of spectral reassignment as described in their 1995 paper.
- The spectrum analyzer implements A-weighting according to IEC 61672:2003, and shares the same linear, log, and ERB frequency scaling.
- Although there is no direct standard for generating audio waveforms
(as far as I am aware), our waveform's implementation takes
inspiration from Audacity and Chris Needham's
audiowaveform. - The oscilloscope uses normalized autocorrelation period estimation and waveform-template correlation to keep traces stable across complex periodic signals and visible channel selections.
- The stereometer separates bands using LR4 Butterworth filters, along with linear and log scaling. The correlation meter uses those same Butterworth crossings.
- The loudness meter implements K-weighting relative to full scale/LUFS momentary/short-term, True Peak, and RMS fast/slow. Standards used include ITU-R BS.1770.
The point of this section is not to discourage engagement with the project, but rather to emphasize the expected level at which contributions are to operate.
OpenMeters is licensed under the GNU General Public License version 3.0 or later. See the LICENSE file for more information, but you knew that already. Code contributed to this project is also licensed under GPL-3.0-or-later, but the contributor retains copyright to their contributions.
Project-owned Rust files generally include an SPDX license header for GPL-3.0-or-later. Follow the nearby file style. If you adapt third-party code, keep the required notice and license information with the code and update packaged license documentation when needed.
Try to follow the general format of:
<type>(<scope>): <subject>
<body>
<DCO>
Where:
-
<type>is a noun describing the type of change, such as "fix", "feat", "refactor", etc. -
<scope>is an optional noun describing the area of the codebase affected by the change, or a specific component or module. This is optional, but can be helpful for understanding the context of the change. -
<subject>is a short description of the change. Save the details for the body. -
<body>is an optional longer description of the change, which can include motivation, implementation, etc. -
<DCO>is aSigned-off-by:footer certifying that you have the right to submit the contribution under this project's license. Use git's--signoff(-s) flag to add it automatically:$ git commit -s -m "fix(spectrum): correct A-weighting calculation"
AI tools have (for the most part) fundamentally changed how software is written. Personally, I limit my use of these tools heavily. All code must be reviewed extensively by a human prior to being pushed upstream.
Low-quality and obviously AI-generated pull requests and issues will be closed. If you cannot find the time to review or test your own code, I will not do so either.
OpenMeters is a Rust 2024 project. Use the Rust version declared in
Cargo.toml (rust-version) or newer. CI currently uses Rust 1.95
with rustfmt and clippy installed.
rustup toolchain install 1.95
rustup component add rustfmt clippy --toolchain 1.95You also need native development packages for PipeWire, Wayland/X11, xkbcommon, fontconfig/freetype, libclang, pkg-config, and Vulkan.
Fork and clone the repository, then create a topic branch:
git clone https://github.com/your-username/openmeters.git
cd openmeters
git switch -c my-changeUseful commands while iterating:
cargo check --workspace --locked
cargo run
cargo run --release
RUST_LOG=openmeters=debug cargo runFor performance work you may want to use the profiling profile.
The CI workflow currently runs these checks:
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test --all-targetsPlease run the same checks before committing. For documentation changes, please check formatting, links, examples, and spelling.
Always test relevant behavior through tests and manual verification.
Release tags use v<Cargo.toml package.version> for normal upstream
releases. For packaging-only rebuilds, append a positive package
release suffix: v1.7.1-2. The suffix does not change the Rust crate
version; it is passed to make -C packaging RELEASE=<suffix> for the
Debian/RPM release number.
src/domain.rs shared application enums and routing/visual identifiers
src/dsp.rs AudioBlock and small DSP types
src/util/ low-level audio math, color, musical, and telemetry helpers
src/infra/pipewire/ PipeWire registry monitor, routing, virtual sink, tap.
src/persistence/ settings schema, lossy loading, store, themes, visual config
src/visuals.rs visual module declarations, option enums, widget macros
src/visuals/ visual processors, state, render primitives, palettes, registry
src/visuals/render/ shared render helpers and WGSL shaders
src/ui/ iced app, subscriptions, pages, widgets, theme, windowing
src/main.rs application wiring and shutdown flow
packaging/ Debian/RPM/tarball packaging things
Keep dependencies between these areas shallow and one-way where possible:
domain,dsp, andutilshould not depend on UI or PipeWire.infrashould stay focused on PipeWire integration and routing.persistenceowns serialized settings and theme file behavior.visualsowns processor/state/render code and the visual registry.uicomposes application state, settings handles, subscriptions, windows, pages, and widgets.
Each visual lives under src/visuals/<name>/:
processor.rsconvertsAudioBlocks into snapshots. This is the most important part to test carefully.state.rsowns user-facing visual state and maps snapshots into render parameters.render.rsowns custom iced/wgpu drawing primitives.
When adding or changing a visual, also check the related wiring:
src/domain.rsforVisualKind.src/visuals.rsfor module declarations and option enums.src/visuals/palettes.rsfor default palettes.src/visuals/registry.rsfor descriptors, settings application, export, enablement, ordering, and sample delivery.src/persistence/visuals.rsfor serializable visual settings and lossy parsing.src/ui/pages/visuals/settings/for settings panels.README.mdif the user-visible behavior changes.
Always use shared render helpers in src/visuals/render/common.rs;
add new render code only when they don't fit.
Add or update tests when a change has behavior that can regress. If a behavior is impractical to automate, describe the manual checks you performed instead.
Ensure that your PR includes a clear description of the changes you've made, and any relevant context or motivation. If your changes are related to an open issue, please link to it in the description. I will do my best to review your PR in a timely manner.
The title of your PR should follow the same format as commit messages. Feel free to use the same message for both your commit and PR title. Use your best judgment.
Ultimately, I decide what gets merged, but I will never reject a PR due to grammatical issues or petty semantics alone. I will work with you to get it merged if I think the change is good for the project.