@jtarrio/signals 0.9.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.
Files changed (131) hide show
  1. package/LICENSE +203 -0
  2. package/README.md +54 -0
  3. package/dist/demod/demod-am.d.ts +55 -0
  4. package/dist/demod/demod-am.d.ts.map +1 -0
  5. package/dist/demod/demod-am.js +118 -0
  6. package/dist/demod/demod-am.js.map +1 -0
  7. package/dist/demod/demod-cw.d.ts +49 -0
  8. package/dist/demod/demod-cw.d.ts.map +1 -0
  9. package/dist/demod/demod-cw.js +106 -0
  10. package/dist/demod/demod-cw.js.map +1 -0
  11. package/dist/demod/demod-nbfm.d.ts +55 -0
  12. package/dist/demod/demod-nbfm.d.ts.map +1 -0
  13. package/dist/demod/demod-nbfm.js +119 -0
  14. package/dist/demod/demod-nbfm.js.map +1 -0
  15. package/dist/demod/demod-ssb.d.ts +56 -0
  16. package/dist/demod/demod-ssb.d.ts.map +1 -0
  17. package/dist/demod/demod-ssb.js +118 -0
  18. package/dist/demod/demod-ssb.js.map +1 -0
  19. package/dist/demod/demod-wbfm.d.ts +114 -0
  20. package/dist/demod/demod-wbfm.d.ts.map +1 -0
  21. package/dist/demod/demod-wbfm.js +226 -0
  22. package/dist/demod/demod-wbfm.js.map +1 -0
  23. package/dist/demod/demodulator.d.ts +3 -0
  24. package/dist/demod/demodulator.d.ts.map +1 -0
  25. package/dist/demod/demodulator.js +28 -0
  26. package/dist/demod/demodulator.js.map +1 -0
  27. package/dist/demod/empty-demodulator.d.ts +78 -0
  28. package/dist/demod/empty-demodulator.d.ts.map +1 -0
  29. package/dist/demod/empty-demodulator.js +148 -0
  30. package/dist/demod/empty-demodulator.js.map +1 -0
  31. package/dist/demod/modes.d.ts +113 -0
  32. package/dist/demod/modes.d.ts.map +1 -0
  33. package/dist/demod/modes.js +107 -0
  34. package/dist/demod/modes.js.map +1 -0
  35. package/dist/demod/player.d.ts +19 -0
  36. package/dist/demod/player.d.ts.map +1 -0
  37. package/dist/demod/player.js +15 -0
  38. package/dist/demod/player.js.map +1 -0
  39. package/dist/demod/sample-counter.d.ts +22 -0
  40. package/dist/demod/sample-counter.d.ts.map +1 -0
  41. package/dist/demod/sample-counter.js +57 -0
  42. package/dist/demod/sample-counter.js.map +1 -0
  43. package/dist/demod/spectrum.d.ts +23 -0
  44. package/dist/demod/spectrum.d.ts.map +1 -0
  45. package/dist/demod/spectrum.js +76 -0
  46. package/dist/demod/spectrum.js.map +1 -0
  47. package/dist/dsp/buffers.d.ts +127 -0
  48. package/dist/dsp/buffers.d.ts.map +1 -0
  49. package/dist/dsp/buffers.js +171 -0
  50. package/dist/dsp/buffers.js.map +1 -0
  51. package/dist/dsp/coefficients.d.ts +23 -0
  52. package/dist/dsp/coefficients.d.ts.map +1 -0
  53. package/dist/dsp/coefficients.js +81 -0
  54. package/dist/dsp/coefficients.js.map +1 -0
  55. package/dist/dsp/converters.d.ts +15 -0
  56. package/dist/dsp/converters.d.ts.map +1 -0
  57. package/dist/dsp/converters.js +43 -0
  58. package/dist/dsp/converters.js.map +1 -0
  59. package/dist/dsp/demodulators.d.ts +68 -0
  60. package/dist/dsp/demodulators.d.ts.map +1 -0
  61. package/dist/dsp/demodulators.js +149 -0
  62. package/dist/dsp/demodulators.js.map +1 -0
  63. package/dist/dsp/fft.d.ts +54 -0
  64. package/dist/dsp/fft.d.ts.map +1 -0
  65. package/dist/dsp/fft.js +175 -0
  66. package/dist/dsp/fft.js.map +1 -0
  67. package/dist/dsp/filters.d.ts +197 -0
  68. package/dist/dsp/filters.d.ts.map +1 -0
  69. package/dist/dsp/filters.js +486 -0
  70. package/dist/dsp/filters.js.map +1 -0
  71. package/dist/dsp/math.d.ts +10 -0
  72. package/dist/dsp/math.d.ts.map +1 -0
  73. package/dist/dsp/math.js +55 -0
  74. package/dist/dsp/math.js.map +1 -0
  75. package/dist/dsp/power.d.ts +2 -0
  76. package/dist/dsp/power.d.ts.map +1 -0
  77. package/dist/dsp/power.js +23 -0
  78. package/dist/dsp/power.js.map +1 -0
  79. package/dist/dsp/resamplers.d.ts +45 -0
  80. package/dist/dsp/resamplers.d.ts.map +1 -0
  81. package/dist/dsp/resamplers.js +85 -0
  82. package/dist/dsp/resamplers.js.map +1 -0
  83. package/dist/errors.d.ts +15 -0
  84. package/dist/errors.d.ts.map +1 -0
  85. package/dist/errors.js +33 -0
  86. package/dist/errors.js.map +1 -0
  87. package/dist/players/audioplayer.d.ts +25 -0
  88. package/dist/players/audioplayer.d.ts.map +1 -0
  89. package/dist/players/audioplayer.js +68 -0
  90. package/dist/players/audioplayer.js.map +1 -0
  91. package/dist/radio/msgqueue.d.ts +32 -0
  92. package/dist/radio/msgqueue.d.ts.map +1 -0
  93. package/dist/radio/msgqueue.js +62 -0
  94. package/dist/radio/msgqueue.js.map +1 -0
  95. package/dist/radio/radio.d.ts +107 -0
  96. package/dist/radio/radio.d.ts.map +1 -0
  97. package/dist/radio/radio.js +279 -0
  98. package/dist/radio/radio.js.map +1 -0
  99. package/dist/radio/sample_receiver.d.ts +17 -0
  100. package/dist/radio/sample_receiver.d.ts.map +1 -0
  101. package/dist/radio/sample_receiver.js +52 -0
  102. package/dist/radio/sample_receiver.js.map +1 -0
  103. package/dist/radio/signal_source.d.ts +53 -0
  104. package/dist/radio/signal_source.d.ts.map +1 -0
  105. package/dist/radio/signal_source.js +15 -0
  106. package/dist/radio/signal_source.js.map +1 -0
  107. package/dist/radio.d.ts +4 -0
  108. package/dist/radio.d.ts.map +1 -0
  109. package/dist/radio.js +4 -0
  110. package/dist/radio.js.map +1 -0
  111. package/dist/sources/generators.d.ts +41 -0
  112. package/dist/sources/generators.d.ts.map +1 -0
  113. package/dist/sources/generators.js +238 -0
  114. package/dist/sources/generators.js.map +1 -0
  115. package/dist/sources/provider.d.ts +7 -0
  116. package/dist/sources/provider.d.ts.map +1 -0
  117. package/dist/sources/provider.js +23 -0
  118. package/dist/sources/provider.js.map +1 -0
  119. package/dist/sources/push.d.ts +30 -0
  120. package/dist/sources/push.d.ts.map +1 -0
  121. package/dist/sources/push.js +106 -0
  122. package/dist/sources/push.js.map +1 -0
  123. package/dist/sources/read_ring.d.ts +14 -0
  124. package/dist/sources/read_ring.d.ts.map +1 -0
  125. package/dist/sources/read_ring.js +59 -0
  126. package/dist/sources/read_ring.js.map +1 -0
  127. package/dist/sources/realtime.d.ts +44 -0
  128. package/dist/sources/realtime.d.ts.map +1 -0
  129. package/dist/sources/realtime.js +136 -0
  130. package/dist/sources/realtime.js.map +1 -0
  131. package/package.json +25 -0
@@ -0,0 +1,238 @@
1
+ // Copyright 2025 Jacobo Tarrio Barreiro. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { IqPool } from "../dsp/buffers.js";
15
+ import { Preemphasis } from "../dsp/filters.js";
16
+ /** Returns a generator for a tone at the given frequency with the given amplitude. */
17
+ export function tone(freq, amplitude, phase) {
18
+ if (phase === undefined)
19
+ phase = 0;
20
+ return (sample, rate, centerFreq, I, Q) => {
21
+ const delta = (freq - centerFreq) / rate;
22
+ if (delta >= 0.5 || -0.5 >= delta) {
23
+ I.fill(0);
24
+ Q.fill(0);
25
+ return;
26
+ }
27
+ const p = 2 * Math.PI * delta * (sample % rate) + phase;
28
+ let a = Math.cos(p);
29
+ let b = Math.sin(p);
30
+ const f = 2 * Math.PI * delta;
31
+ const c = Math.cos(f);
32
+ const d = Math.sin(f);
33
+ for (let i = 0; i < I.length; ++i) {
34
+ I[i] = a * amplitude;
35
+ Q[i] = b * amplitude;
36
+ const xa = a * c - b * d;
37
+ const xb = b * c + a * d;
38
+ a = xa;
39
+ b = xb;
40
+ }
41
+ };
42
+ }
43
+ /** Returns a generator for noise with a given maximum amplitude. */
44
+ export function noise(amplitude, random) {
45
+ if (random === undefined)
46
+ random = Math.random;
47
+ return (_sample, _rate, _centerFreq, I, Q) => {
48
+ for (let i = 0; i < I.length; ++i) {
49
+ let r = amplitude * Math.sqrt(random());
50
+ let t = random() * 2 * Math.PI;
51
+ I[i] = r * Math.cos(t);
52
+ Q[i] = r * Math.sin(t);
53
+ }
54
+ };
55
+ }
56
+ /** Returns a generator that adds the outputs of all the provided generators together. */
57
+ export function sum(...generators) {
58
+ let pool = new IqPool(1, 65536);
59
+ return (sample, rate, centerFreq, I, Q) => {
60
+ I.fill(0);
61
+ Q.fill(0);
62
+ let [J, R] = pool.get(I.length);
63
+ for (let g of generators) {
64
+ g(sample, rate, centerFreq, J, R);
65
+ for (let i = 0; i < I.length; ++i) {
66
+ I[i] += J[i];
67
+ Q[i] += R[i];
68
+ }
69
+ }
70
+ };
71
+ }
72
+ /**
73
+ * Returns a generator that multiplies the output of the carrier generator
74
+ * with the output of the signal generator.
75
+ * The signal generator always receives a center frequency of 0 Hz.
76
+ */
77
+ export function product(carrier, signal) {
78
+ let pool = new IqPool(1, 65536);
79
+ return (sample, rate, centerFreq, I, Q) => {
80
+ let [J, R] = pool.get(I.length);
81
+ carrier(sample, rate, centerFreq, I, Q);
82
+ signal(sample, rate, 0, J, R);
83
+ for (let i = 0; i < I.length; ++i) {
84
+ const a = I[i];
85
+ const b = Q[i];
86
+ const c = J[i];
87
+ const d = R[i];
88
+ I[i] = a * c - b * d;
89
+ Q[i] = a * d + b * c;
90
+ }
91
+ };
92
+ }
93
+ /**
94
+ * Returns a generator that multiplies every sample by the given gain.
95
+ */
96
+ export function amplify(gain, signal) {
97
+ return (sample, rate, centerFreq, I, Q) => {
98
+ signal(sample, rate, centerFreq, I, Q);
99
+ for (let i = 0; i < I.length; ++i) {
100
+ I[i] *= gain;
101
+ Q[i] *= gain;
102
+ }
103
+ };
104
+ }
105
+ /** Returns the real part of another generator's output. */
106
+ export function real(signal) {
107
+ return (sample, rate, centerFreq, I, Q) => {
108
+ signal(sample, rate, centerFreq, I, Q);
109
+ Q.fill(0);
110
+ };
111
+ }
112
+ /**
113
+ * Returns a generator that amplitude-modulates the output
114
+ * of the signal generator using a modulation factor of 2.
115
+ * Only the I component of the signal is used as the input.
116
+ * The signal generator always receives a center frequency of 0 Hz.
117
+ */
118
+ export function modulateAM(carrierFreq, amplitude, signal) {
119
+ let pool = new IqPool(1, 65536);
120
+ const carrier = tone(carrierFreq, amplitude);
121
+ return (sample, rate, centerFreq, I, Q) => {
122
+ const delta = (carrierFreq - centerFreq) / rate;
123
+ if (delta >= 0.5 || -0.5 >= delta) {
124
+ I.fill(0);
125
+ Q.fill(0);
126
+ return;
127
+ }
128
+ let [J, R] = pool.get(I.length);
129
+ carrier(sample, rate, centerFreq, I, Q);
130
+ signal(sample, rate, 0, J, R);
131
+ for (let i = 0; i < I.length; ++i) {
132
+ const c = (1 + J[i]) / 2;
133
+ I[i] *= c;
134
+ Q[i] *= c;
135
+ }
136
+ };
137
+ }
138
+ /**
139
+ * Returns a generator that frequency-modulates the output
140
+ * of the signal generator using the given maximum frequency deviation.
141
+ * Only the I component of the signal is used as the input.
142
+ * The signal generator always receives a center frequency of 0 Hz.
143
+ */
144
+ export function modulateFM(carrierFreq, maximumDeviation, amplitude, signal) {
145
+ let pool = new IqPool(1, 65536);
146
+ let phase = 0;
147
+ return (sample, rate, centerFreq, I, Q) => {
148
+ const delta = (carrierFreq - centerFreq) / rate;
149
+ if (delta >= 0.5 || -0.5 >= delta) {
150
+ I.fill(0);
151
+ Q.fill(0);
152
+ return;
153
+ }
154
+ const maxF = maximumDeviation / rate;
155
+ let [J, R] = pool.get(I.length);
156
+ signal(sample, rate, 0, J, R);
157
+ let sigSum = 0;
158
+ let p = phase;
159
+ for (let i = 0; i < I.length; ++i) {
160
+ const angle = 2 * Math.PI * p;
161
+ I[i] = amplitude * Math.cos(angle);
162
+ Q[i] = amplitude * Math.sin(angle);
163
+ p += delta + maxF * J[i];
164
+ sigSum += J[i];
165
+ }
166
+ phase += delta * I.length + maxF * sigSum;
167
+ phase -= Math.floor(phase);
168
+ };
169
+ }
170
+ /**
171
+ * Returns a generator that applies pre-emphasis to the output of another signal generator.
172
+ * This pre-emphasis is just the opposite to the de-emphasis produced by an IIR single-pole
173
+ * low-pass filter with the given time constant.
174
+ */
175
+ function preemphasis(tcMicros, signal) {
176
+ let prevRate;
177
+ let filterI;
178
+ let filterQ;
179
+ return (sample, rate, centerFreq, I, Q) => {
180
+ if (prevRate !== rate) {
181
+ prevRate = rate;
182
+ filterI = new Preemphasis(rate, tcMicros / 1e6);
183
+ filterQ = filterI.clone();
184
+ }
185
+ signal(sample, rate, centerFreq, I, Q);
186
+ filterI.inPlace(I);
187
+ filterQ.inPlace(Q);
188
+ };
189
+ }
190
+ /**
191
+ * Returns a generator that avoids recomputing the signal
192
+ * if called twice with the same parameters.
193
+ */
194
+ function cache(signal) {
195
+ let lastSample;
196
+ let lastRate;
197
+ let lastCenterFreq;
198
+ let pool = new IqPool(1, 1024);
199
+ let cache = [
200
+ new Float32Array(0),
201
+ new Float32Array(0),
202
+ ];
203
+ return (sample, rate, centerFreq, I, Q) => {
204
+ if (lastSample !== sample ||
205
+ lastRate !== rate ||
206
+ lastCenterFreq !== centerFreq ||
207
+ cache[0].length !== I.length) {
208
+ cache = pool.get(I.length);
209
+ signal(sample, rate, centerFreq, cache[0], cache[1]);
210
+ lastSample = sample;
211
+ lastRate = rate;
212
+ lastCenterFreq = centerFreq;
213
+ }
214
+ I.set(cache[0]);
215
+ Q.set(cache[1]);
216
+ };
217
+ }
218
+ export function wbfmSignal(left, rightOrTcMicros, tcMicros) {
219
+ let right;
220
+ if (typeof rightOrTcMicros === "number") {
221
+ tcMicros = rightOrTcMicros;
222
+ }
223
+ else {
224
+ right = rightOrTcMicros;
225
+ }
226
+ if (tcMicros === undefined)
227
+ tcMicros = 50;
228
+ if (right === undefined)
229
+ return amplify(0.9, preemphasis(tcMicros, real(left)));
230
+ const pilot = real(tone(19000, 0.1, -Math.PI / 2));
231
+ const shift = real(tone(38000, 1, -Math.PI / 2));
232
+ const l = cache(preemphasis(tcMicros, real(left)));
233
+ const r = cache(preemphasis(tcMicros, real(right)));
234
+ const apb = amplify(0.45, sum(l, r));
235
+ const amb = amplify(0.45, sum(l, amplify(-1, r)));
236
+ return sum(apb, pilot, product(amb, shift));
237
+ }
238
+ //# sourceMappingURL=generators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generators.js","sourceRoot":"","sources":["../../src/sources/generators.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,sFAAsF;AACtF,MAAM,UAAU,IAAI,CAClB,IAAY,EACZ,SAAiB,EACjB,KAAc;IAEd,IAAI,KAAK,KAAK,SAAS;QAAE,KAAK,GAAG,CAAC,CAAC;IACnC,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;QACzC,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC;YAClC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACV,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;QACxD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC;QAC9B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;YACrB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;YACrB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC,GAAG,EAAE,CAAC;YACP,CAAC,GAAG,EAAE,CAAC;QACT,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,KAAK,CACnB,SAAiB,EACjB,MAAqB;IAErB,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC/C,OAAO,CACL,OAAe,EACf,KAAa,EACb,WAAmB,EACnB,CAAe,EACf,CAAe,EACf,EAAE;QACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;YAC/B,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,GAAG,CAAC,GAAG,UAA6B;IAClD,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAChC,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACV,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACV,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,KAAK,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;YACzB,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;gBAClC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBACb,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CACrB,OAAwB,EACxB,MAAuB;IAEvB,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAChC,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CACrB,IAAY,EACZ,MAAuB;IAEvB,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YACb,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACf,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,IAAI,CAAC,MAAuB;IAC1C,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,WAAmB,EACnB,SAAiB,EACjB,MAAuB;IAEvB,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC7C,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,MAAM,KAAK,GAAG,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;QAChD,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC;YAClC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACV,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACV,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACV,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,WAAmB,EACnB,gBAAwB,EACxB,SAAiB,EACjB,MAAuB;IAEvB,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,MAAM,KAAK,GAAG,CAAC,WAAW,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;QAChD,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC;YAClC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACV,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,gBAAgB,GAAG,IAAI,CAAC;QAErC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9B,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,GAAG,KAAK,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YAC9B,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;QAC1C,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAClB,QAAgB,EAChB,MAAuB;IAEvB,IAAI,QAA4B,CAAC;IACjC,IAAI,OAAgC,CAAC;IACrC,IAAI,OAAgC,CAAC;IACrC,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,CAAC,CAAC;YAChD,OAAO,GAAG,OAAO,CAAC,KAAK,EAAiB,CAAC;QAC3C,CAAC;QACD,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvC,OAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACpB,OAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,KAAK,CAAC,MAAuB;IACpC,IAAI,UAA8B,CAAC;IACnC,IAAI,QAA4B,CAAC;IACjC,IAAI,cAAkC,CAAC;IACvC,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,GAAiC;QACxC,IAAI,YAAY,CAAC,CAAC,CAAC;QACnB,IAAI,YAAY,CAAC,CAAC,CAAC;KACpB,CAAC;IACF,OAAO,CACL,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,CAAe,EACf,CAAe,EACf,EAAE;QACF,IACE,UAAU,KAAK,MAAM;YACrB,QAAQ,KAAK,IAAI;YACjB,cAAc,KAAK,UAAU;YAC7B,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAC5B,CAAC;YACD,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC3B,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,UAAU,GAAG,MAAM,CAAC;YACpB,QAAQ,GAAG,IAAI,CAAC;YAChB,cAAc,GAAG,UAAU,CAAC;QAC9B,CAAC;QACD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC;AAgBD,MAAM,UAAU,UAAU,CACxB,IAAqB,EACrB,eAA0C,EAC1C,QAAiB;IAEjB,IAAI,KAAkC,CAAC;IACvC,IAAI,OAAO,eAAe,KAAK,QAAQ,EAAE,CAAC;QACxC,QAAQ,GAAG,eAAe,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,eAAe,CAAC;IAC1B,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS;QAAE,QAAQ,GAAG,EAAE,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS;QACrB,OAAO,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEzD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { SignalSource, SignalSourceProvider } from "../radio/signal_source.js";
2
+ export declare class SimpleProvider implements SignalSourceProvider {
3
+ private instance;
4
+ constructor(instance: SignalSource);
5
+ get(): Promise<SignalSource>;
6
+ }
7
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/sources/provider.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAE/E,qBAAa,cAAe,YAAW,oBAAoB;IAC7C,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAEpC,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;CAGnC"}
@@ -0,0 +1,23 @@
1
+ // Copyright 2025 Jacobo Tarrio Barreiro. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ export class SimpleProvider {
15
+ instance;
16
+ constructor(instance) {
17
+ this.instance = instance;
18
+ }
19
+ async get() {
20
+ return this.instance;
21
+ }
22
+ }
23
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/sources/provider.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAIjC,MAAM,OAAO,cAAc;IACL;IAApB,YAAoB,QAAsB;QAAtB,aAAQ,GAAR,QAAQ,CAAc;IAAG,CAAC;IAE9C,KAAK,CAAC,GAAG;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ import { SampleBlock, SignalSource } from "../radio/signal_source.js";
2
+ /**
3
+ * A SignalSource that gets samples from a "push" source.
4
+ *
5
+ * You use PushSource when your signal comes in the form of events
6
+ * or callbacks that arrive regularly (push events).
7
+ *
8
+ * Whenever you receive the push event or callback, you must call
9
+ * pushSamples(). This function will use the provided samples to resolve
10
+ * pending reads, and then store the remainder in a buffer.
11
+ *
12
+ * The push source is expected to deliver its signals in real time.
13
+ */
14
+ export declare class PushSource implements SignalSource {
15
+ constructor();
16
+ private sampleRate;
17
+ private centerFrequency;
18
+ private I;
19
+ private Q;
20
+ private outPool;
21
+ private pendingReads;
22
+ setParameter<V>(_property: string, _value: V): Promise<void | V>;
23
+ setSampleRate(sampleRate: number): Promise<number>;
24
+ setCenterFrequency(freq: number): Promise<number>;
25
+ startReceiving(): Promise<void>;
26
+ pushSamples(I: Float32Array, Q: Float32Array, frequency?: number): void;
27
+ readSamples(length: number): Promise<SampleBlock>;
28
+ close(): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=push.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/sources/push.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGtE;;;;;;;;;;;GAWG;AACH,qBAAa,UAAW,YAAW,YAAY;;IAU7C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,CAAC,CAAoB;IAC7B,OAAO,CAAC,CAAC,CAAoB;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAkB;IAEhC,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;IAEhE,aAAa,CAAC,UAAU,EAAE,MAAM;IAOhC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjD,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrC,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,MAAM;IAiChE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAe3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,106 @@
1
+ // Copyright 2025 Jacobo Tarrio Barreiro. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { Float32RingBuffer, IqPool } from "../dsp/buffers.js";
15
+ import { PendingReadRing } from "./read_ring.js";
16
+ /**
17
+ * A SignalSource that gets samples from a "push" source.
18
+ *
19
+ * You use PushSource when your signal comes in the form of events
20
+ * or callbacks that arrive regularly (push events).
21
+ *
22
+ * Whenever you receive the push event or callback, you must call
23
+ * pushSamples(). This function will use the provided samples to resolve
24
+ * pending reads, and then store the remainder in a buffer.
25
+ *
26
+ * The push source is expected to deliver its signals in real time.
27
+ */
28
+ export class PushSource {
29
+ constructor() {
30
+ this.sampleRate = 1024000;
31
+ this.centerFrequency = 0;
32
+ this.I = new Float32RingBuffer(Math.max(65536, this.sampleRate / 10));
33
+ this.Q = new Float32RingBuffer(this.I.capacity);
34
+ this.outPool = new IqPool(16, 65536);
35
+ this.pendingReads = new PendingReadRing(8);
36
+ }
37
+ sampleRate;
38
+ centerFrequency;
39
+ I;
40
+ Q;
41
+ outPool;
42
+ pendingReads;
43
+ async setParameter(_property, _value) { }
44
+ async setSampleRate(sampleRate) {
45
+ this.sampleRate = sampleRate;
46
+ this.I = new Float32RingBuffer(Math.max(65536, this.sampleRate / 10));
47
+ this.Q = new Float32RingBuffer(this.I.capacity);
48
+ return this.sampleRate;
49
+ }
50
+ async setCenterFrequency(freq) {
51
+ this.centerFrequency = freq;
52
+ return this.centerFrequency;
53
+ }
54
+ async startReceiving() {
55
+ this.I.clear();
56
+ this.Q.clear();
57
+ }
58
+ pushSamples(I, Q, frequency) {
59
+ if (frequency !== undefined)
60
+ this.centerFrequency = frequency;
61
+ let pos = 0;
62
+ while (this.pendingReads.hasPendingRead() && pos < I.length) {
63
+ const remaining = I.length - pos;
64
+ const readSize = this.pendingReads.nextReadSize();
65
+ if (readSize > this.I.available + remaining)
66
+ break;
67
+ let [oI, oQ] = this.outPool.get(readSize);
68
+ let copied = this.I.moveTo(oI);
69
+ if (copied > 0)
70
+ this.Q.moveTo(oQ);
71
+ if (copied < oI.length) {
72
+ const end = pos + oI.length - copied;
73
+ oI.set(I.subarray(pos, end), copied);
74
+ oQ.set(Q.subarray(pos, end), copied);
75
+ pos = end;
76
+ }
77
+ this.pendingReads.resolve({
78
+ I: oI,
79
+ Q: oQ,
80
+ frequency: this.centerFrequency,
81
+ });
82
+ }
83
+ if (pos < I.length) {
84
+ this.I.store(I.subarray(pos));
85
+ this.Q.store(Q.subarray(pos));
86
+ return;
87
+ }
88
+ }
89
+ readSamples(length) {
90
+ if (this.I.available < length || this.pendingReads.hasPendingRead()) {
91
+ return this.pendingReads.add(length);
92
+ }
93
+ let [oI, oQ] = this.outPool.get(length);
94
+ this.I.moveTo(oI);
95
+ this.Q.moveTo(oQ);
96
+ return Promise.resolve({
97
+ I: oI,
98
+ Q: oQ,
99
+ frequency: this.centerFrequency,
100
+ });
101
+ }
102
+ async close() {
103
+ this.pendingReads.cancel();
104
+ }
105
+ }
106
+ //# sourceMappingURL=push.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/sources/push.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { SampleBlock } from "../radio/signal_source.js";
2
+ export declare class PendingReadRing {
3
+ constructor(length: number);
4
+ private pending;
5
+ private writePtr;
6
+ private readPtr;
7
+ private size;
8
+ add(length: number): Promise<SampleBlock>;
9
+ resolve(block: SampleBlock): void;
10
+ cancel(): void;
11
+ hasPendingRead(): boolean;
12
+ nextReadSize(): number;
13
+ }
14
+ //# sourceMappingURL=read_ring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read_ring.d.ts","sourceRoot":"","sources":["../../src/sources/read_ring.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAMxD,qBAAa,eAAe;gBACd,MAAM,EAAE,MAAM;IAO1B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,IAAI,CAAS;IAErB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAczC,OAAO,CAAC,KAAK,EAAE,WAAW;IAO1B,MAAM;IAaN,cAAc,IAAI,OAAO;IAIzB,YAAY,IAAI,MAAM;CAIvB"}
@@ -0,0 +1,59 @@
1
+ // Copyright 2025 Jacobo Tarrio Barreiro. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { RadioError, RadioErrorType } from "../errors.js";
15
+ export class PendingReadRing {
16
+ constructor(length) {
17
+ this.pending = new Array(length);
18
+ this.writePtr = 0;
19
+ this.readPtr = 0;
20
+ this.size = 0;
21
+ }
22
+ pending;
23
+ writePtr;
24
+ readPtr;
25
+ size;
26
+ add(length) {
27
+ if (this.size == this.pending.length) {
28
+ throw new RadioError("Too many simultaneous reads", RadioErrorType.TransferError);
29
+ }
30
+ const { promise, resolve, reject } = Promise.withResolvers();
31
+ this.pending[this.writePtr] = { length, resolve, reject };
32
+ this.writePtr = (this.writePtr + 1) % this.pending.length;
33
+ this.size++;
34
+ return promise;
35
+ }
36
+ resolve(block) {
37
+ if (this.size == 0)
38
+ return;
39
+ this.pending[this.readPtr].resolve(block);
40
+ this.readPtr = (this.readPtr + 1) % this.pending.length;
41
+ this.size--;
42
+ }
43
+ cancel() {
44
+ while (this.size > 0) {
45
+ this.pending[this.readPtr].reject(new RadioError("Transfer has been canceled", RadioErrorType.TransferError));
46
+ this.readPtr = (this.readPtr + 1) % this.pending.length;
47
+ this.size--;
48
+ }
49
+ }
50
+ hasPendingRead() {
51
+ return this.size > 0;
52
+ }
53
+ nextReadSize() {
54
+ if (this.size == 0)
55
+ return 0;
56
+ return this.pending[this.readPtr].length;
57
+ }
58
+ }
59
+ //# sourceMappingURL=read_ring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read_ring.js","sourceRoot":"","sources":["../../src/sources/read_ring.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAO1D,MAAM,OAAO,eAAe;IAC1B,YAAY,MAAc;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IAChB,CAAC;IAEO,OAAO,CAAgB;IACvB,QAAQ,CAAS;IACjB,OAAO,CAAS;IAChB,IAAI,CAAS;IAErB,GAAG,CAAC,MAAc;QAChB,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,UAAU,CAClB,6BAA6B,EAC7B,cAAc,CAAC,aAAa,CAC7B,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAe,CAAC;QAC1E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAC1D,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,KAAkB;QACxB,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;YAAE,OAAO;QAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACxD,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAC/B,IAAI,UAAU,CACZ,4BAA4B,EAC5B,cAAc,CAAC,aAAa,CAC7B,CACF,CAAC;YACF,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACxD,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;IACvB,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC3C,CAAC;CACF"}
@@ -0,0 +1,44 @@
1
+ import { SampleBlock, SignalSource } from "../radio/signal_source.js";
2
+ /**
3
+ * A function that generates samples.
4
+ * @param startSample The first sample's number.
5
+ * @param sampleRate The sample rate.
6
+ * @param centerFrequency The signal's center frequency.
7
+ * @param I An array to be populated with the I component values.
8
+ * @param Q An array to be populated with the Q component values.
9
+ */
10
+ export type SampleGenerator = (startSample: number, sampleRate: number, centerFrequency: number, I: Float32Array, Q: Float32Array) => void;
11
+ /**
12
+ * A SignalSource that gets samples from a SampleGenerator function in real time.
13
+ *
14
+ * This source holds a small buffer that it feeds by calling the generator
15
+ * function. Then, at periodic intervals, it checks if there are any pending
16
+ * reads and resolves them with the contents of the buffer.
17
+ */
18
+ export declare class RealTimeSource implements SignalSource {
19
+ private generator;
20
+ constructor(generator: SampleGenerator);
21
+ private sampleRate;
22
+ private centerFrequency;
23
+ private I;
24
+ private Q;
25
+ private lastSampleInBuffer;
26
+ private inPool;
27
+ private outPool;
28
+ private pendingReads;
29
+ private running;
30
+ private firstTs;
31
+ setParameter<V>(_property: string, _value: V): Promise<void | V>;
32
+ setSampleRate(sampleRate: number): Promise<number>;
33
+ setCenterFrequency(freq: number): Promise<number>;
34
+ startReceiving(): Promise<void>;
35
+ readSamples(length: number): Promise<SampleBlock>;
36
+ close(): Promise<void>;
37
+ /** Schedules the next frame. */
38
+ private schedule;
39
+ /** Fills the buffer and resolves promises for samples that become available in this frame. */
40
+ private frame;
41
+ /** Fills the buffer with samples to satisfy future reads. */
42
+ private fillBuffer;
43
+ }
44
+ //# sourceMappingURL=realtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/sources/realtime.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGtE;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,CAAC,EAAE,YAAY,EACf,CAAC,EAAE,YAAY,KACZ,IAAI,CAAC;AAEV;;;;;;GAMG;AACH,qBAAa,cAAe,YAAW,YAAY;IACrC,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,eAAe;IAa9C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,CAAC,CAAoB;IAC7B,OAAO,CAAC,CAAC,CAAoB;IAC7B,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAgB;IAEzB,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;IAEhE,aAAa,CAAC,UAAU,EAAE,MAAM;IAOhC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjD,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAI3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,gCAAgC;IAChC,OAAO,CAAC,QAAQ;IAIhB,8FAA8F;IAC9F,OAAO,CAAC,KAAK;IAuCb,6DAA6D;IAC7D,OAAO,CAAC,UAAU;CAyBnB"}