Overview

Signal Processing

Mixing & Mastering

Source Code

// This example simulates a real-world audio mastering chain using 
// high-performance element-wise array operations.
//
// Key features demonstrated:
//  - Mixing (Additive): Combining a carrier signal with noise.
//  - Amplitude Modulation: Shaping a signal with a gain envelope.
//  - Full-Wave Hard Limiting: Clipping a signal between dynamic bounds (Min and Max).
//  - Energy Analysis: Calculating total signal power (RMS) via DotProduct.

const SAMPLES = 2000;
const FREQ = 440.0; 
const RATE = 44100;

// 1. Generate Basic Signals
var signal, noise, envelope, ceiling, floor : array of Float;
signal.SetLength(SAMPLES);
noise.SetLength(SAMPLES);
envelope.SetLength(SAMPLES);
ceiling.SetLength(SAMPLES);
floor.SetLength(SAMPLES);

for var i := 0 to SAMPLES - 1 do begin
   // Sine wave with intentional overdrive (Amplitude = 1.5)
   signal[i] := Sin(2 * Pi * FREQ * i / RATE) * 1.5;
   
   // Subtle white noise
   noise[i] := (Random - 0.5) * 0.05;
   
   // Slow fade-out envelope
   envelope[i] := 1.0 - (0.5 * i / SAMPLES);
   
   // Variable "safety ceiling" that tightens from 0.9 down to 0.4
   ceiling[i] := 0.9 - (0.5 * i / SAMPLES);
   floor[i] := -ceiling[i]; // Matching negative floor
end;

PrintLn(Format('Mastering Chain processing %d samples...', [SAMPLES]));

// 2-4. Processing Chain (Mixing, Shaping, and Limiting)
// We use fluent method chaining to perform multiple vectorized operations
// in a single statement. Note that these methods are mutating the 'signal' array.
signal
  .Offset(noise)      // Additive Mixing
  .Multiply(envelope) // Envelope Shaping
  .Min(ceiling)       // Top-side Clipping
  .Max(floor);        // Bottom-side Clipping

PrintLn('Step 1-3: Mixing, Modulation, and Full-Wave Limiting complete (via fluent chaining).');

// 5. Total Signal Power (RMS calculation)
var sumSquares := ArrayDotProduct(signal, signal);
var rms := Sqrt(sumSquares / SAMPLES);
PrintLn(Format('Step 4: Total Energy (RMS) calculated: %.4f', [rms]));

// 6. Inspect Results (Middle of the buffer to see clipping in action)
PrintLn('<br><b>Waveform Clipping Profile (Samples 1000-1010):</b>');
for var i := 1000 to 1009 do begin
   var status := if (signal[i] = ceiling[i]) or (signal[i] = floor[i]) then '[CLIPPED]' else '';
   PrintLn(Format(' Sample #%d: %7.4f  (Limit: %7.4f)  %s', [i, signal[i], ceiling[i], status]));
end;

Result

Mastering Chain processing 2000 samples...
Step 1-3: Mixing, Modulation, and Full-Wave Limiting complete (via fluent chaining).
Step 4: Total Energy (RMS) calculated: 0.5741
<br><b>Waveform Clipping Profile (Samples 1000-1010):</b>
 Sample #1000: -0.1530  (Limit:  0.6500)  
 Sample #1001: -0.0772  (Limit:  0.6498)  
 Sample #1002: -0.0308  (Limit:  0.6495)  
 Sample #1003:  0.0577  (Limit:  0.6493)  
 Sample #1004:  0.1160  (Limit:  0.6490)  
 Sample #1005:  0.1914  (Limit:  0.6488)  
 Sample #1006:  0.2691  (Limit:  0.6485)  
 Sample #1007:  0.3249  (Limit:  0.6483)  
 Sample #1008:  0.4098  (Limit:  0.6480)  
 Sample #1009:  0.4427  (Limit:  0.6478)  
On this page