Skip to content

Commit

Permalink
Implement soundfile handling at init stage in C, C++, LLVM and Interp…
Browse files Browse the repository at this point in the history
… backend.
  • Loading branch information
sletz committed Sep 28, 2024
1 parent e9e1e8f commit bd03668
Show file tree
Hide file tree
Showing 20 changed files with 190 additions and 44 deletions.
24 changes: 17 additions & 7 deletions architecture/ca-gtk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@

#ifdef SOUNDFILE
#include "faust/gui/SoundUI.h"
#include "faust/dsp/dsp-tools.h"
#endif

// Always include this file, otherwise -nvoices only mode does not compile....
Expand Down Expand Up @@ -218,19 +219,28 @@ int main(int argc, char* argv[])
cout << "HTTPD is on" << endl;
#endif

#ifdef SOUNDFILE
{
// Init default DSP to get the SR
coreaudio audio(srate, fpb);
default_dsp def_dsp;
if (!audio.init(name, &def_dsp)) {
cerr << "Unable to init audio" << endl;
exit(1);
}
// After audio init to get SR
srate = audio.getSampleRate();
}
SoundUI soundinterface("", srate);
DSP->buildUserInterface(&soundinterface);
#endif

coreaudio audio(srate, fpb);
if (!audio.init(name, DSP)) {
cerr << "Unable to init audio" << endl;
exit(1);
}

// After audio init to get SR
#ifdef SOUNDFILE
// Use bundle path
SoundUI soundinterface("", audio.getSampleRate());
DSP->buildUserInterface(&soundinterface);
#endif

#ifdef OSCCTRL
OSCUI oscinterface(name, argc, argv);
DSP->buildUserInterface(&oscinterface);
Expand Down
30 changes: 30 additions & 0 deletions architecture/faust/dsp/dsp-tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,5 +225,35 @@ class AudioChannels
FAUSTFLOAT** buffers() { return fChannels; }
};

// Default DSP
struct default_dsp : public dsp {

int getNumInputs() { return 1; }

int getNumOutputs() { return 1; }

void buildUserInterface(UI* ui_interface) {}

int getSampleRate() { return 44100; }

void init(int sample_rate) {}

void instanceInit(int sample_rate) {}

void instanceConstants(int sample_rate) {}

void instanceResetUserInterface() {}

void instanceClear() {}

dsp* clone() { return new default_dsp(); }

void metadata(Meta* m) {}

void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
{}

};

#endif
/************************** END dsp-tools.h **************************/
1 change: 1 addition & 0 deletions architecture/faust/gui/CInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ typedef void (* buildUserInterfaceFun) (dsp_imp* dsp, UIGlue* ui);
typedef int (* getSampleRateFun) (dsp_imp* dsp);
typedef void (* initFun) (dsp_imp* dsp, int sample_rate);
typedef void (* classInitFun) (int sample_rate);
typedef void (* staticInitFun) (dsp_imp* dsp, int sample_rate);
typedef void (* instanceInitFun) (dsp_imp* dsp, int sample_rate);
typedef void (* instanceConstantsFun) (dsp_imp* dsp, int sample_rate);
typedef void (* instanceResetUserInterfaceFun) (dsp_imp* dsp);
Expand Down
4 changes: 2 additions & 2 deletions compiler/documentator/doc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ static void printDocDgm(const Tree expr, const char* svgTopDir, ostream& docout,
* Warning : pdflatex can't directly include SVG files !
*/
char dgmid[MAXIDCHARS + 1];
sprintf(dgmid, "%02d", i);
snprintf(dgmid, sizeof(dgmid), "%02d", i);
string thisdgmdir = subst("$0/svg-$1", svgTopDir, dgmid);
// cerr << "Documentator : printDocDgm : drawSchema in '" << gCurrentDir << "/" << thisdgmdir <<
// "'" << endl;
Expand Down Expand Up @@ -1026,7 +1026,7 @@ static char* legalFileName(const Tree t, int n, char* dst)
static string calcNumberedName(const char* base, int i)
{
char nb[MAXIDCHARS + 1];
sprintf(nb, "%03d", i);
snprintf(nb, sizeof(nb), "%03d", i);
return subst("$0$1", base, nb);
}

Expand Down
19 changes: 16 additions & 3 deletions compiler/generator/code_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,6 @@ void CodeContainer::processFIR(void)
createMemoryLayout();
}

// Possibly generate JSON
generateJSONFile();

// Sort struct fields by size and type
// 05/16/17 : deactivated since it slows down the code...
/*
Expand All @@ -505,6 +502,15 @@ void CodeContainer::processFIR(void)
fCurLoop->generateScalarLoop("count"));
endTiming("FIR var checker");
}

#ifdef FIR_BUILD
if (global::isDebug("FIR_PRINTER")) {
stringstream res;
FIRInstVisitor fir_visitor(&res);
flattenFIR()->accept(&fir_visitor);
std::cout << res.str();
}
#endif
}

// Possibly rewrite arrays access using iZone/fZone
Expand Down Expand Up @@ -540,22 +546,29 @@ void CodeContainer::rewriteInZones()

void CodeContainer::mergeSubContainers()
{
BlockInst* sub_ui = new BlockInst();

for (const auto& it : fSubContainers) {
// Merge the subcontainer in the main one
fExtGlobalDeclarationInstructions->merge(it->fExtGlobalDeclarationInstructions);
fGlobalDeclarationInstructions->merge(it->fGlobalDeclarationInstructions);
fDeclarationInstructions->merge(it->fDeclarationInstructions);
fControlDeclarationInstructions->merge(it->fControlDeclarationInstructions);
sub_ui->merge(it->fUserInterfaceInstructions);
// TO CHECK (used for waveform initialisation which has to be moved first...)
fStaticInitInstructions->mergeFront(it->fStaticInitInstructions);
// Then clear it
it->fGlobalDeclarationInstructions->fCode.clear();
it->fExtGlobalDeclarationInstructions->fCode.clear();
it->fDeclarationInstructions->fCode.clear();
it->fControlDeclarationInstructions->fCode.clear();
it->fUserInterfaceInstructions->fCode.clear();
it->fStaticInitInstructions->fCode.clear();
}

// Insert subcontainer UIs at the end of the top group, just before the last closeBox
fUserInterfaceInstructions->insert(fUserInterfaceInstructions->size() - 1, sub_ui);

// Possibly rewrite access in iZone/fZone
rewriteInZones();
}
Expand Down
7 changes: 7 additions & 0 deletions compiler/generator/code_container.hh
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,13 @@ class CodeContainer : public virtual Garbageable {
return inst;
}

StatementInst* pushPreUserInterfaceMethod(StatementInst* inst)
{
faustassert(inst);
fUserInterfaceInstructions->pushFrontInst(inst);
return inst;
}

StatementInst* pushAllocateMethod(StatementInst* inst)
{
faustassert(inst);
Expand Down
7 changes: 7 additions & 0 deletions compiler/generator/instructions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,13 @@ struct BlockInst : public StatementInst {
}
}

void insert(int index, BlockInst* inst)
{
auto it = fCode.begin();
std::advance(it, index);
fCode.insert(it, inst);
}

int size() const { return int(fCode.size()); }

bool hasReturn() const;
Expand Down
4 changes: 4 additions & 0 deletions compiler/generator/instructions_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "instructions_compiler.hh"
#include "instructions_compiler1.hh"
#include "instructions_compiler_jax.hh"
#include "interpreter_code_container.hh"
#include "normalform.hh"
#include "prim2.hh"
#include "recursivness.hh"
Expand Down Expand Up @@ -429,6 +430,9 @@ CodeContainer* InstructionsCompiler::signal2Container(const string& name, Tree s
} else if (gGlobal->gOutputLang == "jax") {
InstructionsCompilerJAX C(container);
C.compileSingleSignal(sig);
} else if (gGlobal->gOutputLang == "interp") {
InterpreterInstructionsCompiler C(container);
C.compileSingleSignal(sig);
} else {
// Special compiler for -fx mode
if (gGlobal->gFloatSize == 4) {
Expand Down
48 changes: 45 additions & 3 deletions compiler/generator/llvm/llvm_code_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,13 @@ void LLVMCodeContainer::produceInternal()

dsp_factory_base* LLVMCodeContainer::produceFactory()
{
// Generate gub containers
generateSubContainers();
if (gGlobal->gInlineTable) {
// Sub containers are merged in the main class
mergeSubContainers();
} else {
// Generate sub containers
generateSubContainers();
}

// Build DSP struct
generateDeclarations(&fStructVisitor);
Expand All @@ -230,7 +235,11 @@ dsp_factory_base* LLVMCodeContainer::produceFactory()
generateExtGlobalDeclarations(fCodeProducer);
generateGlobalDeclarations(fCodeProducer);

generateStaticInitFun("classInit" + fKlassName, false)->accept(fCodeProducer);
if (gGlobal->gInlineTable) {
generateStaticInitFun("staticInit" + fKlassName, false)->accept(fCodeProducer);
} else {
generateStaticInitFun("classInit" + fKlassName, false)->accept(fCodeProducer);
}
generateInstanceClear("instanceClear" + fKlassName, "dsp", false, false)->accept(fCodeProducer);
generateInstanceConstants("instanceConstants" + fKlassName, "dsp", false, false)
->accept(fCodeProducer);
Expand Down Expand Up @@ -275,6 +284,39 @@ dsp_factory_base* LLVMCodeContainer::produceFactory()
return new llvm_dynamic_dsp_factory_aux("", fModule, fContext, "", -1);
}

DeclareFunInst* LLVMCodeContainer::generateStaticInitFun(const string& name, bool isstatic)
{
Names args;
if (gGlobal->gInlineTable) {
args.push_back(IB::genNamedTyped("dsp", Typed::kObj_ptr));
}
args.push_back(IB::genNamedTyped("sample_rate", Typed::kInt32));

BlockInst* block = IB::genBlockInst();

if (gGlobal->gInlineTable) {
BlockInst* inlined = inlineSubcontainersFunCalls(fStaticInitInstructions);
block->pushBackInst(inlined);
} else {
block->pushBackInst(fStaticInitInstructions);
block->pushBackInst(fPostStaticInitInstructions);
}

// 20/11/16 : added in generateInstanceInitFun, is this needed here ?
/*
init_block->pushBackInst(fResetUserInterfaceInstructions);
init_block->pushBackInst(fClearInstructions);
*/

// Explicit return
block->pushBackInst(IB::genRetInst());

// Creates function
FunTyped* fun_type = IB::genFunTyped(args, IB::genVoidTyped(),
(isstatic) ? FunTyped::kStatic : FunTyped::kDefault);
return IB::genDeclareFunInst(name, fun_type, block);
}

// Scalar
LLVMScalarCodeContainer::LLVMScalarCodeContainer(const string& name, int numInputs, int numOutputs)
: LLVMCodeContainer(name, numInputs, numOutputs)
Expand Down
11 changes: 4 additions & 7 deletions compiler/generator/llvm/llvm_code_container.hh
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,10 @@ class LLVMCodeContainer : public virtual CodeContainer {
template <typename REAL>
void generateGetJSON()
{
LLVMPtrType string_ptr = llvm::PointerType::get(fBuilder->getInt8Ty(), 0);
LLVMVecTypes getJSON_args;
#if LLVM_VERSION_MAJOR >= 16
llvm::FunctionType* getJSON_type =
llvm::FunctionType::get(string_ptr, llvm::ArrayRef<LLVMType>(getJSON_args), false);
#else
LLVMPtrType string_ptr = llvm::PointerType::get(fBuilder->getInt8Ty(), 0);
LLVMVecTypes getJSON_args;
llvm::FunctionType* getJSON_type =
llvm::FunctionType::get(string_ptr, makeArrayRef(getJSON_args), false);
#endif
LLVMFun getJSON = llvm::Function::Create(getJSON_type, llvm::GlobalValue::ExternalLinkage,
"getJSON" + fKlassName, fModule);

Expand Down Expand Up @@ -111,6 +106,8 @@ class LLVMCodeContainer : public virtual CodeContainer {
CodeContainer* createScalarContainer(const std::string& name, int sub_container_type);

static CodeContainer* createContainer(const std::string& name, int numInputs, int numOutputs);

DeclareFunInst* generateStaticInitFun(const std::string& name, bool isstatic);
};

class LLVMScalarCodeContainer : public LLVMCodeContainer {
Expand Down
17 changes: 13 additions & 4 deletions compiler/generator/llvm/llvm_dsp_aux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,17 @@ dsp_factory_table<SDsp_factory> llvm_dsp_factory_aux::gLLVMFactoryTable;
// Set of externally defined functions, to be linked with the LLVM module
set<string> llvm_dsp_factory_aux::gForeignFunctions;

uint64_t llvm_dsp_factory_aux::loadOptimize(const string& function)
uint64_t llvm_dsp_factory_aux::loadOptimize(const string& function, bool strict)
{
uint64_t fun = fJIT->getFunctionAddress(function);
if (fun) {
return fun;
} else {
} else if (strict) {
stringstream error;
error << "ERROR : loadOptimize failed for '" << function << "'\n";
throw faustexception(error.str());
} else {
return 0;
}
}

Expand Down Expand Up @@ -204,6 +206,7 @@ void llvm_dsp_factory_aux::init(const string& type_name, const string& dsp_name)
fInstanceConstants = nullptr;
fInstanceClear = nullptr;
fClassInit = nullptr;
fStaticInit = nullptr;
fCompute = nullptr;
// By default
fClassName = "mydsp";
Expand Down Expand Up @@ -267,7 +270,8 @@ bool llvm_dsp_factory_aux::initJITAux()
fDestroy = (destroyDspFun)loadOptimize("destroy" + fClassName);
fInstanceConstants = (instanceConstantsFun)loadOptimize("instanceConstants" + fClassName);
fInstanceClear = (instanceClearFun)loadOptimize("instanceClear" + fClassName);
fClassInit = (classInitFun)loadOptimize("classInit" + fClassName);
fClassInit = (classInitFun)loadOptimize("classInit" + fClassName, false);
fStaticInit = (staticInitFun)loadOptimize("staticInit" + fClassName, false);
fCompute = (computeFun)loadOptimize("compute" + fClassName);
fGetJSON = (getJSONFun)loadOptimize("getJSON" + fClassName);

Expand Down Expand Up @@ -397,11 +401,16 @@ void llvm_dsp::init(int sample_rate)

void llvm_dsp::classInit(int sample_rate)
{
fFactory->getFactory()->fClassInit(sample_rate);
if (fFactory->getFactory()->fClassInit) {
fFactory->getFactory()->fClassInit(sample_rate);
}
}

void llvm_dsp::instanceInit(int sample_rate)
{
if (fFactory->getFactory()->fStaticInit) {
fFactory->getFactory()->fStaticInit(fDSP, sample_rate);
}
instanceConstants(sample_rate);
instanceResetUserInterface();
instanceClear();
Expand Down
19 changes: 14 additions & 5 deletions compiler/generator/llvm/llvm_dsp_aux.hh
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,15 @@ class llvm_dsp_factory_aux : public dsp_factory_imp {
destroyDspFun fDestroy;
initFun fInstanceConstants;
instanceClearFun fInstanceClear;
classInitFun fClassInit;
computeFun fCompute;
getJSONFun fGetJSON;
// fClassInit in used in default compilation mode
classInitFun fClassInit;
// fStaticInit in used in -it compilation mode
staticInitFun fStaticInit;
computeFun fCompute;
getJSONFun fGetJSON;

uint64_t loadOptimize(const std::string& function);
// Returns the function address or 0
uint64_t loadOptimize(const std::string& function, bool strict = true);

void init(const std::string& dsp_name, const std::string& type_name);

Expand Down Expand Up @@ -305,7 +309,12 @@ class LIBFAUST_API llvm_dsp_factory : public dsp_factory, public faust_smartable

llvm_dsp* createDSPInstance();

void classInit(int sample_rate) { fFactory->fClassInit(sample_rate); }
void classInit(int sample_rate)
{
if (fFactory->fClassInit) {
fFactory->fClassInit(sample_rate);
}
}

void setMemoryManager(dsp_memory_manager* manager) { fFactory->setMemoryManager(manager); }
dsp_memory_manager* getMemoryManager() { return fFactory->getMemoryManager(); }
Expand Down
Loading

0 comments on commit bd03668

Please sign in to comment.