PHP Classes

How to Implement a PHP Simulator of a Digital Signal Processing Circuit Learning from the Package Ascoos OS Digital Circuit DSP: Simulate a digital signal processing circuit

Recommend this page to a friend!
     
  Info   Example   View files Files   Install with Composer Install with Composer   Download Download   Reputation   Support forum   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2026-01-14 (1 month ago) RSS 2.0 feedNot yet rated by the usersTotal: Not yet counted Not yet ranked
Version License PHP version Categories
digital-circuit-dsp 1.0Custom (specified...8.3Algorithms, Audio, Hardware, PHP 8
Description 

Author

This package can simulate a digital signal processing (DSP) circuit.

It provides an example script that shows how to can create a circuit made of a set of filters that can be of a certain type and simulate the response of that circuit to given signals.

The example script shows how to:

- Generate clean and noisy signals

- Gaussian or Uniform noise injection

- FIR and IIR low-pass filtering

- Hann-windowed FFT

- SNR, THD, SINAD, ENOB estimation

- Latency estimation

- JSON or CSV results export support

- Logging and debugging

Innovation Award
PHP Programming Innovation award nominee
January 2026
Nominee
Vote
A digital signal processing circuit is an electronic circuit that can digitize a signal and apply different types of processing methods to obtain a better signal.

This package shows how to implement a simulation of a digital signal processing circuit using pure PHP code.

Manuel Lemos
Picture of Christos Drogidis
  Performance   Level  
Name: Christos Drogidis <contact>
Classes: 34 packages by
Country: Greece Greece
Innovation award
Innovation award
Nominee: 20x

Winner: 3x

Instructions

Please read this document to learn how to setup a simulator of a digital signal processor circuit.

Example

<?php
/**
 * @ASCOOS-NAME : Ascoos OS
 * @ASCOOS-VERSION : 1.0.0
 * @ASCOOS-SUPPORT : support@ascoos.com
 * @ASCOOS-BUGS : https://issues.ascoos.com
 *
 * @CASE-STUDY : digital_circuit_dsp.php
 * @fileNo : ASCOOS-OS-CASESTUDY-SEC02786
 *
 * @desc <English>
 * Simulates a digital signal processing pipeline: generates a clean 440 Hz sine + noisy version (uniform or Gaussian),
 * applies FIR & IIR low-pass filters, performs Hann-windowed FFT, estimates SNR improvement, THD, SINAD, ENOB and latency,
 * exports results to JSON/CSV ? for IoT/embedded DSP prototyping.
 * @desc <Greek>
 * ???????????? ????? ???????? ???????????? ???????: ?????????? ?????? ???????????? 440 Hz + ????????? ???? (?????????? ? Gaussian),
 * ????????? FIR & IIR low-pass ??????, ??????? FFT ?? ???????? Hann, ?????????? ???????? SNR, THD, SINAD, ENOB ??? ???????????,
 * ?????? ???????????? ?? JSON/CSV ? ??? ????????? IoT/embedded DSP.
 *
 * @since PHP 8.3.0+
 */
declare(strict_types=1);

use
ASCOOS\OS\Kernel\Science\Electronics\TDigitalCircuitHandler;

$properties = [
   
'logs' => [
       
'useLogger' => true,
       
'dir' => $AOS_LOGS_PATH,
       
'file' => 'dsp_simulation_improved.log'
   
]
];

try {
   
$dHandler = new TDigitalCircuitHandler([], $properties);

   
// ????????????????????????????????????????????????
    // 1. <English> Test signal generation (clean + noisy)
    // <Greek> ?????????? ???????????? ??????? (?????? + ?????????)
    // ????????????????????????????????????????????????
   
$fs = 8000.0; // Sampling frequency (Hz)
   
$N = 1024; // Number of samples (power-of-2 for FFT)

   
$cleanSignal = []; // Pure 440 Hz sine
   
$noisySignal = []; // Sine + noise
   
$timeVector = []; // Time axis

   
$noiseScale = 0.03; // ~30 dB below main tone (for uniform)
   
$noiseStdDev = 0.03; // ~30 dB below main tone (for Gaussian)
   
$noiseType = 'gaussian'; // 'uniform' or 'gaussian'

   
for ($i = 0; $i < $N; $i++) {
       
$t = $i / $fs;
       
$s = sin(2 * M_PI * 440.0 * $t); // 440 Hz sine

       
if ($noiseType === 'gaussian') {
           
// Gaussian noise with stdDev = $noiseStdDev
           
$noise = $dHandler->gaussianNoise($noiseStdDev);
        } else {
           
// Uniform noise in [-1, 1) then scaled
           
$noise = $noiseScale * ((mt_rand() / mt_getrandmax() - 0.5) * 2.0);
        }

       
$timeVector[] = $t;
       
$cleanSignal[] = $s;
       
$noisySignal[] = $s + $noise;
    }

   
// ????????????????????????????????????????????????
    // 2. <English> FIR low-pass filtering (3-tap moving average)
    // <Greek> FIR low-pass ??????????? (3-tap ?????????? ?????)
    // ????????????????????????????????????????????????
   
$firCoeffs = [0.25, 0.5, 0.25]; // Simple triangular FIR
   
$firFiltered = $dHandler->applyFIRFilter($firCoeffs, $noisySignal);

   
// Group delay ~ (M-1)/2 samples
   
$firDelaySamples = (count($firCoeffs) - 1) / 2.0;
   
$firDelaySeconds = $firDelaySamples / $fs;

   
// ????????????????????????????????????????????????
    // 3. <English> IIR biquad low-pass Butterworth (2nd order @ 1800 Hz)
    // <Greek> IIR biquad low-pass Butterworth (2?? ????? @ 1800 Hz)
    // ????????????????????????????????????????????????
   
$fc = 1800.0; // Cutoff frequency
   
$Q = 1 / sqrt(2); // ?0.7071 ? Butterworth

   
$biquadCoeffs = $dHandler->biquadLowpassCoefficients($fc, $Q, $fs);
   
$iirFiltered = $dHandler->applyBiquadFilter($biquadCoeffs, $noisySignal);

   
// Approximate latency: 1 sample (implementation-dependent)
   
$iirDelaySamples = 1.0;
   
$iirDelaySeconds = $iirDelaySamples / $fs;

   
// ????????????????????????????????????????????????
    // 4. <English> Hann-windowed FFT analysis (reducing spectral leakage)
    // <Greek> ??????? FFT ?? ???????? Hann (?????? spectral leakage)
    // ????????????????????????????????????????????????
   
$hannWindow = [];
    for (
$i = 0; $i < $N; $i++) {
       
$hannWindow[] = 0.5 * (1.0 - cos(2.0 * M_PI * $i / ($N - 1)));
    }

   
$windowedSignal = [];
    for (
$i = 0; $i < $N; $i++) {
       
$windowedSignal[] = $noisySignal[$i] * $hannWindow[$i];
    }

   
$fftComplex = $dHandler->fft($windowedSignal, true); // Normalized FFT
   
$fftMagnitude = array_map([$dHandler, 'complexMagnitude'], $fftComplex);

   
// Keep only positive spectrum [0, fs/2]
   
$halfLength = (int)($N / 2) + 1;
   
$fftMags = array_slice($fftMagnitude, 0, $halfLength);

   
$fftFreqs = [];
   
$df = $fs / $N;
    for (
$i = 0; $i < $halfLength; $i++) {
       
$fftFreqs[] = $i * $df;
    }

   
// Peak frequency detection
   
$maxMag = max($fftMags);
   
$peakIdx = array_search($maxMag, $fftMags, true);
   
$peakFreq = $fftFreqs[$peakIdx] ?? 0.0;

   
// ????????????????????????????????????????????????
    // 5. <English> SNR estimation (input vs FIR vs IIR)
    // <Greek> ???????? SNR (??????? vs FIR vs IIR)
    // ????????????????????????????????????????????????
   
$snrInput = $dHandler->SNRdB($cleanSignal, $noisySignal); // SNR before filtering
   
$snrFIR = $dHandler->SNRdB($cleanSignal, $firFiltered); // SNR after FIR
   
$snrIIR = $dHandler->SNRdB($cleanSignal, $iirFiltered); // SNR after IIR

   
$snrFirGain = $snrFIR - $snrInput;
   
$snrIirGain = $snrIIR - $snrInput;

   
// ????????????????????????????????????????????????
    // 5b. <English> THD, SINAD, ENOB estimation (from FFT)
    // <Greek> ???????? THD, SINAD, ENOB ??? FFT
    // ????????????????????????????????????????????????
   
$dspMetrics = $dHandler->estimateThdSinadEnob($fftFreqs, $fftMags, 440.0, 5, 1.5);

   
$thdDb = $dspMetrics['thd_db'];
   
$sinadDb = $dspMetrics['sinad_db'];
   
$enob = $dspMetrics['enob_bits'];

   
// ????????????????????????????????????????????????
    // 6. <English> Console summary of key results
    // <Greek> ???????? ??????? ????????????? ???? ???????
    // ????????????????????????????????????????????????
   
echo "DSP Simulation Results / ???????????? DSP\n";
    echo
"??????????????????????????????????????????\n";
    echo
"Signal length : $N samples\n";
    echo
"Sampling rate : {$fs} Hz\n";
    echo
"Noise type : {$noiseType}\n";
    echo
"Peak frequency (FFT) : " . round($peakFreq, 1) . " Hz\n";
    echo
"Max FFT magnitude : " . round($maxMag, 4) . "\n\n";

    echo
"SNR (input noisy) : " . ($snrInput === INF ? "INF" : round($snrInput, 2)) . " dB\n";
    echo
"SNR (after FIR) : " . ($snrFIR === INF ? "INF" : round($snrFIR, 2)) . " dB\n";
    echo
"SNR (after IIR) : " . ($snrIIR === INF ? "INF" : round($snrIIR, 2)) . " dB\n\n";

    echo
"SNR gain (FIR) : " . (is_nan($snrFirGain) ? "NaN" : round($snrFirGain, 2)) . " dB\n";
    echo
"SNR gain (IIR) : " . (is_nan($snrIirGain) ? "NaN" : round($snrIirGain, 2)) . " dB\n\n";

    echo
"THD (approx) : " . (is_nan($thdDb) ? "NaN" : round($thdDb, 2)) . " dB\n";
    echo
"SINAD (approx) : " . (is_nan($sinadDb) ? "NaN" : round($sinadDb, 2)) . " dB\n";
    echo
"ENOB (approx) : " . (is_nan($enob) ? "NaN" : round($enob, 3)) . " bits\n\n";

    echo
"FIR delay : " . round($firDelaySamples, 2) . " samples (" . round($firDelaySeconds * 1e3, 3) . " ms)\n";
    echo
"IIR delay (approx) : " . round($iirDelaySamples, 2) . " samples (" . round($iirDelaySeconds * 1e3, 3) . " ms)\n\n";

    echo
"FIR first 5 samples : " . json_encode(array_slice($firFiltered, 0, 5), JSON_NUMERIC_CHECK) . "\n";
    echo
"IIR biquad coeffs : " . json_encode($biquadCoeffs, JSON_NUMERIC_CHECK) . "\n\n";

   
// ????????????????????????????????????????????????
    // 7. <English> Export full data to JSON
    // <Greek> ??????? ?????? ????????? ?? JSON
    // ????????????????????????????????????????????????
   
$jsonExportPath = $AOS_TMP_DATA_PATH . '/signal_dsp_demo.json';

   
$dHandler->toJSONFile($jsonExportPath, [
       
'fs' => $fs,
       
'N' => $N,
       
'time' => $timeVector,
       
'signals' => [
           
'clean' => $cleanSignal,
           
'noisy' => $noisySignal,
           
'fir' => $firFiltered,
           
'iir' => $iirFiltered,
        ],
       
'fft' => [
           
'freq' => $fftFreqs,
           
'mag' => $fftMags,
           
'window' => 'Hann',
        ],
       
'snr_db' => [
           
'input_noisy' => $snrInput,
           
'fir' => $snrFIR,
           
'iir' => $snrIIR,
        ],
       
'snr_improvement' => [
           
'fir_gain_db' => $snrFirGain,
           
'iir_gain_db' => $snrIirGain,
        ],
       
'latency' => [
           
'fir' => [
               
'samples' => $firDelaySamples,
               
'seconds' => $firDelaySeconds,
            ],
           
'iir' => [
               
'samples' => $iirDelaySamples,
               
'seconds' => $iirDelaySeconds,
            ],
        ],
       
'dsp_metrics' => [
           
'thd_db' => $thdDb,
           
'sinad_db' => $sinadDb,
           
'enob_bits' => $enob,
        ],
       
'metadata' => [
           
'peak_frequency_hz' => $peakFreq,
           
'generated_at' => date('c'),
           
'description_en' => 'DSP demo: 440 Hz sine, noise ('
               
. $noiseType . '), FIR/IIR low-pass, Hann FFT, SNR, THD, SINAD, ENOB & latency estimation.',
           
'description_gr' => 'Demo DSP: ???????????? 440 Hz, ??????? ('
               
. $noiseType . '), FIR/IIR low-pass, FFT Hann, ???????? SNR, THD, SINAD, ENOB & ????????????.',
           
'filters' => [
               
'fir_coeffs' => $firCoeffs,
               
'iir_cutoff_hz'=> $fc,
               
'iir_Q' => $Q,
               
'iir_coeffs' => $biquadCoeffs,
            ],
           
'plot_suggestions' => [
               
'time-domain: clean vs noisy vs FIR vs IIR',
               
'frequency-domain: FFT magnitude with 440 Hz peak',
               
'SNR evolution: input vs FIR vs IIR',
               
'DSP metrics: THD / SINAD / ENOB vs configuration',
            ],
        ],
    ]);

    echo
"JSON results exported to: $jsonExportPath\n";

   
// ????????????????????????????????????????????????
    // 8. <English> Export selected data to CSV (FFT spectrum & time-domain)
    // <Greek> ??????? ??????????? ????????? ?? CSV (????? FFT & ??????? ?????)
    // ????????????????????????????????????????????????

    // 8a. FFT spectrum CSV
   
$fftCsvPath = $AOS_TMP_DATA_PATH . '/signal_dsp_fft_spectrum.csv';

   
$fftHeader = [
       
'freq_hz',
       
'magnitude',
    ];

   
$fftRows = [];
    for (
$i = 0; $i < $halfLength; $i++) {
       
$fftRows[] = [
           
$fftFreqs[$i],
           
$fftMags[$i],
        ];
    }

   
$dHandler->toCSVFile($fftCsvPath, $fftRows, $fftHeader, ',');

    echo
"FFT spectrum exported to: $fftCsvPath\n";

   
// 8b. Time-domain signals CSV
   
$timeCsvPath = $AOS_TMP_DATA_PATH . '/signal_dsp_time_signals.csv';

   
$timeHeader = [
       
't_seconds',
       
'clean',
       
'noisy',
       
'fir',
       
'iir',
    ];

   
$timeRows = [];
    for (
$i = 0; $i < $N; $i++) {
       
$timeRows[] = [
           
$timeVector[$i],
           
$cleanSignal[$i],
           
$noisySignal[$i],
           
$firFiltered[$i] ?? null,
           
$iirFiltered[$i] ?? null,
        ];
    }

   
$dHandler->toCSVFile($timeCsvPath, $timeRows, $timeHeader, ',');

    echo
"Time-domain signals exported to: $timeCsvPath\n";

   
// ????????????????????????????????????????????????
    // 9. <English> Logging summary
    // <Greek> ?????? ??? log
    // ????????????????????????????????????????????????
   
$dHandler->logger?->log(
       
sprintf(
               
"DSP simulation completed | N=%d | noise=%s | peak=%.1f Hz | max_mag=%.4f | ". "SNR_in=%.2f dB | SNR_FIR=%.2f dB | SNR_IIR=%.2f dB | ".
           
"THD=%.2f dB | SINAD=%.2f dB | ENOB=%.3f bits | ".
           
"JSON=%s | FFT_CSV=%s | TIME_CSV=%s",
           
$N,
           
$noiseType,
           
$peakFreq,
           
$maxMag,
           
$snrInput,
           
$snrFIR,
           
$snrIIR,
           
$thdDb,
           
$sinadDb,
           
$enob,
           
$jsonExportPath,
           
$fftCsvPath,
           
$timeCsvPath
       
),
       
$dHandler::DEBUG_LEVEL_INFO
   
);

} catch (
Throwable $e) {
    echo
"Error / ??????: " . $e->getMessage() . "\n";

    if (isset(
$dHandler) && $dHandler->logger) {
       
$dHandler->logger->log(
           
"DSP simulation failed: " . $e->getMessage(),
           
$dHandler::DEBUG_LEVEL_ERROR
       
);
    }
} finally {
   
// ????????????????????????????????????????????????
    // 10. <English> Resources Release
    // <Greek> ???????????? ?????
    // ????????????????????????????????????????????????
   
if (isset($dHandler)) {
       
$dHandler->Free();
    }
}


Details

Digital Signal Processing Pipeline ? DSP Case Study

> Case Study Code: ASCOOS-OS-CASESTUDY-SEC02786

This case study demonstrates how Ascoos OS and the TDigitalCircuitHandler class implement a complete digital signal processing (DSP) pipeline in pure PHP, without external libraries.

The pipeline includes:

  • generation of clean and noisy signals
  • Gaussian or Uniform noise injection
  • FIR & IIR low?pass filtering
  • Hann?windowed FFT
  • SNR, THD, SINAD, ENOB estimation
  • latency estimation
  • JSON & CSV export
  • logging and debugging

The result is a complete, educational, and production?ready DSP implementation suitable for IoT, embedded simulation, audio pipelines, and academic use.

Purpose

  • Generate a clean 440 Hz sine wave
  • Add noise (Gaussian or Uniform)
  • Apply FIR & IIR low?pass filters
  • Perform FFT using a Hann window
  • Detect peak frequency
  • Compute: - SNR (input, FIR, IIR) - SNR improvement (gain) - THD (Total Harmonic Distortion) - SINAD (Signal?to?Noise And Distortion) - ENOB (Effective Number Of Bits)
  • Export results to JSON & CSV
  • Log all metrics for analysis

Core Ascoos OS Classes

DSP Core

  • TDigitalCircuitHandler Main DSP class: filters, FFT, SNR, Gaussian noise, THD/SINAD/ENOB.

DSP Utilities

  • gaussianNoise() Generates Gaussian noise using Box?Muller with caching
  • findClosestBin() Finds the nearest FFT bin within tolerance
  • estimateThdSinadEnob() Computes THD, SINAD, and ENOB from FFT data

Export & Logging

  • toJSONFile() Exports the full DSP pipeline to JSON
  • toCSVFile() Exports FFT spectrum & time?domain signals
  • Logger Records all metrics and file paths

File Structure

The implementation is located in:

This file includes:

  • signal generation
  • noise injection (Gaussian/Uniform)
  • FIR/IIR filtering
  • Hann?windowed FFT
  • SNR, THD, SINAD, ENOB
  • latency estimation
  • JSON/CSV export
  • logging

Architecture Diagram

????????????????????????????????????????????????????????????????????????????????
?                              ASCOOS OS KERNEL                                ?
?                     (Electronics ? DSP ? Math Engine)                        ?
????????????????????????????????????????????????????????????????????????????????
                                      ?
                                      ?
                    ????????????????????????????????????????
                    ?      TDigitalCircuitHandler          ?
                    ?  (Filters ? FFT ? Noise ? Metrics)   ?
                    ????????????????????????????????????????
                                      ?
                                      ?
         ????????????????????????????????????????????????????????????????????
         ?                         DSP Pipeline                             ?
         ????????????????????????????????????????????????????????????????????
                                      ?
                                      ?
         ????????????????????????????????????????????????????????????????????
         ? 1. Signal Generation (Clean + Noise)                             ?
         ? 2. FIR Filtering                                                 ?
         ? 3. IIR Filtering                                                 ?
         ? 4. Hann Window                                                   ?
         ? 5. FFT (Magnitude Spectrum)                                      ?
         ? 6. SNR / THD / SINAD / ENOB                                      ?
         ? 7. Latency Estimation                                            ?
         ? 8. JSON / CSV Export                                             ?
         ? 9. Logging                                                       ?
         ????????????????????????????????????????????????????????????????????
                                      ?
                                      ?
????????????????????????????????????????????????????????????????????????????????
?                           Unified DSP Output Renderer                        ?
?      (Console Summary ? JSON Data ? CSV Files ? Logs)                        ?
????????????????????????????????????????????????????????????????????????????????

Requirements

  1. PHP ? 8.3
  2. Installed Ascoos OS or AWES 26 Pro
  3. Enabled classes `TDigitalCircuitHandler`, `TCircuitHandler`, and `TElectronicsHandler` via the Extras Classes Manager
  4. Access to: - `$AOS_TMP_DATA_PATH` - `$AOS_LOGS_PATH`

Execution Flow

  1. Initialize the DSP Handler Loads `TDigitalCircuitHandler` with logging enabled.
  2. Generate clean signal 440 Hz sine wave, 1024 samples.
  3. Inject noise - Gaussian (Box?Muller) - or Uniform
  4. Apply FIR filter 3?tap moving average.
  5. Apply IIR biquad Butterworth filter 2nd?order, cutoff 1800 Hz.
  6. Apply Hann window Reduces spectral leakage.
  7. Perform FFT Computes magnitude spectrum.
  8. Detect peak frequency Finds the dominant spectral component.
  9. Compute SNR Input, FIR, IIR + SNR gain.
  10. Compute THD, SINAD, ENOB Using tolerance to handle leakage.
  11. Export JSON Full dataset + metadata.
  12. Export CSV FFT spectrum + time?domain signals.
  13. Logging Records all metrics and file paths.

Code Example

$dsp = new TDigitalCircuitHandler([], $properties);

$noise = $dsp->gaussianNoise(0.03);
$fir   = $dsp->applyFIRFilter($firCoeffs, $noisySignal);
$iir   = $dsp->applyBiquadFilter($biquadCoeffs, $noisySignal);

$fft   = $dsp->fft($windowed, true);
$mag   = array_map([$dsp, 'complexMagnitude'], $fft);

$metrics = $dsp->estimateThdSinadEnob($fftFreqs, $fftMags, 440.0);

Expected Output

=== DSP Simulation Results ===

Peak frequency (FFT): 440.0 Hz
Max FFT magnitude   : 0.9981

SNR (input noisy)   : 29.52 dB
SNR (after FIR)     : 33.87 dB
SNR (after IIR)     : 35.12 dB

THD (approx)        : -42.1 dB
SINAD (approx)      : 33.5 dB
ENOB (approx)       : 5.27 bits

JSON exported to: /tmp/signal_dsp_demo.json
FFT CSV exported to: /tmp/signal_dsp_fft_spectrum.csv
Time CSV exported to: /tmp/signal_dsp_time_signals.csv

Resources

License

This case study is covered under the Ascoos General License (AGL). See LICENSE.md.


  Files folder image Files (6)  
File Role Description
Accessible without login Plain text file digital_circuit_dsp-el.md Doc. Documentation
Accessible without login Plain text file digital_circuit_dsp.md Doc. Documentation
Accessible without login Plain text file digital_circuit_dsp.php Example Example script
Accessible without login Plain text file LICENSE-GR.md Lic. License text
Accessible without login Plain text file LICENSE.md Lic. License text
Accessible without login Plain text file README.md Doc. Documentation

The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page.
Install with Composer Install with Composer
Downloaddigital-circuit-dsp-2026-01-14.zip 13KB
Downloaddigital-circuit-dsp-2026-01-14.tar.gz
Install with ComposerInstall with Composer
Needed packages  
Class DownloadWhy it is needed Dependency
Ascoos OS Download .zip .tar.gz Uses kernel classes Required
 Version Control Unique User Downloads  
 100%
Total:0
This week:0