dspx 0.1.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +185 -0
- package/.vscode/c_cpp_properties.json +17 -0
- package/.vscode/settings.json +68 -0
- package/.vscode/tasks.json +28 -0
- package/DISCLAIMER.md +32 -0
- package/LICENSE +21 -0
- package/README.md +1803 -0
- package/ROADMAP.md +192 -0
- package/TECHNICAL_DEBT.md +165 -0
- package/binding.gyp +65 -0
- package/docs/ADVANCED_LOGGER_FEATURES.md +598 -0
- package/docs/AUTHENTICATION_SECURITY.md +396 -0
- package/docs/BACKEND_IMPROVEMENTS.md +399 -0
- package/docs/CHEBYSHEV_BIQUAD_EQ_IMPLEMENTATION.md +405 -0
- package/docs/FFT_IMPLEMENTATION.md +490 -0
- package/docs/FFT_IMPROVEMENTS_SUMMARY.md +387 -0
- package/docs/FFT_USER_GUIDE.md +494 -0
- package/docs/FILTERS_IMPLEMENTATION.md +260 -0
- package/docs/FILTER_API_GUIDE.md +418 -0
- package/docs/FIR_SIMD_OPTIMIZATION.md +175 -0
- package/docs/LOGGER_API_REFERENCE.md +350 -0
- package/docs/NOTCH_FILTER_QUICK_REF.md +121 -0
- package/docs/PHASE2_TESTS_AND_NOTCH_FILTER.md +341 -0
- package/docs/PHASES_5_7_SUMMARY.md +403 -0
- package/docs/PIPELINE_FILTER_INTEGRATION.md +446 -0
- package/docs/SIMD_OPTIMIZATIONS.md +211 -0
- package/docs/TEST_MIGRATION_SUMMARY.md +173 -0
- package/docs/TIMESERIES_IMPLEMENTATION_SUMMARY.md +322 -0
- package/docs/TIMESERIES_QUICK_REF.md +85 -0
- package/docs/advanced.md +559 -0
- package/docs/time-series-guide.md +617 -0
- package/docs/time-series-migration.md +376 -0
- package/jest.config.js +37 -0
- package/package.json +42 -0
- package/prebuilds/linux-x64/dsp-ts-redis.node +0 -0
- package/prebuilds/win32-x64/dsp-ts-redis.node +0 -0
- package/scripts/test.js +24 -0
- package/src/build/dsp-ts-redis.node +0 -0
- package/src/native/DspPipeline.cc +675 -0
- package/src/native/DspPipeline.h +44 -0
- package/src/native/FftBindings.cc +817 -0
- package/src/native/FilterBindings.cc +1001 -0
- package/src/native/IDspStage.h +53 -0
- package/src/native/adapters/InterpolatorStage.h +201 -0
- package/src/native/adapters/MeanAbsoluteValueStage.h +289 -0
- package/src/native/adapters/MovingAverageStage.h +306 -0
- package/src/native/adapters/RectifyStage.h +88 -0
- package/src/native/adapters/ResamplerStage.h +238 -0
- package/src/native/adapters/RmsStage.h +299 -0
- package/src/native/adapters/SscStage.h +121 -0
- package/src/native/adapters/VarianceStage.h +307 -0
- package/src/native/adapters/WampStage.h +114 -0
- package/src/native/adapters/WaveformLengthStage.h +115 -0
- package/src/native/adapters/ZScoreNormalizeStage.h +326 -0
- package/src/native/core/FftEngine.cc +441 -0
- package/src/native/core/FftEngine.h +224 -0
- package/src/native/core/FirFilter.cc +324 -0
- package/src/native/core/FirFilter.h +149 -0
- package/src/native/core/IirFilter.cc +576 -0
- package/src/native/core/IirFilter.h +210 -0
- package/src/native/core/MovingAbsoluteValueFilter.cc +17 -0
- package/src/native/core/MovingAbsoluteValueFilter.h +135 -0
- package/src/native/core/MovingAverageFilter.cc +18 -0
- package/src/native/core/MovingAverageFilter.h +135 -0
- package/src/native/core/MovingFftFilter.cc +291 -0
- package/src/native/core/MovingFftFilter.h +203 -0
- package/src/native/core/MovingVarianceFilter.cc +194 -0
- package/src/native/core/MovingVarianceFilter.h +114 -0
- package/src/native/core/MovingZScoreFilter.cc +215 -0
- package/src/native/core/MovingZScoreFilter.h +113 -0
- package/src/native/core/Policies.h +352 -0
- package/src/native/core/RmsFilter.cc +18 -0
- package/src/native/core/RmsFilter.h +131 -0
- package/src/native/core/SscFilter.cc +16 -0
- package/src/native/core/SscFilter.h +137 -0
- package/src/native/core/WampFilter.cc +16 -0
- package/src/native/core/WampFilter.h +101 -0
- package/src/native/core/WaveformLengthFilter.cc +17 -0
- package/src/native/core/WaveformLengthFilter.h +98 -0
- package/src/native/utils/CircularBufferArray.cc +336 -0
- package/src/native/utils/CircularBufferArray.h +62 -0
- package/src/native/utils/CircularBufferVector.cc +145 -0
- package/src/native/utils/CircularBufferVector.h +45 -0
- package/src/native/utils/NapiUtils.cc +53 -0
- package/src/native/utils/NapiUtils.h +21 -0
- package/src/native/utils/SimdOps.h +870 -0
- package/src/native/utils/SlidingWindowFilter.cc +239 -0
- package/src/native/utils/SlidingWindowFilter.h +159 -0
- package/src/native/utils/TimeSeriesBuffer.cc +205 -0
- package/src/native/utils/TimeSeriesBuffer.h +140 -0
- package/src/ts/CircularLogBuffer.ts +87 -0
- package/src/ts/DriftDetector.ts +331 -0
- package/src/ts/TopicRouter.ts +428 -0
- package/src/ts/__tests__/AdvancedDsp.test.ts +585 -0
- package/src/ts/__tests__/AuthAndEdgeCases.test.ts +241 -0
- package/src/ts/__tests__/Chaining.test.ts +387 -0
- package/src/ts/__tests__/ChebyshevBiquad.test.ts +229 -0
- package/src/ts/__tests__/CircularLogBuffer.test.ts +158 -0
- package/src/ts/__tests__/DriftDetector.test.ts +389 -0
- package/src/ts/__tests__/Fft.test.ts +484 -0
- package/src/ts/__tests__/ListState.test.ts +153 -0
- package/src/ts/__tests__/Logger.test.ts +208 -0
- package/src/ts/__tests__/LoggerAdvanced.test.ts +319 -0
- package/src/ts/__tests__/LoggerMinor.test.ts +247 -0
- package/src/ts/__tests__/MeanAbsoluteValue.test.ts +398 -0
- package/src/ts/__tests__/MovingAverage.test.ts +322 -0
- package/src/ts/__tests__/RMS.test.ts +315 -0
- package/src/ts/__tests__/Rectify.test.ts +272 -0
- package/src/ts/__tests__/Redis.test.ts +456 -0
- package/src/ts/__tests__/SlopeSignChange.test.ts +166 -0
- package/src/ts/__tests__/Tap.test.ts +164 -0
- package/src/ts/__tests__/TimeBasedExpiration.test.ts +124 -0
- package/src/ts/__tests__/TimeBasedRmsAndMav.test.ts +231 -0
- package/src/ts/__tests__/TimeBasedVarianceAndZScore.test.ts +284 -0
- package/src/ts/__tests__/TimeSeries.test.ts +254 -0
- package/src/ts/__tests__/TopicRouter.test.ts +332 -0
- package/src/ts/__tests__/TopicRouterAdvanced.test.ts +483 -0
- package/src/ts/__tests__/TopicRouterPriority.test.ts +487 -0
- package/src/ts/__tests__/Variance.test.ts +509 -0
- package/src/ts/__tests__/WaveformLength.test.ts +147 -0
- package/src/ts/__tests__/WillisonAmplitude.test.ts +197 -0
- package/src/ts/__tests__/ZScoreNormalize.test.ts +459 -0
- package/src/ts/advanced-dsp.ts +566 -0
- package/src/ts/backends.ts +1137 -0
- package/src/ts/bindings.ts +1225 -0
- package/src/ts/easter-egg.ts +42 -0
- package/src/ts/examples/MeanAbsoluteValue/test-state.ts +99 -0
- package/src/ts/examples/MeanAbsoluteValue/test-streaming.ts +269 -0
- package/src/ts/examples/MovingAverage/test-state.ts +85 -0
- package/src/ts/examples/MovingAverage/test-streaming.ts +188 -0
- package/src/ts/examples/RMS/test-state.ts +97 -0
- package/src/ts/examples/RMS/test-streaming.ts +253 -0
- package/src/ts/examples/Rectify/test-state.ts +107 -0
- package/src/ts/examples/Rectify/test-streaming.ts +242 -0
- package/src/ts/examples/Variance/test-state.ts +195 -0
- package/src/ts/examples/Variance/test-streaming.ts +260 -0
- package/src/ts/examples/ZScoreNormalize/test-state.ts +277 -0
- package/src/ts/examples/ZScoreNormalize/test-streaming.ts +306 -0
- package/src/ts/examples/advanced-dsp-examples.ts +397 -0
- package/src/ts/examples/callbacks/advanced-router-features.ts +326 -0
- package/src/ts/examples/callbacks/benchmark-circular-buffer.ts +109 -0
- package/src/ts/examples/callbacks/monitoring-example.ts +265 -0
- package/src/ts/examples/callbacks/pipeline-callbacks-example.ts +137 -0
- package/src/ts/examples/callbacks/pooled-callbacks-example.ts +274 -0
- package/src/ts/examples/callbacks/priority-routing-example.ts +277 -0
- package/src/ts/examples/callbacks/production-topic-router.ts +214 -0
- package/src/ts/examples/callbacks/topic-based-logging.ts +161 -0
- package/src/ts/examples/chaining/test-chaining-redis.ts +113 -0
- package/src/ts/examples/chaining/test-chaining.ts +52 -0
- package/src/ts/examples/emg-features-example.ts +284 -0
- package/src/ts/examples/fft-example.ts +309 -0
- package/src/ts/examples/fft-examples.ts +349 -0
- package/src/ts/examples/filter-examples.ts +320 -0
- package/src/ts/examples/list-state-example.ts +131 -0
- package/src/ts/examples/logger-example.ts +91 -0
- package/src/ts/examples/notch-filter-examples.ts +243 -0
- package/src/ts/examples/phase5/drift-detection-example.ts +290 -0
- package/src/ts/examples/phase6-7/production-observability.ts +476 -0
- package/src/ts/examples/phase6-7/redis-timeseries-integration.ts +446 -0
- package/src/ts/examples/redis/redis-example.ts +202 -0
- package/src/ts/examples/redis-example.ts +202 -0
- package/src/ts/examples/simd-benchmark.ts +126 -0
- package/src/ts/examples/tap-debugging.ts +230 -0
- package/src/ts/examples/timeseries/comparison-example.ts +290 -0
- package/src/ts/examples/timeseries/iot-sensor-example.ts +143 -0
- package/src/ts/examples/timeseries/redis-streaming-example.ts +233 -0
- package/src/ts/examples/waveform-length-example.ts +139 -0
- package/src/ts/fft.ts +722 -0
- package/src/ts/filters.ts +1078 -0
- package/src/ts/index.ts +120 -0
- package/src/ts/types.ts +589 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Waveform Length Example
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates how to use the waveformLength stage to compute
|
|
5
|
+
* the total path length of a signal over a sliding window.
|
|
6
|
+
*
|
|
7
|
+
* Waveform Length (WL) is useful for:
|
|
8
|
+
* - EMG signal analysis
|
|
9
|
+
* - Detecting signal complexity
|
|
10
|
+
* - Measuring signal variability
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { createDspPipeline } from "../bindings";
|
|
14
|
+
|
|
15
|
+
async function waveformLengthExample() {
|
|
16
|
+
console.log("=== Waveform Length Example ===\n");
|
|
17
|
+
|
|
18
|
+
// Create a pipeline with waveform length computation
|
|
19
|
+
const pipeline = createDspPipeline();
|
|
20
|
+
|
|
21
|
+
// Add waveform length stage with a 100-sample window
|
|
22
|
+
pipeline.WaveformLength({ windowSize: 100 });
|
|
23
|
+
|
|
24
|
+
// Example 1: Smooth sine wave (low waveform length)
|
|
25
|
+
console.log("Example 1: Smooth Sine Wave");
|
|
26
|
+
const smoothSignal = new Float32Array(200);
|
|
27
|
+
for (let i = 0; i < smoothSignal.length; i++) {
|
|
28
|
+
smoothSignal[i] = Math.sin(i * 0.1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await pipeline.process(smoothSignal, { channels: 1 });
|
|
32
|
+
|
|
33
|
+
// Average WL in the middle of the signal (after window fills)
|
|
34
|
+
const smoothAvg =
|
|
35
|
+
smoothSignal.slice(100, 150).reduce((a, b) => a + b, 0) / 50;
|
|
36
|
+
console.log(`Average WL (smooth): ${smoothAvg.toFixed(3)}`);
|
|
37
|
+
console.log("Smooth signals have lower waveform length\n");
|
|
38
|
+
|
|
39
|
+
// Reset for next example
|
|
40
|
+
pipeline.clearState();
|
|
41
|
+
|
|
42
|
+
// Example 2: Noisy signal (high waveform length)
|
|
43
|
+
console.log("Example 2: Noisy Signal");
|
|
44
|
+
const noisySignal = new Float32Array(200);
|
|
45
|
+
for (let i = 0; i < noisySignal.length; i++) {
|
|
46
|
+
noisySignal[i] = Math.sin(i * 0.1) + (Math.random() - 0.5) * 0.5;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
await pipeline.process(noisySignal, { channels: 1 });
|
|
50
|
+
|
|
51
|
+
const noisyAvg = noisySignal.slice(100, 150).reduce((a, b) => a + b, 0) / 50;
|
|
52
|
+
console.log(`Average WL (noisy): ${noisyAvg.toFixed(3)}`);
|
|
53
|
+
console.log("Noisy signals have higher waveform length\n");
|
|
54
|
+
|
|
55
|
+
// Reset for next example
|
|
56
|
+
pipeline.clearState();
|
|
57
|
+
|
|
58
|
+
// Example 3: Multi-channel EMG-like signal
|
|
59
|
+
console.log("Example 3: Multi-Channel Processing (2 channels)");
|
|
60
|
+
const multiChannel = new Float32Array(400); // 200 samples × 2 channels
|
|
61
|
+
|
|
62
|
+
for (let i = 0; i < 200; i++) {
|
|
63
|
+
// Channel 0: High-frequency component
|
|
64
|
+
multiChannel[i * 2] = Math.sin(i * 0.3) * Math.exp(-i / 100);
|
|
65
|
+
|
|
66
|
+
// Channel 1: Low-frequency component
|
|
67
|
+
multiChannel[i * 2 + 1] = Math.sin(i * 0.05) * 0.5;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
await pipeline.process(multiChannel, { channels: 2 });
|
|
71
|
+
|
|
72
|
+
// Extract and analyze each channel separately
|
|
73
|
+
const channel0 = new Float32Array(200);
|
|
74
|
+
const channel1 = new Float32Array(200);
|
|
75
|
+
for (let i = 0; i < 200; i++) {
|
|
76
|
+
channel0[i] = multiChannel[i * 2];
|
|
77
|
+
channel1[i] = multiChannel[i * 2 + 1];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const ch0Avg = channel0.slice(100, 150).reduce((a, b) => a + b, 0) / 50;
|
|
81
|
+
const ch1Avg = channel1.slice(100, 150).reduce((a, b) => a + b, 0) / 50;
|
|
82
|
+
|
|
83
|
+
console.log(`Channel 0 avg WL: ${ch0Avg.toFixed(3)} (high frequency)`);
|
|
84
|
+
console.log(`Channel 1 avg WL: ${ch1Avg.toFixed(3)} (low frequency)`);
|
|
85
|
+
console.log("Higher frequency signals have higher waveform length\n");
|
|
86
|
+
|
|
87
|
+
// Example 4: Real-time processing with state persistence
|
|
88
|
+
console.log("Example 4: State Persistence (Redis-ready)");
|
|
89
|
+
pipeline.clearState();
|
|
90
|
+
|
|
91
|
+
// Process first batch
|
|
92
|
+
const batch1 = new Float32Array(100);
|
|
93
|
+
for (let i = 0; i < 100; i++) {
|
|
94
|
+
batch1[i] = Math.sin(i * 0.2);
|
|
95
|
+
}
|
|
96
|
+
await pipeline.process(batch1, { channels: 1 });
|
|
97
|
+
|
|
98
|
+
// Save state (would be stored in Redis in production)
|
|
99
|
+
const state = await pipeline.saveState();
|
|
100
|
+
console.log("State saved after first batch");
|
|
101
|
+
|
|
102
|
+
// Create new pipeline with same structure and restore state
|
|
103
|
+
const newPipeline = createDspPipeline();
|
|
104
|
+
newPipeline.WaveformLength({ windowSize: 100 }); // Must match original pipeline
|
|
105
|
+
await newPipeline.loadState(state);
|
|
106
|
+
|
|
107
|
+
// Process second batch with restored state
|
|
108
|
+
const batch2 = new Float32Array(100);
|
|
109
|
+
for (let i = 0; i < 100; i++) {
|
|
110
|
+
batch2[i] = Math.sin((i + 100) * 0.2);
|
|
111
|
+
}
|
|
112
|
+
await newPipeline.process(batch2, { channels: 1 });
|
|
113
|
+
|
|
114
|
+
console.log("State restored and processing continued seamlessly\n");
|
|
115
|
+
|
|
116
|
+
// Example 5: Chaining with other stages
|
|
117
|
+
console.log("Example 5: Pipeline Chaining");
|
|
118
|
+
const chainPipeline = createDspPipeline();
|
|
119
|
+
|
|
120
|
+
// Rectify → Waveform Length
|
|
121
|
+
chainPipeline.Rectify({ mode: "full" });
|
|
122
|
+
chainPipeline.WaveformLength({ windowSize: 50 });
|
|
123
|
+
|
|
124
|
+
const chainSignal = new Float32Array(150);
|
|
125
|
+
for (let i = 0; i < 150; i++) {
|
|
126
|
+
chainSignal[i] = Math.sin(i * 0.15) * 2 - 1; // Oscillating signal
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
await chainPipeline.process(chainSignal, { channels: 1 });
|
|
130
|
+
|
|
131
|
+
const chainAvg = chainSignal.slice(50, 100).reduce((a, b) => a + b, 0) / 50;
|
|
132
|
+
console.log(`WL after rectification: ${chainAvg.toFixed(3)}`);
|
|
133
|
+
console.log("Rectification can change the waveform length characteristics\n");
|
|
134
|
+
|
|
135
|
+
console.log("=== Example Complete ===");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Run the example
|
|
139
|
+
waveformLengthExample().catch(console.error);
|