Skip to content

Commit

Permalink
[NEW] Add getSigInterval/setSigInterval in signal API.
Browse files Browse the repository at this point in the history
  • Loading branch information
sletz committed Aug 14, 2023
1 parent 7dcdd2c commit f3b099b
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 17 deletions.
4 changes: 2 additions & 2 deletions architecture/faust/dsp/libfaust-signal-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ extern "C"
/**
* Simplify a signal to its normal form, where:
* - all possible optimisations, simplications, and compile time computations have been done
* - the mathematical functions (primitives and binary functions), delay, select2, sounfile primitive...
* - the mathematical functions (primitives and binary functions), delay, select2, soundfile primitive...
* are properly typed (arguments and result)
* - signal cast are properly done when needed
*
Expand All @@ -546,7 +546,7 @@ extern "C"
/**
* Simplify a null terminated array of signals to its normal form, where:
* - all possible optimisations, simplications, and compile time computations have been done
* - the mathematical functions (primitives and binary functions), delay, select2, sounfile primitive...
* - the mathematical functions (primitives and binary functions), delay, select2, soundfile primitive...
* are properly typed (arguments and result)
* - signal cast are properly done when needed
*
Expand Down
31 changes: 29 additions & 2 deletions architecture/faust/dsp/libfaust-signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <string>
#include <vector>
#include <ostream>
#include <limits>

#include "faust/export.h"

Expand Down Expand Up @@ -117,6 +118,27 @@ LIBFAUST_API std::string printSignal(Signal sig, bool shared, int max_size);
#ifndef LIBFAUSTSIGNAL_H
#define LIBFAUSTSIGNAL_H

// To be used with getSigInterval/setSigInterval
struct Interval {
double fLo{std::numeric_limits<double>::lowest()}; //< minimal value
double fHi{std::numeric_limits<double>::max()}; //< maximal value
int fLSB{-24}; //< lsb in bits

// To be used to set a full interval
Interval(double lo, double hi, int lsb):fLo(lo), fHi(hi), fLSB(lsb)
{}

// To be used to only set the LSB, with fLo and fHi taking default values
Interval(int lsb):fLSB(lsb)
{}
};

std::ostream& operator<<(std::ostream& dst, const Interval& it)
{
dst << "Interval [" << it.fLo << ", " << it.fHi << ", " << it.fLSB << "]";
return dst;
}

/**
* Create global compilation context, has to be done first.
*/
Expand All @@ -127,6 +149,11 @@ extern "C" LIBFAUST_API void createLibContext();
*/
extern "C" LIBFAUST_API void destroyLibContext();


LIBFAUST_API Interval getSigInterval(Signal s);

LIBFAUST_API void setSigInterval(Signal s, Interval& inter);

/**
* Check if a signal is nil.
*
Expand Down Expand Up @@ -608,7 +635,7 @@ LIBFAUST_API bool isSigSoundfileBuffer(Signal s, Signal& sf, Signal& chan, Signa
/**
* Simplify a signal to its normal form, where:
* - all possible optimisations, simplications, and compile time computations have been done
* - the mathematical functions (primitives and binary functions), delay, select2, sounfile primitive...
* - the mathematical functions (primitives and binary functions), delay, select2, soundfile primitive...
* are properly typed (arguments and result)
* - signal cast are properly done when needed
*
Expand All @@ -621,7 +648,7 @@ LIBFAUST_API Signal simplifyToNormalForm(Signal s);
/**
* Simplify a signal vector to its normal form, where:
* - all possible optimisations, simplications, and compile time computations have been done
* - the mathematical functions (primitives and binary functions), delay, select2, sounfile primitive...
* - the mathematical functions (primitives and binary functions), delay, select2, soundfile primitive...
* are properly typed (arguments and result)
* - signal cast are properly done when needed
*
Expand Down
35 changes: 35 additions & 0 deletions compiler/box_signal_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "ppbox.hh"
#include "xtended.hh"
#include "propagate.hh"
#include "sigtyperules.hh"

using namespace std;

Expand Down Expand Up @@ -62,6 +63,40 @@ extern "C" LIBFAUST_API void destroyLibContext()
global::destroy();
}

// MUST match definition in libfaust-signal.h
#define low std::numeric_limits<double>::lowest()
#define high std::numeric_limits<double>::max()

struct Interval {
double fLo{low}; //< minimal value
double fHi{high}; //< maximal value
int fLSB{-24}; //< lsb in bits

Interval(double lo, double hi, int lsb):fLo(lo), fHi(hi), fLSB(lsb)
{}
Interval(int lsb):fLSB(lsb)
{}
};

LIBFAUST_API Interval getSigInterval(Tree sig)
{
interval it = getSigType(sig)->getInterval();
return Interval(it.lo(), it.hi(), it.lsb());
}

LIBFAUST_API void setSigInterval(Tree sig, Interval& inter)
{
Type ty = getSigType(sig);
interval it1 = ty->getInterval();
// If the inter argument has low/high range (the defaults), then it1 low/high values are kept,
// otherwise use the given ones
interval it2 ((inter.fLo == low) ? it1.lo() : inter.fLo,
(inter.fHi == high) ? it1.hi() : inter.fHi,
inter.fLSB);
ty->setInterval(it2);
setSigType(sig, ty);
}

LIBFAUST_API const char* xtendedName(Tree tree)
{
void* userData = getUserData(tree);
Expand Down
3 changes: 2 additions & 1 deletion compiler/generator/instructions_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ Tree InstructionsCompiler::prepare(Tree LS)
throw faustexception("Dump shared normal form finished...\n");
} else if (gGlobal->gDumpNorm == 2) {
// Print signal tree type
SignalTypePrinter printer(L1);
SignalTypePrinter types(L1);
std::cout << types.print();
throw faustexception("Dump signal type finished...\n");
}

Expand Down
6 changes: 4 additions & 2 deletions compiler/normalize/normalform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ LIBFAUST_API Tree simplifyToNormalForm(Tree t)

LIBFAUST_API tvec simplifyToNormalForm2(tvec siglist)
{
return treeConvert(simplifyToNormalForm(listConvert(siglist)));
tvec res;
for (const auto& it : siglist) { res.push_back(simplifyToNormalForm(it));}
return res;
}

LIBFAUST_API string printSignal(Tree sig, bool shared, int max_size)
Expand All @@ -161,7 +163,7 @@ LIBFAUST_API string printSignal(Tree sig, bool shared, int max_size)
gGlobal->clear();
stringstream str;
if (shared) {
ppsigShared(sig, str);
ppsigShared(sig, str, max_size);
} else {
str << ppsig(sig, max_size) << endl;
}
Expand Down
5 changes: 2 additions & 3 deletions compiler/signals/sigtype.hh
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class AudioType : public virtual Garbageable {
int boolean() const { return fBoolean; } ///< returns when a signal stands for a boolean value

interval getInterval() const { return fInterval; } ///< returns the interval (min and max values) of a signal
void setInterval(const interval& r) { fInterval = r; }
res getRes() const { return fRes; } ///< returns the resolution of the signal (fixed)

void setCode(Tree code) { fCode = code; } ///< sets the memoized code of a signal
Expand All @@ -125,9 +126,7 @@ class AudioType : public virtual Garbageable {
virtual std::ostream& print(std::ostream& dst) const = 0; ///< print nicely a type
///< true when type is maximal (and therefore can't change depending of hypothesis)
virtual bool isMaximal() const = 0;

protected:
void setInterval(const interval& r) { fInterval = r; }

};

// printing
Expand Down
3 changes: 1 addition & 2 deletions compiler/signals/sigtyperules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ using namespace std;
// prototypes
//--------------------------------------------------------------------------

static void setSigType(Tree sig, Type t);
static TupletType* initialRecType(Tree t);
static TupletType* maximalRecType(Tree t);

Expand Down Expand Up @@ -372,7 +371,7 @@ ::Type getCertifiedSigType(Tree sig)
* @param sig the signal we want to type
* @param t the type of the signal
*/
static void setSigType(Tree sig, Type t)
void setSigType(Tree sig, Type t)
{
TRACE(cerr << gGlobal->TABBER << "SET FIX TYPE OF " << ppsig(sig, MAX_ERROR_SIZE) << " TO TYPE " << *t << endl;)
sig->setType(t);
Expand Down
7 changes: 6 additions & 1 deletion compiler/signals/sigtyperules.hh
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,16 @@ void typeAnnotation(Tree sig, bool causality);
*/
::Type getCertifiedSigType(Tree term);


/**
* Retrieve the type annotation of sig
* @param sig the signal we want to know the type
*/
::Type getSigType(Tree sig);

/**
* Retrieve the type annotation of sig
* @param sig the signal we want to know the type
*/
void setSigType(Tree sig, ::Type);

#endif
12 changes: 9 additions & 3 deletions compiler/transform/sigPromotion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,22 @@ SignalTypePrinter::SignalTypePrinter(Tree L)
// Check that the root tree is properly type annotated
getCertifiedSigType(L);
visitRoot(L);
}

string SignalTypePrinter::print()
{
/*
HACK: since the signal tree shape is still not deterministic,
we sort the list to be sure it stays the same.
To be removed if the tree shape becomes deterministic.
*/
std::sort(fPrinted.begin(), fPrinted.end());
std::cout << "Size = " << fPrinted.size() << std::endl;
stringstream out;
sort(fPrinted.begin(), fPrinted.end());
out << "Size = " << fPrinted.size() << std::endl;
for (const auto& it : fPrinted) {
std::cout << it;
out << it;
}
return out.str();
}

void SignalTypePrinter::visit(Tree sig)
Expand Down
2 changes: 2 additions & 0 deletions compiler/transform/sigPromotion.hh
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class SignalTypePrinter final : public SignalVisitor {

public:
SignalTypePrinter(Tree L);

std::string print();

};

Expand Down
2 changes: 1 addition & 1 deletion compiler/transform/signalVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ void SignalVisitor::visit(Tree sig)
else if (isSigIntCast(sig, x)) {
self(x);
return;
}else if (isSigBitCast(sig, x)) {
} else if (isSigBitCast(sig, x)) {
self(x);
return;
} else if (isSigFloatCast(sig, x)) {
Expand Down
47 changes: 47 additions & 0 deletions tools/benchmark/signal-tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,52 @@ static void normalform()
)
}

static void intervals()
{
COMPILER
(
tvec signals;

Signal s1 = sigAdd(sigAdd(sigDelay(sigDelay(sigInput(0), sigReal(500)), sigReal(200)), sigReal(0.5)), sigReal(3));
Signal s2 = sigMul(sigMul(sigDelay(sigInput(0), sigInt(500)), sigReal(0.5)), sigReal(4));
signals.push_back(s1);
signals.push_back(s2);

compile("intervals1", signals);

Interval i1 = getSigInterval(s1);
Interval i2 = getSigInterval(s2);

cout << i1 << endl;
cout << i2 << endl;

Interval i3(48);
Interval i4(-10, 10, 48);
setSigInterval(s1, i3);
setSigInterval(s2, i4);

// Compute normal form
tvec nf = simplifyToNormalForm2(signals);

cout << "\nPrint the signals in normal form\n";
for (size_t i = 0; i < nf.size(); i++) {
cout << printSignal(nf[i], false, INT_MAX);
}

cout << "\nPrint the signals in short form\n";
for (size_t i = 0; i < nf.size(); i++) {
cout << printSignal(nf[i], false, 128);
}

cout << "\nPrint the signals in normal form in shared mode\n";
for (size_t i = 0; i < nf.size(); i++) {
cout << printSignal(nf[i], true, INT_MAX);
}

compile("intervals2", signals);
)
}

// process = @(+(0.5), 500) * vslider("Vol", 0.5, 0, 1, 0.01);

static void test8()
Expand Down Expand Up @@ -807,6 +853,7 @@ int main(int argc, char* argv[])
equivalent1();
equivalent2();
normalform();
intervals();
test8();
test9();
test10();
Expand Down

0 comments on commit f3b099b

Please sign in to comment.