AudioLab Type System¶
Location: 2 - FOUNDATION/04_CORE/04_00_type_system/
Type: Header-only INTERFACE library
Dependencies: None (foundational module)
Target: AudioLab::TypeSystem
Purpose¶
The Type System module provides fundamental type definitions, SIMD types, buffer abstractions, and type traits for the entire AudioLab framework. It serves as the foundation for type-safe, high-performance audio processing.
Key Features¶
- Zero Runtime Overhead: All types are
constexprwhen possible - Header-Only: No linking required, maximum inlining
- Platform Agnostic: Automatic SIMD detection (AVX2, NEON)
- Type Safety: Strong typing for samples, parameters, buffers
- Compile-Time Validation: Extensive use of
static_assert
Module Structure¶
00_type_system/
├── 00_fundamental_types/ # Sample types, channel configs, sample rates
├── 01_simd_types/ # Platform-specific SIMD wrappers
├── 02_buffer_types/ # Audio buffer abstractions
├── 03_parameter_types/ # Parameter value types & ranges
├── 04_conversion_traits/ # Type conversion utilities
└── tests/ # Unit tests for all types
Available Types¶
Fundamental Types (00_fundamental_types/)¶
// Sample types
using Sample = float; // Primary audio sample type
using SampleD = double; // High-precision sample
using SampleI = int32_t; // Integer sample (24-bit DACs)
// Channel configurations
enum class ChannelConfig {
Mono,
Stereo,
Surround_5_1,
Surround_7_1
};
// Sample rate types
template<uint32_t Rate>
struct SampleRate {
static constexpr uint32_t value = Rate;
};
using SR_44100 = SampleRate<44100>;
using SR_48000 = SampleRate<48000>;
using SR_96000 = SampleRate<96000>;
SIMD Types (01_simd_types/)¶
// Platform-agnostic SIMD vector
template<typename T, size_t N>
struct SimdVector {
// Auto-selects AVX2, NEON, or scalar fallback
};
// Common aliases
using SimdFloat4 = SimdVector<float, 4>;
using SimdFloat8 = SimdVector<float, 8>; // AVX2 if available
Buffer Types (02_buffer_types/)¶
// Non-owning buffer view
template<typename SampleT>
class AudioBufferView {
// Lightweight, passed by value
};
// Multi-channel buffer
template<typename SampleT, size_t Channels>
class AudioBuffer {
// Aligned allocation for SIMD
};
// Circular buffer for delay lines
template<typename T>
class CircularBuffer {
// RT-safe, power-of-2 size, fractional delay support
};
Parameter Types (03_parameter_types/)¶
// Type-safe parameter value
template<typename T, T Min, T Max>
struct RangedParameter {
static constexpr T min = Min;
static constexpr T max = Max;
// Compile-time range validation
};
// Normalized parameter [0.0, 1.0]
struct NormalizedParam {
float value;
constexpr explicit NormalizedParam(float v);
};
Conversion Traits (04_conversion_traits/)¶
// Sample format conversion
template<typename From, typename To>
struct SampleConverter {
static constexpr To convert(From value) noexcept;
};
// Automatic conversion detection
template<typename T>
inline constexpr bool is_sample_type_v = /* ... */;
Usage Examples¶
Basic Sample Processing¶
#include <audiolab/type_system/00_fundamental_types/sample.hpp>
constexpr Sample process(Sample input) {
return input * 0.5f; // Simple gain, constexpr-friendly
}
SIMD Processing¶
#include <audiolab/type_system/01_simd_types/simd_vector.hpp>
void process_block(AudioBufferView<float> buffer) {
for (size_t i = 0; i < buffer.size(); i += 8) {
auto vec = SimdFloat8::load(&buffer[i]);
vec *= 0.5f;
vec.store(&buffer[i]);
}
}
Type-Safe Parameters¶
#include <audiolab/type_system/03_parameter_types/ranged.hpp>
using Gain = RangedParameter<float, 0.0f, 2.0f>;
constexpr Gain my_gain{1.0f}; // Compile-time validated
static_assert(my_gain.value >= Gain::min);
Circular Buffer (Delay Line)¶
#include <audiolab/type_system/02_buffer_types/circular_buffer.hpp>
using namespace audiolab::core::types;
// Create delay buffer: 500ms @ 48kHz
size_t bufferSize = calculateDelayBufferSize(0.5, 48000.0); // Returns 32768
CircularBuffer<float> delayLine(bufferSize);
// Simple delay effect
void processDelay(float input, float& output) {
delayLine.write(input);
output = delayLine.read(24000); // 500ms delay
}
// Chorus effect with modulated delay
void processChorus(float input, float& output, float lfoPhase) {
delayLine.write(input);
// Modulate delay: 10ms ± 5ms
float delaySamples = 480.0f + 240.0f * std::sin(lfoPhase);
output = delayLine.readLinear(delaySamples); // Linear interpolation
}
// Multi-tap delay (reverb-style)
void processReverb(float input, float& output) {
delayLine.write(input);
const size_t taps[] = {1200, 2400, 4800, 9600}; // 25ms, 50ms, 100ms, 200ms
float tapOutputs[4];
delayLine.readMultiple(taps, tapOutputs, 4);
output = (tapOutputs[0] + tapOutputs[1] + tapOutputs[2] + tapOutputs[3]) * 0.25f;
}
Best Practices¶
1. Use Strong Types¶
// ❌ Avoid raw primitives
void process(float gain, float pan);
// ✅ Use typed parameters
void process(GainParam gain, PanParam pan);
2. Prefer constexpr¶
// ✅ Enable compile-time computation
constexpr Sample db_to_linear(float db) {
return std::pow(10.0f, db / 20.0f);
}
3. Leverage SIMD Types¶
// ❌ Scalar loop
for (size_t i = 0; i < N; ++i) {
output[i] = input[i] * gain;
}
// ✅ SIMD batch processing
for (size_t i = 0; i < N; i += SimdFloat8::size) {
auto vec = SimdFloat8::load(&input[i]);
(vec * gain).store(&output[i]);
}
4. Use Buffer Views for APIs¶
// ✅ Non-owning, lightweight
void process(AudioBufferView<Sample> input,
AudioBufferView<Sample> output);
Platform Support¶
| Platform | SIMD | Status |
|---|---|---|
| x86_64 | AVX2 | ✅ Full support |
| x86_64 | SSE4 | ✅ Fallback |
| ARM64 | NEON | ✅ Full support |
| Generic | None | ✅ Scalar fallback |
Dependencies¶
Internal: None (foundational module) External: C++17 standard library only
Testing¶
All types have comprehensive unit tests:
See Also¶
- Math Primitives - Mathematical operations on types
- Buffer Management - Advanced buffer utilities
- Parameter System - Runtime parameter handling
Documentation¶
Detailed documentation for each type category: