@@ -109,10 +109,20 @@ struct SignalFIRCompiler : public SignalVisitor {
109
109
110
110
DelayedSig () = default ;
111
111
112
- DelayedSig (const std::string& name, int size, Address::AccessType access = Address::kStruct )
112
+ DelayedSig (const std::string& name, int size, Address::AccessType access = Address::kStruct ,
113
+ BlockInst* declare_block = nullptr , BlockInst* rest_block = nullptr )
113
114
: fName (name), fSize (size), fAccess (access)
114
115
{
115
116
faustassert ((size & (size - 1 )) == 0 && " delay‑line size must be a power of two" );
117
+
118
+ // Declare and initialize the delay line a an arry DSP struct
119
+ /*
120
+ declare_block->pushBackInst(
121
+ IB::genDecStructVar(fName,
122
+ IB::genBasicTyped(Typed::kFloatMacro))); reset_block->pushBackInst(
123
+ IB::genStoreStructVar(fName,
124
+ IB::genRealNumInst(Typed::kFloatMacro, init)));
125
+ */
116
126
}
117
127
118
128
void resize (int size) { fSize = std::max (fSize , size); }
@@ -160,7 +170,7 @@ struct SignalFIRCompiler : public SignalVisitor {
160
170
/* *
161
171
* @brief Represents a static table for FIR-like load/store operations.
162
172
*
163
- * The `TableData` structure models a named array in the DSP environment , where
173
+ * The `TableData` structure models a named array in the DSP struct , where
164
174
* each element can be read from or written to using generated FIR
165
175
* instructions. It is primarily used to implement lookup tables, buffers, or other
166
176
* fixed-size memory structures in the DSP context.
@@ -171,7 +181,7 @@ struct SignalFIRCompiler : public SignalVisitor {
171
181
* - Can be used for constant folding or static initialization.
172
182
*/
173
183
struct TableData {
174
- std::string fName ; // /< Variable name for the table array in the DSP environment .
184
+ std::string fName ; // /< Variable name for the table array in the DSP struct .
175
185
int fSize = 0 ; // /< Number of elements in the table (must be > 0).
176
186
Tree fSigGen = nullptr ; // /< Optional signal generator used for static initialization.
177
187
Address::AccessType fAccess = Address::kStruct ; // /< Memory access mode for the table.
@@ -255,13 +265,13 @@ struct SignalFIRCompiler : public SignalVisitor {
255
265
*
256
266
* The `inputControl` structure defines the configuration and runtime integration of
257
267
* user interface controls that allow users to interact with signal parameters.
258
- * These controls are typically generated in DSP environments (e.g., sliders, buttons,
268
+ * These controls are typically generated in DSP struct (e.g., sliders, buttons,
259
269
* and numerical entries) and are automatically linked to the internal DSP state.
260
270
*
261
271
* ## Key Features
262
272
* - Supports different control types (buttons, sliders, and numerical entries).
263
273
* - Maintains control metadata such as label, initial value, range, and step size.
264
- * - Automatically declares and initializes the control in the DSP environment .
274
+ * - Automatically declares and initializes the control in the DSP struct .
265
275
*/
266
276
struct inputControl {
267
277
/* *
@@ -281,7 +291,7 @@ struct SignalFIRCompiler : public SignalVisitor {
281
291
282
292
type fType ; // /< The type of control.
283
293
std::string fLabel ; // /< Display label shown to the user.
284
- std::string fName ; // /< Unique identifier for this control in the DSP environment .
294
+ std::string fName ; // /< Unique identifier for this control in the DSP struct .
285
295
double fInit ; // /< Initial value of the control.
286
296
double fMin ; // /< Minimum allowed value.
287
297
double fMax ; // /< Maximum allowed value.
@@ -295,7 +305,7 @@ struct SignalFIRCompiler : public SignalVisitor {
295
305
/* *
296
306
* @brief Constructs a new user interface control and integrates it into the DSP.
297
307
*
298
- * This constructor declares the control variable in the DSP environment and
308
+ * This constructor declares the control variable in the DSP struct and
299
309
* initializes it with the given value.
300
310
*
301
311
* @param sig The signal tree associated with this control (for DSP binding).
@@ -308,17 +318,17 @@ struct SignalFIRCompiler : public SignalVisitor {
308
318
* @param max The maximum value allowed.
309
319
* @param step The increment step for adjusting the control.
310
320
*/
311
- inputControl (Tree sig, BlockInst* declare_block, BlockInst* reset_block, type type ,
312
- const std::string& label, double init, double min, double max, double step)
321
+ inputControl (Tree sig, SignalFIRCompiler& compiler, type type, const std::string& label ,
322
+ double init, double min, double max, double step)
313
323
: fType (type), fLabel (label), fInit (init), fMin (min), fMax (max), fStep (step)
314
324
{
315
325
// Generate a unique variable name for this control based on its type
316
326
fName = gGlobal ->getFreshID (gTypeName [type]);
317
327
318
- // Declare and initialize the control variable in the DSP environment
319
- declare_block ->pushBackInst (
328
+ // Declare and initialize the control variable in the DSP struct
329
+ compiler. fDeclareBlock ->pushBackInst (
320
330
IB::genDecStructVar (fName , IB::genBasicTyped (Typed::kFloatMacro )));
321
- reset_block ->pushBackInst (
331
+ compiler. fResetBlock ->pushBackInst (
322
332
IB::genStoreStructVar (fName , IB::genRealNumInst (Typed::kFloatMacro , init)));
323
333
}
324
334
@@ -334,13 +344,13 @@ struct SignalFIRCompiler : public SignalVisitor {
334
344
* @brief Represents a user interface output control (bargraph).
335
345
*
336
346
* The `outputControl` structure defines the configuration and integration of output controls
337
- * used to visualize signal values in the DSP environment . These controls do not accept user
347
+ * used to visualize signal values in the DSP struct . These controls do not accept user
338
348
* input; instead, they display real-time data such as signal levels or metering information.
339
349
*
340
350
* ## Key Features
341
351
* - Supports horizontal and vertical bargraph types.
342
352
* - Maintains control metadata such as label and value range.
343
- * - Automatically declares the control in the DSP environment .
353
+ * - Automatically declares the control in the DSP struct .
344
354
*/
345
355
struct outputControl {
346
356
/* *
@@ -356,7 +366,7 @@ struct SignalFIRCompiler : public SignalVisitor {
356
366
357
367
type fType ; // /< The type of output control.
358
368
std::string fLabel ; // /< Display label shown to the user.
359
- std::string fName ; // /< Unique identifier for this control in the DSP environment .
369
+ std::string fName ; // /< Unique identifier for this control in the DSP struct .
360
370
double fMin ; // /< Minimum value displayed by the bargraph (e.g. -60 dB).
361
371
double fMax ; // /< Maximum value displayed by the bargraph (e.g. 0 dB).
362
372
@@ -368,7 +378,7 @@ struct SignalFIRCompiler : public SignalVisitor {
368
378
/* *
369
379
* @brief Constructs a new output control and integrates it into the DSP.
370
380
*
371
- * This constructor declares the control variable in the DSP environment .
381
+ * This constructor declares the control variable in the DSP struct .
372
382
*
373
383
* @param sig The signal tree associated with this control (for DSP binding).
374
384
* @param declare_block The block in which the control variable is declared.
@@ -377,15 +387,15 @@ struct SignalFIRCompiler : public SignalVisitor {
377
387
* @param min The minimum value displayed by the bargraph.
378
388
* @param max The maximum value displayed by the bargraph.
379
389
*/
380
- outputControl (Tree sig, BlockInst* declare_block , type type, const std::string& label,
390
+ outputControl (Tree sig, SignalFIRCompiler& compiler , type type, const std::string& label,
381
391
double min, double max)
382
392
: fType (type), fLabel (label), fMin (min), fMax (max)
383
393
{
384
394
// Generate a unique variable name for this control based on its type
385
395
fName = gGlobal ->getFreshID (gTypeName [type]);
386
396
387
- // Declare the control variable in the DSP environment
388
- declare_block ->pushBackInst (
397
+ // Declare the control variable in the DSP struct
398
+ compiler. fDeclareBlock ->pushBackInst (
389
399
IB::genDecStructVar (fName , IB::genBasicTyped (Typed::kFloatMacro )));
390
400
}
391
401
@@ -412,12 +422,7 @@ struct SignalFIRCompiler : public SignalVisitor {
412
422
* - Registers input and output controls such as sliders and bargraphs.
413
423
*/
414
424
struct SignalBuilder : public SignalVisitor {
415
- std::map<Tree, DelayedSig>& fDelays ;
416
- std::map<Tree, TableData>& fTables ;
417
- std::map<Tree, inputControl>& fInputControls ;
418
- std::map<Tree, outputControl>& fOutputControls ;
419
- BlockInst* fDeclareBlock ;
420
- BlockInst* fResetBlock ;
425
+ SignalFIRCompiler& fCompiler ;
421
426
422
427
/* *
423
428
* @brief Allocates or resizes a delay line for a given signal. All delay lines have a
@@ -461,24 +466,26 @@ struct SignalFIRCompiler : public SignalVisitor {
461
466
int nature = getCertifiedSigType (x)->nature (); // Nature of the signal being delayed
462
467
int N = pow2limit (delay + 1 ); // Max delay rounded up to power of 2
463
468
464
- if (fDelays .count (x) == 0 ) {
469
+ if (fCompiler . fDelays .count (x) == 0 ) {
465
470
/*
466
471
if (global::isDebug("SIG_COMPILER")) {
467
472
std::cout << "allocateDelayLine NEW " << ppsig(x, 8) << std::endl;
468
473
}
469
474
*/
470
475
if (nature == kInt ) {
471
- fDelays [x] = DelayedSig (gGlobal ->getFreshID ((rec) ? " iRec" : " iVec" ), N);
476
+ fCompiler .fDelays [x] =
477
+ DelayedSig (gGlobal ->getFreshID ((rec) ? " iRec" : " iVec" ), N);
472
478
} else {
473
- fDelays [x] = DelayedSig (gGlobal ->getFreshID ((rec) ? " fRec" : " fVec" ), N);
479
+ fCompiler .fDelays [x] =
480
+ DelayedSig (gGlobal ->getFreshID ((rec) ? " fRec" : " fVec" ), N);
474
481
}
475
482
} else {
476
483
/*
477
484
if (global::isDebug("SIG_COMPILER")) {
478
485
std::cout << "allocateDelayLine RESIZE INT " << ppsig(x, 8) << std::endl;
479
486
}
480
487
*/
481
- fDelays [x].resize (N);
488
+ fCompiler . fDelays [x].resize (N);
482
489
}
483
490
}
484
491
@@ -499,27 +506,9 @@ struct SignalFIRCompiler : public SignalVisitor {
499
506
*
500
507
* ## Constructor
501
508
*
502
- * @param delays A map from signal nodes to allocated delay lines.
503
- * @param tables A map from signal nodes to static table data.
504
- * @param inputs_control A map from signal nodes to input UI controls.
505
- * @param outputs_control A map from signal nodes to output UI controls.
506
- * @param declare_block The block where runtime variable declarations will be emitted.
507
- * @param reset_block The block where reset instructions (e.g., control initialization)
508
- * will be emitted.
509
+ * @param compiler The compiler.
509
510
*/
510
- SignalBuilder (std::map<Tree, DelayedSig>& delays, std::map<Tree, TableData>& tables,
511
- std::map<Tree, inputControl>& inputs_control,
512
- std::map<Tree, outputControl>& outputs_control, BlockInst* declare_block,
513
- BlockInst* reset_block)
514
- : fDelays (delays),
515
- fTables (tables),
516
- fInputControls(inputs_control),
517
- fOutputControls(outputs_control),
518
- fDeclareBlock(declare_block),
519
- fResetBlock(reset_block)
520
- {
521
- fVisitGen = true ;
522
- }
511
+ SignalBuilder (SignalFIRCompiler& compiler) : fCompiler (compiler) { fVisitGen = true ; }
523
512
524
513
/* *
525
514
* @brief Visits a signal node and generates any required runtime structure.
@@ -576,9 +565,11 @@ struct SignalFIRCompiler : public SignalVisitor {
576
565
isSigInt (size_tree, &size_val);
577
566
Type c_type = getCertifiedSigType (gen_tree);
578
567
if (c_type->nature () == kInt ) {
579
- fTables [sig] = TableData (gGlobal ->getFreshID (" iTable" ), gen_tree, size_val);
568
+ fCompiler .fTables [sig] =
569
+ TableData (gGlobal ->getFreshID (" iTable" ), gen_tree, size_val);
580
570
} else {
581
- fTables [sig] = TableData (gGlobal ->getFreshID (" fTable" ), gen_tree, size_val);
571
+ fCompiler .fTables [sig] =
572
+ TableData (gGlobal ->getFreshID (" fTable" ), gen_tree, size_val);
582
573
}
583
574
SignalVisitor::visit (sig);
584
575
} else if (isSigWaveform (sig)) {
@@ -594,39 +585,36 @@ struct SignalFIRCompiler : public SignalVisitor {
594
585
}
595
586
*/
596
587
} else if (isSigButton (sig, path)) { // UI
597
- fInputControls [sig] =
598
- inputControl (sig, fDeclareBlock , fResetBlock , inputControl::kButton ,
588
+ fCompiler . fInputControls [sig] =
589
+ inputControl (sig, fCompiler , inputControl::kButton ,
599
590
removeMetadata (tree2str (hd (path))), 0 , 0 , 1 , 1 );
600
591
} else if (isSigCheckbox (sig, path)) {
601
- fInputControls [sig] =
602
- inputControl (sig, fDeclareBlock , fResetBlock , inputControl::kCheckbutton ,
592
+ fCompiler . fInputControls [sig] =
593
+ inputControl (sig, fCompiler , inputControl::kCheckbutton ,
603
594
removeMetadata (tree2str (hd (path))), 0 , 0 , 1 , 1 );
604
595
} else if (isSigVSlider (sig, path, c, x, y, z)) {
605
- fInputControls [sig] =
606
- inputControl (sig, fDeclareBlock , fResetBlock , inputControl::kVslider ,
607
- removeMetadata (tree2str (hd (path))), tree2double (c), tree2double (x),
608
- tree2double (y), tree2double (z));
596
+ fCompiler .fInputControls [sig] = inputControl (
597
+ sig, fCompiler , inputControl::kVslider , removeMetadata (tree2str (hd (path))),
598
+ tree2double (c), tree2double (x), tree2double (y), tree2double (z));
609
599
} else if (isSigHSlider (sig, path, c, x, y, z)) {
610
- fInputControls [sig] =
611
- inputControl (sig, fDeclareBlock , fResetBlock , inputControl::kHslider ,
612
- removeMetadata (tree2str (hd (path))), tree2double (c), tree2double (x),
613
- tree2double (y), tree2double (z));
600
+ fCompiler .fInputControls [sig] = inputControl (
601
+ sig, fCompiler , inputControl::kHslider , removeMetadata (tree2str (hd (path))),
602
+ tree2double (c), tree2double (x), tree2double (y), tree2double (z));
614
603
} else if (isSigNumEntry (sig, path, c, x, y, z)) {
615
- fInputControls [sig] =
616
- inputControl (sig, fDeclareBlock , fResetBlock , inputControl::kNumEntry ,
617
- removeMetadata (tree2str (hd (path))), tree2double (c), tree2double (x),
618
- tree2double (y), tree2double (z));
604
+ fCompiler .fInputControls [sig] = inputControl (
605
+ sig, fCompiler , inputControl::kNumEntry , removeMetadata (tree2str (hd (path))),
606
+ tree2double (c), tree2double (x), tree2double (y), tree2double (z));
619
607
} else if (isSigVBargraph (sig, path, x, y,
620
608
z)) { // z is the input signal to the bargraph
621
- fOutputControls [sig] = outputControl (sig, fDeclareBlock , outputControl:: kVbargraph ,
622
- removeMetadata (tree2str (hd (path))),
623
- tree2double (x), tree2double (y));
609
+ fCompiler . fOutputControls [sig] = outputControl (
610
+ sig, fCompiler , outputControl:: kVbargraph , removeMetadata (tree2str (hd (path))),
611
+ tree2double (x), tree2double (y));
624
612
SignalVisitor::visit (sig); // Visit children (i.e., the input signal z)
625
613
} else if (isSigHBargraph (sig, path, x, y,
626
614
z)) { // z is the input signal to the bargraph
627
- fOutputControls [sig] = outputControl (sig, fDeclareBlock , outputControl:: kHbargraph ,
628
- removeMetadata (tree2str (hd (path))),
629
- tree2double (x), tree2double (y));
615
+ fCompiler . fOutputControls [sig] = outputControl (
616
+ sig, fCompiler , outputControl:: kHbargraph , removeMetadata (tree2str (hd (path))),
617
+ tree2double (x), tree2double (y));
630
618
SignalVisitor::visit (sig); // Visit children (i.e., the input signal z)
631
619
} else {
632
620
// Other cases
@@ -658,21 +646,20 @@ struct SignalFIRCompiler : public SignalVisitor {
658
646
: fNumInputs (inputs), fNumOutputs (outputs), fOutputSig (lsig)
659
647
{
660
648
// Allocate IR blocks
661
- fGlobalBlock = IB::genBlockInst (); // Global code (e.g., global variables)
662
- fDeclareBlock = IB::genBlockInst (); // Variable declarations
663
- fInitBlock = IB::genBlockInst (); // Initialization code
664
- fResetBlock = IB::genBlockInst (); // Reset code
665
- fClearBlock = IB::genBlockInst (); // Clear state code
666
- fControlBlock = IB::genBlockInst (); // Control/UI update code
667
- fComputeBlock = IB::genBlockInst (); // Main DSP computation
668
-
649
+ fGlobalBlock = IB::genBlockInst ();
650
+ fDeclareBlock = IB::genBlockInst ();
651
+ fInitBlock = IB::genBlockInst ();
652
+ fResetBlock = IB::genBlockInst ();
653
+ fClearBlock = IB::genBlockInst ();
654
+ fControlBlock = IB::genBlockInst ();
655
+ fComputeBlock = IB::genBlockInst ();
656
+
669
657
// Prepare the signal compilation context
670
658
// The SignalBuilder populates:
671
659
// - Delay lines (fDelays)
672
660
// - Lookup tables (fTables)
673
661
// - UI controls (fInputControls, fOutputControls)
674
- SignalBuilder builder (fDelays , fTables , fInputControls , fOutputControls , fDeclareBlock ,
675
- fResetBlock );
662
+ SignalBuilder builder (*this );
676
663
builder.visitRoot (fOutputSig ); // Traverse the DSP signal tree and collect resources
677
664
}
678
665
@@ -867,7 +854,7 @@ struct SignalFIRCompiler : public SignalVisitor {
867
854
// to store intermediate `ValueInst*` results in a LIFO
868
855
// (last-in, first-out) order.
869
856
// ------------------------------------------------------------
870
-
857
+
871
858
/* *
872
859
* @brief Pop the top value from the stack.
873
860
*
@@ -895,12 +882,12 @@ struct SignalFIRCompiler : public SignalVisitor {
895
882
ValueInst* topRes () { return fValueStack .top (); }
896
883
897
884
/* *
898
- * @brief Push a value onto the stack.
899
- *
900
- * Adds a new `ValueInst` to the top of the stack.
901
- *
902
- * @param val The `ValueInst*` to push.
903
- */
885
+ * @brief Push a value onto the stack.
886
+ *
887
+ * Adds a new `ValueInst` to the top of the stack.
888
+ *
889
+ * @param val The `ValueInst*` to push.
890
+ */
904
891
void pushRes (ValueInst* val) { fValueStack .push (val); }
905
892
906
893
virtual void visit (Tree t) override ;
0 commit comments