Markdown Converter
Agent skill for markdown-converter
This file contains consolidated development rules for noise-repellent that work with both Cursor and Antigravity IDEs.
Sign in to like and favorite skills
This file contains consolidated development rules for noise-repellent that work with both Cursor and Antigravity IDEs.
CRITICAL: Always rebuild and test after modifying plugin code or TTL files.
CRITICAL: Port indices in C code and TTL files MUST be synchronized.
When removing/adding ports:
PortIndex enum in C code.ttl.in filesC Code Changes: - Remove NOISEREPELLENT_ENABLE from PortIndex enum - Shift subsequent indices: LATENCY (7), INPUT_1 (8), OUTPUT_1 (9) - Remove enable field from plugin struct - Remove enable case from connect_port() - Change signal_crossfade_run() to always pass 'true' TTL Changes: - Remove enable port definition (index 7) - Shift subsequent ports: latency (7), input (8), output (9)
PortIndex enum in C file.ttl.in filemeson compile -C buildPortIndex enum.ttl.in file# Check generated TTL files grep "lv2:index" build/*.ttl # Verify C enum values grep "NOISEREPELLENT_" plugins/*.c # Rebuild after changes meson compile -C build
.ttl.in files: Templates in lv2ttl/ directory.ttl files: Built in build/ directory.ttl files directlylv2:port [ a lv2:ControlPort, lv2:InputPort ; lv2:index 0 ; lv2:symbol "reduction" ; lv2:name "Reduction amount" ; lv2:minimum 0.0 ; lv2:maximum 20.0 ; lv2:default 10.0 ; units:unit units:db ; ]
Each plugin needs:
NOISEREPELLENT_ADAPTIVE_URI)LV2_Descriptor)lv2_descriptor() function entry# Configure build meson setup build --wrap-mode=forcefallback # Build project meson compile -C build # Clean rebuild rm -rf build && meson setup build --wrap-mode=forcefallback
For libspecbleach development:
# Create symlink to local libspecbleach cd subprojects ln -sf ../../../libspecbleach libspecbleach # Force meson to use local version meson setup build --wrap-mode=forcefallback
plugins/lv2ttl/# Build plugins meson compile -C build # Check generated files ls -la build/*.dylib build/*.ttl
# Check that port indices match between C and TTL grep -n "lv2:index" build/*.ttl grep -n "NOISEREPELLENT_" plugins/*.c
instantiate(): Create plugin instanceconnect_port(): Connect control/audio portsactivate(): Prepare for processingrun(): Process audio (required)deactivate(): Optional cleanupcleanup(): Destroy instancetypedef enum PortIndex { CONTROL_PARAM_1 = 0, CONTROL_PARAM_2 = 1, // ... more controls LATENCY_REPORT = N, AUDIO_INPUT = N+1, AUDIO_OUTPUT = N+2, } PortIndex;
calloc() for zero-initialized memorycleanup()instantiate()instantiate()lv2_log_error()When working on libspecbleach changes that affect noise-repellent:
Create symlink:
cd subprojects ln -sf ../../../libspecbleach libspecbleach
Configure with forcefallback:
meson setup build --wrap-mode=forcefallback
Verify symlink usage:
meson compile -C build -v | grep libspecbleach
ninja -C libspecbleach/build formatmeson compile -C build# If libspecbleach API changes significantly rm -rf build meson setup build --wrap-mode=forcefallback # Or reconfigure existing build meson setup --reconfigure build --wrap-mode=forcefallback
Symptoms: Plugin loads but controls don't work Solution: Verify port indices match between C enum and TTL files
Symptoms: Build succeeds but plugin doesn't appear in host Solution: Check that
.ttl.in files are valid Turtle syntax
Symptoms: Link errors or API mismatches Solution: Use
--wrap-mode=forcefallback and verify symlinks
noise-repellent/ ├── plugins/ # LV2 plugin implementations ├── lv2ttl/ # TTL file templates ├── src/ # Shared utilities ├── subprojects/ # Dependencies (libspecbleach) ├── meson.build # Build configuration └── meson_options.txt # Build options
CRITICAL: Always protect against unconnected control ports in
run() functions.
Pattern:
// Safe parameter access with defaults self->parameters.param = self->param_port ? *self->param_port : DEFAULT_VALUE;
Why: LV2 hosts may not connect all control ports. Null pointer dereferences cause crashes.
CRITICAL: Validate audio ports before processing.
Pattern:
if (!self->input || !self->output) { return; // Silent failure is safer than crash }
Why: Audio ports are mandatory but hosts might pass NULL under error conditions.
CRITICAL: Handle initial latency periods in crossfade and delay compensation logic.
Pattern:
// During startup, pass through audio unchanged if (samples_processed < latency) { output[k] = input[k]; // Continue filling buffers for future processing }
Why: Delay buffers start empty, causing silence. Audio must flow immediately on startup.
IMPORTANT: Always call core processing functions regardless of UI state.
Pattern:
// Call processing function unconditionally process_audio(input, output, parameters); // Route output based on processing state if (bypass_enabled) { apply_crossfade(input, output, false); // Pass through } else { apply_crossfade(input, output, true); // Apply processing }
Why: Processing libraries often handle multiple modes internally. Separate processing from output routing.
RECOMMENDED: Validate parameter ranges before passing to processing functions.
Pattern:
// Clamp parameters to valid ranges param = fmaxf(fminf(param, MAX_VALUE), MIN_VALUE);
Why: Prevents undefined behavior from out-of-range parameters.
cleanup() function