Skip to content

Conventional Commits for AudioLab

Overview

AudioLab follows the Conventional Commits specification to enable automated changelog generation and semantic versioning.


Commit Message Format

<type>(<scope>): <subject>

[optional body]

[optional footer(s)]

Example

feat(reverb): add shimmer reverb algorithm

Implemented frequency-shifted feedback reverb based on
Valhalla design principles. Uses pitch shifters in
feedback path for ethereal pad sounds.

Closes #234

Type

The type must be one of the following:

Type Description Changelog Section Version Bump
feat New feature Added MINOR
fix Bug fix Fixed PATCH
perf Performance improvement Performance PATCH
docs Documentation only Documentation -
style Code style (formatting, etc.) - -
refactor Code refactoring - -
test Adding tests - -
chore Maintenance tasks - -
ci CI/CD changes - -
build Build system changes - -
revert Reverts previous commit - PATCH

Special: Breaking Changes

feat(buffer)!: change AudioBuffer API to use std::span

BREAKING CHANGE: AudioBuffer::process() now takes std::span
instead of raw pointers. Update all call sites.

Migration:
  // Old
  buffer.process(data, size);

  // New
  buffer.process(std::span(data, size));

Triggers: MAJOR version bump


Scope

The scope indicates which part of the codebase is affected.

AudioLab Scopes

Core Systems: - core - Core framework - dsp - DSP algorithms - buffer - Buffer management - memory - Memory management - threading - Threading architecture - rt-safety - Realtime safety

Effects: - reverb - Reverb algorithms - delay - Delay effects - filter - Filters - dynamics - Dynamics processing - distortion - Distortion/saturation - modulation - Modulation effects

Plugin Infrastructure: - plugin - Plugin framework - ui - User interface - preset - Preset management - parameter - Parameter system - state - State management

Infrastructure: - build - Build system - ci - CI/CD pipeline - docs - Documentation - test - Testing infrastructure - deps - Dependencies

Examples

feat(reverb): add plate reverb algorithm
fix(buffer): prevent overflow in circular buffer
perf(filter): optimize IIR filter using SIMD
docs(api): update AudioBuffer documentation
refactor(core): extract interface from concrete class
test(dynamics): add unit tests for compressor
chore(deps): update JUCE to 7.0.9

Subject

The subject line should:

  • Use imperative mood ("add" not "added" or "adds")
  • Don't capitalize first letter
  • No period at the end
  • Be concise (≤ 50 characters if possible)

Good Examples

add sidechain input supportfix audio clicks on bypassimprove reverb tail decay accuracyremove deprecated AudioBuffer API

Bad Examples

Added sidechain input support (past tense) ❌ Add Sidechain Input Support (capitalized) ❌ add sidechain input support. (period) ❌ stuff (not descriptive) ❌ WIP (use branches, not commits)


Body

Optional detailed explanation:

  • Use to explain what and why, not how
  • Wrap at 72 characters
  • Separate from subject with blank line

Example

feat(compressor): add sidechain input support

Allow external audio to control compression. Common use case:
ducking music when voiceover speaks. Sidechain input is
optional - if not connected, uses main input signal.

Implementation uses high-pass filtered sidechain at 80Hz
to reduce bass sensitivity, as per industry standard.

Optional metadata:

Issue References

Fixes #123
Closes #456
Resolves #789
Refs #234

Breaking Changes

BREAKING CHANGE: Preset file format changed from JSON to binary.
Use audiolab-migrate-presets.exe to convert old presets.

Co-authors

Co-authored-by: Alice Chen <alice@audiolab.com>
Co-authored-by: Bob Smith <bob@audiolab.com>

Signed-off-by

Signed-off-by: Developer Name <developer@audiolab.com>

Complete Examples

Feature Addition

feat(dynamics): add multi-band compressor

Implements 3-band compressor with crossover filters.
Each band has independent threshold, ratio, attack,
release controls. Uses Linkwitz-Riley 4th order
crossovers at 200Hz and 2kHz.

Closes #456

Bug Fix

fix(reverb): prevent buffer overflow in tail calculation

Reverb was writing past buffer end when delay > 1 second,
causing crashes. Added bounds checking and increased
max buffer size to 4 seconds.

Root cause: Buffer allocated for 48kHz 1s (48000 samples)
but delay parameter allowed up to 5 seconds.

Fixes #4271
Tested: Added unit test for 2-second delay case

Performance Improvement

perf(filter): vectorize IIR filter using AVX2

Replaced scalar implementation with SIMD version using
AVX2 intrinsics. Processes 8 samples per iteration.

Benchmark results (Intel i7-9700K):
- Before: 1.2ms per 1024 samples
- After:  0.3ms per 1024 samples
- Speedup: 4x

Falls back to SSE2 or scalar on older CPUs.

Breaking Change

feat(buffer)!: migrate to std::span for buffer API

BREAKING CHANGE: All AudioBuffer methods now use std::span
instead of raw pointers. This provides bounds safety and
modern C++ semantics.

Migration guide:
  // Old API (AudioLab 1.x)
  float* data = buffer.getWritePointer();
  process(data, size);

  // New API (AudioLab 2.0)
  auto span = buffer.getWriteSpan();
  process(span);

Rationale: Prevent buffer overflows and enable better
compiler optimizations.

Fixes #123
Closes #234

Refactor (No Changelog)

refactor(core): extract IProcessor interface

Extracted common interface from concrete processor classes
to enable dependency injection and testing. No behavioral
changes.

Affected classes:
- AudioProcessor (now implements IProcessor)
- EffectProcessor (now implements IProcessor)

Documentation

docs(api): add usage examples to AudioBuffer docs

Added code examples for common operations:
- Filling buffer with sine wave
- Applying gain
- Mixing buffers
- Converting sample formats

Also fixed typos in parameter descriptions.

Changelog Generation Mapping

Commit types map to changelog sections:

types:
  feat:
    section: Added
  fix:
    section: Fixed
  perf:
    section: Performance
  docs:
    section: Documentation
  BREAKING CHANGE:
    section: Breaking Changes

Generated Changelog Example

## [2.1.0] - 2023-10-15

### Added
- **dynamics**: add multi-band compressor (#456)
- **reverb**: add shimmer reverb algorithm (#234)

### Fixed
- **reverb**: prevent buffer overflow in tail calculation (#4271)
- **ui**: fix preset dropdown flickering (#892)

### Performance
- **filter**: vectorize IIR filter using AVX2 (4x speedup)

### Documentation
- **api**: add usage examples to AudioBuffer docs

Validation

Pre-commit Hook

Install pre-commit hook to validate commit messages:

.git/hooks/commit-msg:

#!/bin/sh

# Regex for conventional commits
PATTERN="^(feat|fix|perf|docs|style|refactor|test|chore|ci|build|revert)(\(.+\))?(!)?: .{1,50}"

if ! grep -qE "$PATTERN" "$1"; then
    echo "ERROR: Commit message does not follow Conventional Commits"
    echo ""
    echo "Format: <type>(<scope>): <subject>"
    echo ""
    echo "Types: feat, fix, perf, docs, style, refactor, test, chore"
    echo "Example: feat(reverb): add shimmer algorithm"
    exit 1
fi

CI Validation

GitHub Actions workflow:

name: Validate Commits

on: [pull_request]

jobs:
  commitlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - uses: wagoid/commitlint-github-action@v5

Tips and Best Practices

1. Atomic Commits

Each commit should be a logical unit:

✅ Good (atomic commits):

feat(reverb): add stereo width control
test(reverb): add tests for stereo width
docs(reverb): document stereo width parameter

❌ Bad (mixed changes):

feat(reverb): add stereo width + fix bugs + refactor + update docs

2. Commit Often

✅ Small, frequent commits
   - Easy to review
   - Easy to revert
   - Clear history

❌ Large, infrequent commits
   - Hard to review
   - Hard to debug
   - Messy history

3. Write for Future You

✅ "fix(buffer): prevent overflow when delay > 1 second"
   → Future you: "Ah, there was a specific edge case!"

❌ "fix buffer bug"
   → Future you: "Which bug? What buffer?"

4. Use Body for Context

Subject should be concise, body can be detailed:

fix(ui): prevent preset dropdown flickering

The dropdown was redrawing on every mouse move event,
causing visible flickering. Changed to only redraw on
selection change.

Root cause: Missing event filter in ComboBox implementation.

Fixes #892

Common Scenarios

Hotfix

fix(critical): patch buffer overflow vulnerability

Critical security fix for CVE-2023-XXXXX. Buffer overflow
in audio processing could lead to crash or code execution.

All users should update immediately.

Fixes #CRITICAL-001

Deprecation

feat(api)!: deprecate AudioBuffer::getRawPointer()

Mark AudioBuffer::getRawPointer() as deprecated. Use
getWriteSpan() instead for memory safety.

BREAKING CHANGE: Will be removed in v3.0.0

Migration:
  [[deprecated("Use getWriteSpan()")]]
  float* getRawPointer();

Refs #567

Revert

revert: feat(reverb): add neural network reverb

Reverts commit a3f8b92.

The neural network approach was too slow for realtime
(300ms latency). Reverting to pursue FFT-based approach.

References


Remember: Good commit messages are love letters to your future self and teammates.