Skip to content

05_07_ATOMS_L1 - L1 Atoms (Componentes DSP Básicos)

📋 RESUMEN EJECUTIVO

Los L1 Atoms son los bloques de construcción fundamentales del sistema AudioLab DSP. Cada átomo es un componente DSP completo y autónomo que encapsula kernels L0 en procesadores musicalmente significativos con interface estandarizada, gestión de estado RT-safe, y optimizaciones SIMD.

Criticidad: ⭐⭐⭐⭐⭐ (Máxima - Base de toda la arquitectura L2/L3)


🎯 PROPÓSITO

Los átomos L1 transforman primitivas matemáticas (kernels L0) en componentes DSP utilizables:

L0 KernelsL1 AtomsL2 CellsL3 Engines

Sin átomos L1, cada desarrollador tendría que: - ❌ Re-implementar filtros biquad desde cero - ❌ Gestionar manualmente anti-aliasing en osciladores - ❌ Diseñar curvas de envelope desde primitivas - ❌ Manejar smoothing de parámetros manualmente

Con átomos L1: - ✅ Instanciar BiquadFilter con 1 línea de código - ✅ Anti-aliasing automático vía PolyBLEP - ✅ Envelopes ADSR con curvas exponenciales precisas - ✅ Parameter smoothing integrado y RT-safe


🏗️ COMPONENTES IMPLEMENTADOS

8 Tipos de Átomos Fundamentales:

Átomo Propósito Variantes Criticidad
Filter Filtrado de frecuencia Biquad, SVF, Ladder (Moog) ⭐⭐⭐⭐⭐
Oscillator Generación de señal Sin, Saw, Square, Triangle, Wavetable ⭐⭐⭐⭐⭐
Envelope Control de amplitud temporal ADSR, AR, Multi-stage ⭐⭐⭐⭐⭐
LFO Modulación de baja frecuencia Sin/Tri/Saw/Square, Random, Tempo-sync ⭐⭐⭐⭐
Delay Procesamiento temporal Simple, Modulated, Ping-pong ⭐⭐⭐⭐
Saturator Distorsión/saturación Soft/Hard clip, Waveshaper, Tube ⭐⭐⭐⭐
Gain Control de amplitud Linear/dB con smoothing ⭐⭐⭐
Pan Posicionamiento estéreo 4 pan laws, stereo width ⭐⭐⭐

🔑 CAPACIDADES CLAVE

1. Interface Uniforme (Processor Base Class)

#include <audiolab/atoms/processor.hpp>

class Processor {
public:
    virtual void reset() = 0;
    virtual void set_sample_rate(float sr) = 0;
    virtual void process(AudioBuffer& buffer, const ProcessContext& ctx) = 0;

    virtual void set_parameter(int id, float value) = 0;
    virtual float get_parameter(int id) const = 0;

    virtual const char* get_name() const = 0;
    virtual int get_latency_samples() const { return 0; }
};

Todos los átomos heredan de esta interface → código intercambiable y composable.


2. Ejemplos de Uso

Oscilador Anti-aliased

#include <audiolab/atoms/oscillator.hpp>

Oscillator osc;
osc.set_sample_rate(48000.0f);
osc.set_frequency(440.0f);  // A4
osc.set_wave_shape(WaveShape::SAW);

AudioBuffer buffer(1, 1024);
ProcessContext ctx{48000.0f, 1024, 0};
osc.process(buffer, ctx);  // Genera saw wave anti-aliased

Features: - PolyBLEP anti-aliasing (>60dB suppression @ Nyquist/2) - 5 waveforms: Sine, Saw, Square, Triangle, Wavetable - Phase continuity en parameter changes - DC offset <-80dB


Filtro Biquad Multi-tipo

#include <audiolab/atoms/filter.hpp>

BiquadFilter filter;
filter.set_sample_rate(48000.0f);
filter.set_type(FilterType::LOWPASS);
filter.set_frequency(2000.0f);  // Cutoff
filter.set_q(0.707f);            // Butterworth

AudioBuffer buffer(2, 512);  // Stereo
ProcessContext ctx{48000.0f, 512, 0};
filter.process(buffer, ctx);

Tipos disponibles: - Lowpass, Highpass, Bandpass, Notch - Peaking EQ, Low Shelf, High Shelf - Allpass (phase shift)

Features: - Frequency response accuracy ±0.5dB @ cutoff - Stable hasta Q=100 - Transposed Direct Form II (optimizado) - SIMD optimización (4-8x speedup)


Envelope ADSR

#include <audiolab/atoms/envelope.hpp>

ADSREnvelope env;
env.set_sample_rate(48000.0f);
env.set_attack_time(0.01f);   // 10ms
env.set_decay_time(0.1f);     // 100ms
env.set_sustain_level(0.7f);  // 70%
env.set_release_time(0.5f);   // 500ms

env.trigger();  // Note on

AudioBuffer buffer(1, 1024);
ProcessContext ctx{48000.0f, 1024, 0};
env.process(buffer, ctx);  // Genera curva de envelope

env.release();  // Note off

Features: - Timing accuracy ±1ms @ 48kHz - Exponential curves (natural decay) - Re-trigger desde cualquier stage - Multi-stage envelope (hasta 16 puntos) - Velocity scaling integrado


LFO con Tempo Sync

#include <audiolab/atoms/lfo.hpp>

TempoSyncedLFO lfo;
lfo.set_sample_rate(48000.0f);
lfo.set_tempo(120.0f);  // BPM
lfo.set_division(SyncDivision::QUARTER_NOTE);  // 1/4 note = 2Hz @ 120 BPM
lfo.set_wave_shape(WaveShape::SINE);
lfo.set_unipolar(true);  // 0-1 range

AudioBuffer buffer(1, 512);
ProcessContext ctx{48000.0f, 512, 0};
lfo.process(buffer, ctx);

Features: - 7+ tempo divisions (whole, half, quarter, 8th, 16th, dotted, triplet) - Random modes: Sample & Hold, Smooth Random, Perlin Noise - Phase offset control - Bipolar (-1 to 1) / Unipolar (0 to 1) output - LFO Matrix (route 8 LFOs a 256 parámetros)


Delay con Modulación (Chorus/Flanger)

#include <audiolab/atoms/delay.hpp>

ModulatedDelay chorus;
chorus.set_sample_rate(48000.0f);
chorus.set_delay_time(0.02f);          // 20ms base delay
chorus.set_modulation_depth(100.0f);   // ±100 samples
chorus.set_modulation_rate(0.5f);      // 0.5 Hz LFO

AudioBuffer buffer(2, 1024);  // Stereo
ProcessContext ctx{48000.0f, 1024, 0};
chorus.process(buffer, ctx);

Tipos disponibles: - Simple Delay (con feedback) - Modulated Delay (chorus/flanger) - Ping-pong Delay (stereo)

Features: - Fractional delay (interpolación lineal/cúbica) - Delay time accuracy ±1 sample - Feedback stability hasta 0.99 - Max delay: configurable (típicamente 1-10 segundos)


Saturador Multi-modo

#include <audiolab/atoms/saturator.hpp>

Saturator dist;
dist.set_sample_rate(48000.0f);
dist.set_mode(SaturationMode::TUBE);
dist.set_drive(12.0f);  // +12dB drive
dist.set_mix(0.7f);     // 70% wet, 30% dry

AudioBuffer buffer(2, 512);
ProcessContext ctx{48000.0f, 512, 0};
dist.process(buffer, ctx);

Modos disponibles: - Soft Clip (smooth asymptotic) - Hard Clip (brickwall) - Tanh (symmetric saturation) - Arctangent (gentle) - Sine Fold (wavefolder) - Tube (asymmetric, even harmonics) - Bitcrush (digital degradation)

Features: - DC blocker integrado - Asymmetric distortion (bias control) - Waveshaper con lookup tables - THD analysis tools


3. Factory Pattern & Preset System

#include <audiolab/atoms/factory.hpp>
#include <audiolab/atoms/preset.hpp>

// Crear atom desde factory
auto filter = AtomFactory::instance().create("Filter");

// Cargar preset
AtomPreset preset = AtomPreset::from_json(json_string);
PresetManager::apply_preset(*filter, preset);

// Listar atoms disponibles
for (auto& type : AtomFactory::instance().list_atom_types()) {
    std::cout << type << std::endl;
}

Features: - Factory registration automático - JSON serialization de presets - Preset morphing (interpolación entre presets) - Preset bank (categorías, búsqueda, metadata)


4. RT-Safety & Performance

Todos los átomos son Real-Time Safe: - ✅ Zero allocations en process() - ✅ Zero syscalls/locks en audio thread - ✅ Lock-free parameter updates - ✅ Bounded execution time

Performance targets: - CPU usage: <1% por atom @ 48kHz (CPU moderno) - Latency: 0 samples (mayoría de atoms) - SIMD speedup: 4-8x vs scalar (where applicable) - Throughput: >100 voices simultáneas @ 48kHz

Verified via: - Allocation tracking tests - Stack usage analysis (<4KB por process call) - Performance benchmarks en CI/CD


5. SIMD Optimization

Los átomos críticos incluyen paths SIMD optimizados:

// Ejemplo: Biquad filter SIMD (AVX)
void BiquadFilter::process_simd(AudioBuffer& buffer) {
    __m256 b0_vec = _mm256_set1_ps(b0_);
    // ... coefficients

    for (int i = 0; i < buffer.num_samples; i += 8) {
        __m256 input = _mm256_load_ps(&buffer.channels[0][i]);
        __m256 output = _mm256_fmadd_ps(b0_vec, input, z1_vec);
        // ... biquad math
        _mm256_store_ps(&buffer.channels[0][i], output);
    }
}

SIMD support: - AVX2 (8-wide float) - SSE (4-wide float) - Scalar fallback (portability) - Runtime ISA detection


📊 MÉTRICAS DE CALIDAD

Resultados de Testing:

Métrica Target Actual Status
Test Coverage >95% 🔄 Pending -
CPU Usage <1%/atom 🔄 Pending -
THD+N (Osc) <0.01% 🔄 Pending -
Frequency Response (Filter) ±0.5dB 🔄 Pending -
Timing Accuracy (Envelope) ±1ms 🔄 Pending -
RT Allocations 0 🔄 Pending -
SIMD Speedup 4-8x 🔄 Pending -

🚀 QUICK START

1. Instalación

# Clone repo
git clone https://github.com/audiolab/audio-lab.git
cd audio-lab

# Build atoms
cd "3 - COMPONENTS/05_MODULES/05_07_ATOMS_L1"
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .

2. Primer Ejemplo: Sintetizador Básico

#include <audiolab/atoms/oscillator.hpp>
#include <audiolab/atoms/filter.hpp>
#include <audiolab/atoms/envelope.hpp>

class SimpleSynth {
    Oscillator osc;
    BiquadFilter filter;
    ADSREnvelope env;

public:
    SimpleSynth(float sample_rate) {
        osc.set_sample_rate(sample_rate);
        filter.set_sample_rate(sample_rate);
        env.set_sample_rate(sample_rate);

        // Configure
        osc.set_wave_shape(WaveShape::SAW);
        filter.set_type(FilterType::LOWPASS);
        filter.set_frequency(2000.0f);
        filter.set_q(2.0f);

        env.set_attack_time(0.01f);
        env.set_decay_time(0.1f);
        env.set_sustain_level(0.7f);
        env.set_release_time(0.5f);
    }

    void note_on(float frequency) {
        osc.set_frequency(frequency);
        env.trigger();
    }

    void note_off() {
        env.release();
    }

    void process(AudioBuffer& buffer, const ProcessContext& ctx) {
        // Generate oscillator
        osc.process(buffer, ctx);

        // Filter
        filter.process(buffer, ctx);

        // Apply envelope
        AudioBuffer env_buffer(1, buffer.num_samples);
        env.process(env_buffer, ctx);

        for (int i = 0; i < buffer.num_samples; ++i) {
            buffer.channels[0][i] *= env_buffer.channels[0][i];
        }
    }
};

3. Uso

SimpleSynth synth(48000.0f);

synth.note_on(440.0f);  // A4

AudioBuffer buffer(1, 512);
ProcessContext ctx{48000.0f, 512, 0};

for (int block = 0; block < 100; ++block) {
    synth.process(buffer, ctx);
    // Output buffer to audio device
}

synth.note_off();

📁 ESTRUCTURA DEL PROYECTO

05_07_ATOMS_L1/
├── README.md                          # Este archivo
├── PLAN_DE_DESARROLLO.md              # Plan detallado
├── RESUMEN_EJECUTIVO.md               # Executive summary
├── INDICE.md                          # Navegación
├── 05_07_00_base_infrastructure/      # Base classes & utilities
│   ├── include/
│   │   ├── processor.hpp              # Processor base class
│   │   ├── parameter.hpp              # Parameter system
│   │   ├── audio_buffer.hpp           # Buffer management
│   │   ├── modulation.hpp             # Modulation matrix
│   │   └── simd_utils.hpp             # SIMD abstractions
│   └── tests/
├── 05_07_01_oscillator/               # Oscillator atoms
├── 05_07_02_envelope/                 # Envelope atoms
├── 05_07_03_lfo/                      # LFO atoms
├── 05_07_04_filter/                   # Filter atoms
├── 05_07_05_saturator/                # Saturator atoms
├── 05_07_06_gain/                     # Gain atoms
├── 05_07_07_delay/                    # Delay atoms
├── 05_07_08_pan/                      # Pan atoms
├── 05_07_09_preset_system/            # Preset & factory
├── 05_07_test_integration/            # Integration tests
├── 05_07_interfaces/                  # C API, Python bindings
└── 05_07_documentation/               # Docs, examples

🔗 CONEXIONES CON OTROS SUBSISTEMAS

Dependencies (Consume):

Consumers (Usado por):

Integrations:


📚 DOCUMENTACIÓN ADICIONAL

Por Átomo:

  • 05_07_01_oscillator/OSCILLATOR_GUIDE.md - Guía de osciladores
  • 05_07_04_filter/FILTER_COOKBOOK.md - Diseño de filtros
  • 05_07_02_envelope/ENVELOPE_GUIDE.md - Diseño de envelopes
  • 05_07_03_lfo/LFO_GUIDE.md - Modulación con LFOs
  • Y más...

Examples:

  • 05_07_examples/simple_synth.cpp - Sintetizador básico
  • 05_07_examples/filtered_noise.cpp - Noise + filter
  • 05_07_examples/vibrato_effect.cpp - Vibrato con LFO + delay

⚠️ ANTIPATTERNS A EVITAR

🚫 Allocations en process() - Usa buffer pools pre-allocated 🚫 Parameter updates sin smoothing - Usa ParameterSmoother 🚫 Denormals sin flushing - Activa FTZ/DAZ flags 🚫 Ignorar Nyquist - Usa anti-aliasing (PolyBLEP, oversampling) 🚫 Hardcoded sample rate - Siempre usa set_sample_rate() 🚫 State sin reset() - Implementa reset() correctamente


👥 OWNERSHIP

Maintainer: TBD Team: Core DSP Team Status: 🔄 IN DEVELOPMENT - Estructura creada, implementación en progreso


📈 ROADMAP

Fase 1 - Core Atoms (6 semanas)

  • Base Infrastructure (processor, buffer, params)
  • Oscillator (5 waveforms + anti-aliasing)
  • Envelope (ADSR + multi-stage)
  • LFO (tempo sync + random)

Fase 2 - Processing Atoms (6 semanas)

  • Filter (biquad, SVF, ladder)
  • Saturator (7 modos)
  • Gain (smoothing + dB conversion)

Fase 3 - Spatial/Temporal (4 semanas)

  • Delay (simple, modulated, ping-pong)
  • Pan (4 pan laws, stereo width)

Fase 4 - System Integration (4 semanas)

  • Preset system (JSON, morphing)
  • Factory pattern
  • Integration tests
  • Documentation completa

Total: ~20 semanas (5 meses) con 3 devs en paralelo


🛠️ CONTRIBUCIÓN

Para contribuir a L1 Atoms:

  1. Lee PLAN_DE_DESARROLLO.md para contexto
  2. Revisa tareas disponibles en proyecto board
  3. Implementa siguiendo patrones existentes
  4. Asegura >95% test coverage
  5. Verifica RT-safety (zero allocations)
  6. Documenta API y ejemplos
  7. Submit PR con tests passing

Para información detallada de implementación, consultar PLAN_DE_DESARROLLO.md