<?php
/**
* @ASCOOS-NAME : Ascoos OS
* @ASCOOS-VERSION : 26.0.0
* @ASCOOS-SUPPORT : support@ascoos.com
* @ASCOOS-BUGS : https://issues.ascoos.com
*
* @desc <English> Designs an RLC band-pass filter, applies a digital FIR filter to an audio signal, generates a SPICE netlist,
* and processes the audio with normalization, trimming, and fade effects. A frequency response graph is created.
* @desc <Greek> ????????? ??? RLC ?????????? ??????, ????????? ??????? FIR ?????? ?? ???? ????, ?????????? SPICE netlist,
* ??? ????????????? ??? ??? ?? ??????????????, ???????? ??? ??? fade. ????????????? ??????? ????????? ??????????.
*
* @since PHP 8.2.0
*/
declare(strict_types=1);
use ASCOOS\OS\Extras\Science\Electronics\TElectronicsHandler;
use ASCOOS\OS\Extras\Science\Electronics\TCircuitHandler;
use ASCOOS\OS\Extras\Science\Electronics\TDigitalCircuitHandler;
use ASCOOS\OS\Extras\Sounds\TAudioHandler;
use ASCOOS\OS\Kernel\Validation\TValidationHandler;
use ASCOOS\OS\Kernel\Arrays\Events\TEventHandler;
use ASCOOS\OS\Kernel\Core\Errors\Messages\TErrorMessageHandler;
use ASCOOS\OS\Extras\Arrays\Graphs\TArrayGraphHandler;
global $AOS_LOGS_PATH, $AOS_TMP_DATA_PATH, $AOS_ESTR, $AOS_FONTS_PATH;
// <English> Initialize configuration for logging, data storage, audio, and graphing.
// <Greek> ???????????? ????????? ??? ?????????, ?????????? ?????????, ??? ??? ?????????.
$properties = [
'logs' => [
'useLogger' => true,
'dir' => $AOS_LOGS_PATH . '/',
'file' => 'audio_rlc_fir_processing.log'
],
'file' => [
'baseDir' => $AOS_TMP_DATA_PATH . '/reports/audio_rlc_fir',
'quotaSize' => 500000000 // 500MB quota
],
'audio' => [
'samplingFrequency' => 44100, // 44.1 kHz
'inputFile' => 'input_audio.wav',
'outputFile' => 'processed_audio.wav',
'trimStart' => 1.0, // Start trimming at 1 second
'trimEnd' => 9.0 // End trimming at 9 seconds
],
'LineChart' => [
'width' => 800,
'height' => 600,
'showAxes' => true,
'fontPath' => $AOS_FONTS_PATH . '/Murecho/Murecho-Regular.ttf',
'backgroundColorIndex' => 1, // White
'lineColorIndex' => 0, // Black
'axisColorIndex' => 0 // Black
]
];
// <English> Initialize handlers for electronics, circuits, digital processing, audio, validation, events, and error handling.
// <Greek> ???????????? ????????? ??? ???????????, ?????????, ??????? ???????????, ???, ?????????, ???????? ??? ?????????? ?????????.
$electronicsHandler = new TElectronicsHandler([], $properties);
$circuitHandler = new TCircuitHandler([], $properties);
$digitalHandler = new TDigitalCircuitHandler([], $properties);
$audioHandler = new TAudioHandler([], $properties);
$validationHandler = new TValidationHandler($properties);
$eventHandler = new TEventHandler([], $properties);
$errorHandler = new TErrorMessageHandler('el-GR', $properties);
$graphHandler = new TArrayGraphHandler([], $properties['LineChart']);
try {
// <English> Step 1: Design an RLC band-pass filter for audio frequencies (300 Hz to 3 kHz).
// <Greek> ???? 1: ?????????? RLC ??????????? ??????? ??? ?????????? ???? (300 Hz ??? 3 kHz).
$centerFrequency = 1000; // Hz
$resistance = 1000; // 1 k?
$inductance = 0.1; // 100 mH
$capacitance = 1 / (4 * pi() * pi() * $inductance * $centerFrequency * $centerFrequency); // C = 1/(4?²f?²L)
$bandpassGain = $electronicsHandler->bandpassFilterGain($centerFrequency, $resistance, $inductance, $capacitance);
// <English> Validate RLC parameters.
// <Greek> ????????? ?????????? RLC.
$rlcRules = [
'resistance' => 'required|numeric|min:0',
'inductance' => 'required|numeric|min:0',
'capacitance' => 'required|numeric ??????|min:0'
];
$rlcData = [
'resistance' => $resistance,
'inductance' => $inductance,
'capacitance' => $capacitance
];
if (!$validationHandler->validate($rlcData, $rlcRules)) {
$errs = $validationHandler->getErrors();
$errorHandler->logError(E_ASCOOS_INVALID_VALIDATION, new Exception(implode(', ', $errs)));
echo $errorHandler->getMessage(E_ASCOOS_INVALID_VALIDATION);
exit;
}
// <English> Step 2: Generate SPICE netlist for the RLC filter.
// <Greek> ???? 2: ?????????? SPICE netlist ??? ?? RLC ??????.
$components = [
['type' => 'resistor', 'name' => 'R1', 'value' => $resistance, 'node1' => 'in', 'node2' => 'n1'],
['type' => 'inductor', 'name' => 'L1', 'value' => $inductance, 'node1' => 'n1', 'node2' => 'out'],
['type' => 'capacitor', 'name' => 'C1', 'value' => $capacitance, 'node1' => 'out', 'node2' => 'gnd']
];
$netlist = $circuitHandler->generateSpiceNetlist($components);
file_put_contents($properties['file']['baseDir'] . '/rlc_filter.sp', $netlist);
// <English> Step 3: Read and process audio signal with an FIR filter.
// <Greek> ???? 3: ???????? ??? ??????????? ??????? ???? ?? FIR ??????.
$firCoefficients = [0.25, 0.5, 0.25]; // Simple 3-tap FIR filter
$signal = $audioHandler->readWavFile($properties['audio']['inputFile']);
$filteredSignal = $digitalHandler->applyFIRFilter($firCoefficients, $signal);
// <English> Step 4: Analyze frequency response of the FIR filter.
// <Greek> ???? 4: ??????? ????????? ?????????? ??? FIR ???????.
$freqResponse = $digitalHandler->frequencyResponse($firCoefficients, 512);
$graphHandler->setArray(array_map('abs', $freqResponse), ['frequency', 'magnitude']);
$graphHandler->createLineChart($properties['file']['baseDir'] . '/fir_frequency_response.png');
// <English> Step 5: Trim, apply fade, and normalize the signal.
// <Greek> ???? 5: ????????, ???????? ??? fade ??? ?????????????? ??? ???????.
$trimmedSignal = $audioHandler->trimSignal(
$filteredSignal,
$properties['audio']['trimStart'],
$properties['audio']['trimEnd'],
$properties['audio']['samplingFrequency']
);
$fadeSamples = (int)($properties['audio']['samplingFrequency'] * 0.5); // 0.5 seconds fade
$signalWithFade = $audioHandler->fadeIn($trimmedSignal, $fadeSamples);
$signalWithFade = $audioHandler->fadeOut($signalWithFade, $fadeSamples);
$normalizedSignal = $audioHandler->normalizeSignal($signalWithFade, 0.9);
$audioHandler->writeWavFile($normalizedSignal, $properties['audio']['samplingFrequency'], $properties['audio']['outputFile']);
// <English> Step 6: Log successful processing event.
// <Greek> ???? 6: ????????? ????????? ????????? ????????????.
$eventHandler->register('signal_processed', 'audio', fn() =>
$eventHandler->logger->log('Audio signal processed successfully with RLC and FIR filters', $eventHandler::DEBUG_LEVEL_INFO)
);
$eventHandler->trigger('signal_processed', 'audio');
// <English> Step 7: Save JSON report with filter parameters and signal stats.
// <Greek> ???? 7: ?????????? JSON ???????? ?? ??????????? ??????? ??? ?????????? ???????.
$report = [
'rlc_filter' => [
'center_frequency' => $centerFrequency,
'resistance' => $resistance,
'inductance' => $inductance,
'capacitance' => $capacitance,
'gain_at_center' => $bandpassGain
],
'fir_filter' => [
'coefficients' => $firCoefficients
],
'signal_stats' => [
'samples' => count($normalizedSignal),
'duration' => $audioHandler->getDuration($normalizedSignal, $properties['audio']['samplingFrequency'])
]
];
file_put_contents(
$properties['file']['baseDir'] . '/audio_rlc_fir_report.json',
json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
);
// <English> Output completion message.
// <Greek> ???????? ????????? ???????????.
echo "Audio processing with RLC and FIR filters completed. Report and netlist saved.\n";
} catch (Exception $e) {
// <English> Handle exceptions and log error.
// <Greek> ?????????? ?????????? ??? ????????? ?????????.
$errorHandler->logError(1007, $e);
echo $errorHandler->getMessage(1007);
}
// <English> Cleanup resources (free handlers).
// <Greek> ???????????? ????? (?????????? ?????????).
$electronicsHandler->Free($electronicsHandler);
$circuitHandler->Free($circuitHandler);
$digitalHandler->Free($digitalHandler);
$audioHandler->Free($audioHandler);
$validationHandler->Free($validationHandler);
$eventHandler->Free($eventHandler);
$errorHandler->Free($errorHandler);
$graphHandler->Free($graphHandler);
?>
|