diff --git a/.travis.yml b/.travis.yml
index 266b8a8..716ed91 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,7 +17,7 @@ matrix:
script:
- mkdir build && cd build
- cmake .. -GXcode -DUSE_LLVM_CONFIG=off -DLLVM_DIR=./llvm/lib/cmake/llvm
- - cmake --build . --config Release --target faust_tilde_project
+ - cmake --build . --config Release --target faustgen_tilde_project
- os: linux
compiler: gcc
env: release_arch=Linux-amd64-32
@@ -29,16 +29,16 @@ matrix:
script:
- mkdir build && cd build
- cmake .. -DCMAKE_C_FLAGS=-m64 -DUSE_LLVM_CONFIG=off -DLLVM_DIR=./llvm/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release
- - cmake --build . --config Release --target faust_tilde_project
+ - cmake --build . --config Release --target faustgen_tilde_project
before_deploy:
- cd $TRAVIS_BUILD_DIR
- cp -r faust/libraries external/libs
- - cp src/faust_tilde.c external/faust_tilde.c
+ - cp src/faustgen_tilde.c external/faustgen_tilde.c
- cp README.md external/README.txt
- cp LICENSE external/LICENSE.txt
- curl -o ./external/faust-quick-reference.pdf http://faust.grame.fr/images/faust-quick-reference.pdf
- - mv external faust~
- - zip -r "faust_tilde-$release_arch-sources.zip" faust~
+ - mv external faustgen~
+ - zip -r "faustgen_tilde-$release_arch-sources.zip" faustgen~
deploy:
provider: releases
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 96368a7..590c866 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,7 +6,7 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
include(pd.build/pd.cmake)
-project(faust~ C)
+project(faustgen~ C)
## On Linux "force" the link with stdc++
if(UNIX AND NOT APPLE)
@@ -29,17 +29,25 @@ endif()
include(FaustLib.cmake)
## Create Faust~
-message(STATUS "Faust External")
+message(STATUS "faustgen~ external")
## Create the Pure Data external
set_pd_sources(${PROJECT_SOURCE_DIR}/pure-data/src/)
set_pd_external_path("${PROJECT_SOURCE_DIR}/external/")
-add_pd_external(faust_tilde_project faust~ ${PROJECT_SOURCE_DIR}/src/faust_tilde.c)
+file(GLOB faustgen_tilde_sources
+${PROJECT_SOURCE_DIR}/src/faustgen_tilde.c
+${PROJECT_SOURCE_DIR}/src/faust_tilde_ui.h
+${PROJECT_SOURCE_DIR}/src/faust_tilde_ui.c
+${PROJECT_SOURCE_DIR}/src/faust_tilde_io.h
+${PROJECT_SOURCE_DIR}/src/faust_tilde_io.c
+${PROJECT_SOURCE_DIR}/src/faust_tilde_options.h
+${PROJECT_SOURCE_DIR}/src/faust_tilde_options.c)
+add_pd_external(faustgen_tilde_project faustgen~ "${faustgen_tilde_sources}")
## Link the Pure Data external with faustlib
include_directories(${PROJECT_SOURCE_DIR}/faust/architecture)
-add_dependencies(faust_tilde_project staticlib)
-target_link_libraries(faust_tilde_project staticlib)
+add_dependencies(faustgen_tilde_project staticlib)
+target_link_libraries(faustgen_tilde_project staticlib)
## Link the Pure Data external with llvm
find_package(LLVM REQUIRED CONFIG)
@@ -50,11 +58,11 @@ add_definitions(${LLVM_DEFINITIONS})
include_directories(${LLVM_INCLUDE_DIRS})
llvm_map_components_to_libnames(llvm_libs all)
list(REMOVE_ITEM llvm_libs LTO)
-target_link_libraries(faust_tilde_project ${llvm_libs})
+target_link_libraries(faustgen_tilde_project ${llvm_libs})
if(WIN32)
- target_link_libraries(faust_tilde_project ws2_32)
+ target_link_libraries(faustgen_tilde_project ws2_32)
endif()
if(MSVC)
- set_property(TARGET faust_tilde_project APPEND_STRING PROPERTY LINK_FLAGS " /ignore:4099 ")
+ set_property(TARGET faustgen_tilde_project APPEND_STRING PROPERTY LINK_FLAGS " /ignore:4099 ")
endif()
diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
index 0000000..f52204a
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,16 @@
+v0.0.3
+- Change name from faust~ to faustgen~
+- Remove abstraction faust.watcher
+- Add support for autocompile method
+- Add support for passive parameter
+- Add support for list of active parameters
+- Add support for ui glue long names
+- Add support for dynamic compile options
+- Improve print method
+
+v0.0.2
+- Fix Linux dependencies
+- Add abstraction faust.watcher
+
+v0.0.1
+- Integration of FAUST lib inside the faust~ external (Linux/MacOS/Windows)
diff --git a/FaustDeken.bat b/FaustDeken.bat
index 496c085..0792a8c 100644
--- a/FaustDeken.bat
+++ b/FaustDeken.bat
@@ -1,40 +1,40 @@
@echo off
-title Deken manager for Faust~ for Pure Data
+title Deken manager for faustgen~ for Pure Data
set release_version=%1
-rmdir /S /Q faust~
+rmdir /S /Q faustgen~
del /F /S /Q /A *.dek
del /F /S /Q /A *.dek.sha256
del /F /S /Q /A *.dek.txt
-del /F /Q faust_tilde_darwin.zip
-curl -L https://github.com/pierreguillot/faust-pd/releases/download/v%release_version%/faust_tilde-Darwin-amd64-32-sources.zip -o faust_tilde_darwin.zip
-7z x faust_tilde_darwin.zip
-deken package -v%release_version% faust~
-rmdir /S /Q faust~
-del /F /Q faust_tilde_darwin.zip
+del /F /Q faustgen_tilde_darwin.zip
+curl -L https://github.com/pierreguillot/faust-pd/releases/download/v%release_version%/faustgen_tilde-Darwin-amd64-32-sources.zip -o faustgen_tilde_darwin.zip
+7z x faustgen_tilde_darwin.zip
+deken package -v%release_version% faustgen~
+rmdir /S /Q faustgen~
+del /F /Q faustgen_tilde_darwin.zip
-del /F /Q faust_tilde_linux.zip
-curl -L https://github.com/pierreguillot/faust-pd/releases/download/v%release_version%/faust_tilde-Linux-amd64-32-sources.zip -o faust_tilde_linux.zip
-7z x faust_tilde_linux.zip
-deken package -v%release_version% faust~
-rmdir /S /Q faust~
-del /F /Q faust_tilde_linux.zip
+del /F /Q faustgen_tilde_linux.zip
+curl -L https://github.com/pierreguillot/faust-pd/releases/download/v%release_version%/faustgen_tilde-Linux-amd64-32-sources.zip -o faustgen_tilde_linux.zip
+7z x faustgen_tilde_linux.zip
+deken package -v%release_version% faustgen~
+rmdir /S /Q faustgen~
+del /F /Q faustgen_tilde_linux.zip
-del /F /Q faust_tilde_windows.zip
-curl -L https://github.com/pierreguillot/faust-pd/releases/download/v%release_version%/faust_tilde-Windows-amd64-32-sources.zip -o faust_tilde_windows.zip
-7z x faust_tilde_windows.zip
-deken package -v%release_version% faust~
-rmdir /S /Q faust~
-del /F /Q faust_tilde_windows.zip
+del /F /Q faustgen_tilde_windows.zip
+curl -L https://github.com/pierreguillot/faust-pd/releases/download/v%release_version%/faustgen_tilde-Windows-amd64-32-sources.zip -o faustgen_tilde_windows.zip
+7z x faustgen_tilde_windows.zip
+deken package -v%release_version% faustgen~
+rmdir /S /Q faustgen~
+del /F /Q faustgen_tilde_windows.zip
-del /F /Q faust_tilde_archive.zip
-curl -L https://github.com/pierreguillot/faust-pd/archive/v%release_version%.zip -o faust_tilde_archive.zip
-7z x faust_tilde_archive.zip
-rename faust-pd-%release_version% faust~
-deken package -v%release_version% faust~
-rmdir /S /Q faust~
-del /F /Q faust_tilde_archive.zip
+del /F /Q faustgen_tilde_archive.zip
+curl -L https://github.com/pierreguillot/faust-pd/archive/v%release_version%.zip -o faustgen_tilde_archive.zip
+7z x faustgen_tilde_archive.zip
+rename faust-pd-%release_version% faustgen~
+deken package -v%release_version% faustgen~
+rmdir /S /Q faustgen~
+del /F /Q faustgen_tilde_archive.zip
-rem deken upload faust~[v%release_version%](Darwin-amd64-32)(Sources).dek faust~[v%release_version%](Linux-amd64-32)(Sources).dek faust~[v%release_version%](Windows-amd64-32)(Sources).dek faust~[v%release_version%](Sources).dek
+rem deken upload faustgen~[v%release_version%](Darwin-amd64-32)(Sources).dek faustgen~[v%release_version%](Linux-amd64-32)(Sources).dek faustgen~[v%release_version%](Windows-amd64-32)(Sources).dek faustgen~[v%release_version%](Sources).dek
pause
diff --git a/FaustDeken.sh b/FaustDeken.sh
index c09697a..1d1d7ce 100755
--- a/FaustDeken.sh
+++ b/FaustDeken.sh
@@ -1,39 +1,39 @@
#!/bin/bash
-echo -e "title Deken manager for Faust~ for Pure Data"
+echo -e "title Deken manager for faustgen~ for Pure Data"
-rm -rf faust~
+rm -rf faustgen~
rm -f *.dek
rm -f *.dek.sha256
rm -f *.dek.txt
-rm -f faust_tilde_darwin.zip
-curl -L "https://github.com/pierreguillot/faust-pd/releases/download/v$1/faust_tilde-Darwin-amd64-32-sources.zip" -o faust_tilde_darwin.zip
-tar zxvf faust_tilde_darwin.zip
-deken package -v$1 faust~
-rm -rf faust~
-rm -f faust_tilde_darwin.zip
+rm -f faustgen_tilde_darwin.zip
+curl -L "https://github.com/pierreguillot/faust-pd/releases/download/v$1/faustgen_tilde-Darwin-amd64-32-sources.zip" -o faustgen_tilde_darwin.zip
+tar zxvf faustgen_tilde_darwin.zip
+deken package -v$1 faustgen~
+rm -rf faustgen~
+rm -f faustgen_tilde_darwin.zip
-rm -f faust_tilde_linux.zip
-curl -L "https://github.com/pierreguillot/faust-pd/releases/download/v$1/faust_tilde-Linux-amd64-32-sources.zip" -o faust_tilde_linux.zip
-tar zxvf faust_tilde_linux.zip
-deken package -v$1 faust~
-rm -rf faust~
-rm -f faust_tilde_linux.zip
+rm -f faustgen_tilde_linux.zip
+curl -L "https://github.com/pierreguillot/faust-pd/releases/download/v$1/faustgen_tilde-Linux-amd64-32-sources.zip" -o faustgen_tilde_linux.zip
+tar zxvf faustgen_tilde_linux.zip
+deken package -v$1 faustgen~
+rm -rf faustgen~
+rm -f faustgen_tilde_linux.zip
-rm -f faust_tilde_windows.zip
-curl -L "https://github.com/pierreguillot/faust-pd/releases/download/v$1/faust_tilde-Windows-amd64-32-sources.zip" -o faust_tilde_windows.zip
-tar zxvf faust_tilde_windows.zip
-deken package -v$1 faust~
-rm -rf faust~
-rm -f faust_tilde_windows.zip
+rm -f faustgen_tilde_windows.zip
+curl -L "https://github.com/pierreguillot/faust-pd/releases/download/v$1/faustgen_tilde-Windows-amd64-32-sources.zip" -o faustgen_tilde_windows.zip
+tar zxvf faustgen_tilde_windows.zip
+deken package -v$1 faustgen~
+rm -rf faustgen~
+rm -f faustgen_tilde_windows.zip
-rm -f faust_tilde_archive.zip
-curl -L "https://github.com/pierreguillot/faust-pd/archive/v$1.zip" -o faust_tilde_archive.zip
-tar zxvf faust_tilde_archive.zip
-mv faust-pd-$1 faust~
-deken package -v$1 faust~
-rm -rf faust~
-rm -f faust_tilde_archive.zip
+rm -f faustgen_tilde_archive.zip
+curl -L "https://github.com/pierreguillot/faust-pd/archive/v$1.zip" -o faustgen_tilde_archive.zip
+tar zxvf faustgen_tilde_archive.zip
+mv faust-pd-$1 faustgen~
+deken package -v$1 faustgen~
+rm -rf faustgen~
+rm -f faustgen_tilde_archive.zip
-# deken upload faust~[v%release_version%](Darwin-amd64-32)(Sources).dek faust~[v%release_version%](Linux-amd64-32)(Sources).dek faust~[v%release_version%](Windows-amd64-32)(Sources).dek faust~[v%release_version%](Sources).dek
+# deken upload faustgen~[v%release_version%](Darwin-amd64-32)(Sources).dek faustgen~[v%release_version%](Linux-amd64-32)(Sources).dek faustgen~[v%release_version%](Windows-amd64-32)(Sources).dek faustgen~[v%release_version%](Sources).dek
diff --git a/FaustLib.cmake b/FaustLib.cmake
index 1927961..b59f20e 100644
--- a/FaustLib.cmake
+++ b/FaustLib.cmake
@@ -41,7 +41,7 @@ set(WASM_BACKEND OFF CACHE STRING "Include WASM ba
add_subdirectory(./faust/build EXCLUDE_FROM_ALL)
if(MSVC)
- set_property(TARGET staticlib APPEND_STRING PROPERTY COMPILE_FLAGS " /EHsc /D WIN32 -D_SCL_SECURE_NO_WARNINGS ")
+ set_property(TARGET staticlib APPEND_STRING PROPERTY COMPILE_FLAGS " /EHsc /D WIN32 -D_SCL_SECURE_NO_WARNINGS")
set_property(TARGET staticlib APPEND_STRING PROPERTY LINK_FLAGS " /ignore:4099 ")
endif()
diff --git a/README.md b/README.md
index 2bfb0b3..e2147c6 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
- faust~
+ faustgen~
The FAUST compiler embedded in a Pd external
@@ -15,7 +15,7 @@
## Presentation
-The **faust~** object is an external with the [FAUST](http://faust.grame.fr/about/) just-in-time (JIT) compiler embedded that allows to load, compile and play FAUST files within the audio programming environment [Pure Data](http://msp.ucsd.edu/software.html). FAUST (Functional Audio Stream) is a functional programming language specifically designed for real-time signal processing and synthesis developed by the [GRAME](http://www.grame.fr/). The FAUST JIT compiler - built with [LLVM](https://llvm.org/) - brings together the convenience of a standalone interpreted language with the efficiency of a compiled language. The **faust~** object is a very first version with elementary features, any help and any contribution are welcome.
+The **faustgen~** object is an external with the [FAUST](http://faust.grame.fr/about/) just-in-time (JIT) compiler embedded that allows to load, compile and play FAUST files within the audio programming environment [Pure Data](http://msp.ucsd.edu/software.html). FAUST (Functional Audio Stream) is a functional programming language specifically designed for real-time signal processing and synthesis developed by the [GRAME](http://www.grame.fr/). The FAUST JIT compiler - built with [LLVM](https://llvm.org/) - brings together the convenience of a standalone interpreted language with the efficiency of a compiled language. The **faustgen~** object is a very first version with elementary features, any help and any contribution are welcome.
**Dependencies:**
@@ -77,12 +77,12 @@ Once the binaries are compiled or uploaded with Travis and Appveyor to the relea
**FAUST website**: faust.grame.fr
**FAUST developers**: Yann Orlarey, Stéphane Letz, Dominique Fober and others
-**faust~ institutions**: CICM - ANR MUSICOLL
-**fauts~ website**: github.com/grame-cncm/faust-pd
-**faust~ developer**: Pierre Guillot
+**faustgen~ institutions**: CICM - ANR MUSICOLL
+**faustgen~ website**: github.com/grame-cncm/faust-pd
+**faustgen~ developer**: Pierre Guillot
## Legacy
-This **faust~** object for Pd is inspired by the **faustgen~** object for Max developed by Martin Di Rollo and Stéphane Letz.
+This **faustgen~** object for Pd is inspired by the **faustgen~** object for Max developed by Martin Di Rollo and Stéphane Letz.
Another **faust~** object has been developed by Albert Graef using the programming language [Pure](https://github.com/agraef/pure-lang).
diff --git a/ToDoList.md b/ToDoList.md
new file mode 100644
index 0000000..f3ccf75
--- /dev/null
+++ b/ToDoList.md
@@ -0,0 +1,4 @@
+- Mesure DSP time of the code
+- Use automatic optimizations with compile options
+- Check if the DSP process is in-place
+- Check why -double option crashes
diff --git a/appveyor.yml b/appveyor.yml
index 6dc8df2..73e3c02 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -23,7 +23,7 @@ install:
build_script:
- mkdir build%llvmplateform% && cd build%llvmplateform%
- cmake .. -G "%compiler%" -DUSE_LLVM_CONFIG=off -DLLVM_DIR=./llvm-windows-%llvmplateform%-%llvmpconfig%/lib/cmake/llvm
- - msbuild faust~.sln /nologo /p:config=%configuration% /p:plateform=%platform%
+ - msbuild faustgen~.sln /nologo /p:config=%configuration% /p:plateform=%platform%
after_build:
- cd %APPVEYOR_BUILD_FOLDER%
- del /F /Q llvm.zip
@@ -31,12 +31,12 @@ after_build:
- del /F /S /Q /A external\*.ilk
- del /F /S /Q /A external\*.lib
- del /F /S /Q /A external\*.exp
- - copy src\faust_tilde.c external\faust_tilde.c
+ - copy src\faustgen_tilde.c external\faustgen_tilde.c
- copy README.md external\README.md
- copy LICENSE external\LICENSE.txt
- xcopy /S /E /Y /I .\faust\libraries .\external\libs
- - rename external faust~
- - 7z a "faust_tilde-%release_arch%-sources.zip" faust~
+ - rename external faustgen~
+ - 7z a "faustgen_tilde-%release_arch%-sources.zip" faustgen~
artifacts:
- path: '*.zip'
diff --git a/external/examples/dummy.dsp b/external/examples/dummy.dsp
new file mode 100644
index 0000000..d5fed73
--- /dev/null
+++ b/external/examples/dummy.dsp
@@ -0,0 +1,6 @@
+declare name "Dummy";
+declare version "1.0";
+declare author "Heu... me...";
+
+
+process = _, _, _, _ :> _, _;
diff --git a/external/examples/gain.dsp b/external/examples/gain.dsp
new file mode 100644
index 0000000..90fb692
--- /dev/null
+++ b/external/examples/gain.dsp
@@ -0,0 +1,7 @@
+import("stdfaust.lib");
+
+process = _ * (gain)
+with
+{
+ gain = vslider("gain [unit:linear]", 0,0,1,0.001);
+};
diff --git a/external/examples/mixer.dsp b/external/examples/mixer.dsp
new file mode 100644
index 0000000..e0b8854
--- /dev/null
+++ b/external/examples/mixer.dsp
@@ -0,0 +1,7 @@
+declare name "mixer";
+declare version "1.0";
+declare author "Grame";
+declare license "BSD";
+declare copyright "(c)GRAME 2006";
+
+process = _;
diff --git a/external/examples/resonator.dsp b/external/examples/resonator.dsp
new file mode 100644
index 0000000..5ec6e8e
--- /dev/null
+++ b/external/examples/resonator.dsp
@@ -0,0 +1,11 @@
+import("stdfaust.lib");
+
+// Example programmed by Christophe Lebreton - GRAME
+
+f(i) = hslider("freq%3i", 160.,-0.,20000.,0.001);
+r(i) = hslider("decay%3i", 0.,0.,1.,0.001):((pow(4.78)*6)+0.0001):ba.tau2pole;
+g(i) = hslider("gain%3i", 0.,0.,1.,0.0001);
+
+resonator(n) = _<:par(i,n,*(g(i)):fi.nlf2(f(i),r(i)):_,!:*(ba.db2linear((100*(log(1/r(i))))))):>*(0.003162);
+
+process = resonator(20) ;
diff --git a/external/faust.watcher-help.pd b/external/faust.watcher-help.pd
deleted file mode 100644
index 0def173..0000000
--- a/external/faust.watcher-help.pd
+++ /dev/null
@@ -1,43 +0,0 @@
-#N canvas 436 64 481 520 10;
-#X obj 12 15 cnv 15 360 17 empty empty faust.watcher 2 9 0 14 -233017
--66577 0;
-#X obj 180 122 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
-1;
-#X obj 45 80 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
-;
-#X msg 45 172 reload;
-#X text 67 79 Start/Stop watching;
-#X text 198 122 Errors;
-#X obj 46 225 dac~;
-#X obj 45 204 faust~ noise;
-#X obj 45 101 faust.watcher noise 100;
-#X text 51 130 Bang when file has changed, f 17;
-#X text 94 169 Recompile the code when the file changed, f 22;
-#X text 9 36 The first argument is the name of the FAUST DSP file to
-watch. The second optional argument is the time in ms between each
-file check.;
-#X text 16 252 The abstraction sends a notification each time the FAUST
-DSP file is saved (modified). Activates the watching when coding your
-FAUST code in your favorite text editor to recompile automatically
-the code.;
-#X text 17 410 The abstraction uses the ggee library developed by Guenter
-Geiger. If you don't have the ggee library installed \, use Deken to
-download it.;
-#X text 17 460 This notification system has been inspired by the approach
-offered by the FAUST implementation for Pure Data developed by Albert
-Graef : https://github.com/agraef/pure-lang., f 69;
-#X text 168 16 a notifier of FAUST file changes;
-#X text 16 311 FAUST institution: GRAME;
-#X text 16 325 FAUST website: faust.grame.fr;
-#X text 122 340 Yann Orlarey \, Stéphane Letz \, Dominique Fober \,
-...;
-#X text 16 339 FAUST developers:;
-#X text 16 387 faust~ developer: Pierre Guillot;
-#X text 16 359 faust~ institutions: CICM - ANR MUSICOLL;
-#X text 16 373 fauts~ website: github.com/grame-cncm/faust-pd;
-#X connect 2 0 8 0;
-#X connect 3 0 7 0;
-#X connect 7 0 6 0;
-#X connect 7 0 6 1;
-#X connect 8 0 3 0;
-#X connect 8 1 1 0;
diff --git a/external/faust.watcher.pd b/external/faust.watcher.pd
deleted file mode 100644
index a4628f1..0000000
--- a/external/faust.watcher.pd
+++ /dev/null
@@ -1,47 +0,0 @@
-#N canvas 223 281 425 443 10;
-#X obj 147 16 loadbang;
-#X obj 174 128 makefilename %s/%%s.dsp;
-#X msg 174 149 set \$1;
-#X obj 174 170 makefilename;
-#X obj 243 255 outlet;
-#X obj 147 57 t b b;
-#X obj 147 83 symbol \$1;
-#X obj 21 8 inlet;
-#X obj 147 36 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
--1;
-#X msg 174 213 date -r \$1 +s%Y.%S.%m.%d.%H.%M.%S;
-#X obj 174 276 t s s;
-#X obj 174 255 symbol;
-#X obj 174 191 symbol;
-#X obj 201 350 outlet;
-#X obj 201 328 bang;
-#X obj 174 306 sel s;
-#X obj 174 107 ggee/getdir 1;
-#X obj 174 234 ggee/shell, f 12;
-#X obj 45 28 loadbang;
-#X obj 45 49 f \$2;
-#X obj 45 70 sel 0;
-#X obj 21 93 metro 100;
-#X connect 0 0 8 0;
-#X connect 1 0 2 0;
-#X connect 2 0 3 0;
-#X connect 3 0 12 0;
-#X connect 5 0 6 0;
-#X connect 5 1 16 0;
-#X connect 6 0 3 0;
-#X connect 7 0 21 0;
-#X connect 8 0 5 0;
-#X connect 9 0 17 0;
-#X connect 10 0 15 1;
-#X connect 10 1 15 0;
-#X connect 11 0 10 0;
-#X connect 12 0 9 0;
-#X connect 14 0 13 0;
-#X connect 15 1 14 0;
-#X connect 16 0 1 0;
-#X connect 17 0 11 0;
-#X connect 17 1 4 0;
-#X connect 18 0 19 0;
-#X connect 19 0 20 0;
-#X connect 20 1 21 1;
-#X connect 21 0 12 0;
diff --git a/external/faustgen~-help.pd b/external/faustgen~-help.pd
new file mode 100644
index 0000000..b9b35a2
--- /dev/null
+++ b/external/faustgen~-help.pd
@@ -0,0 +1,182 @@
+#N canvas 428 137 481 548 10;
+#X obj 12 15 cnv 15 360 17 empty empty faustgen~ 2 9 0 14 -233017 -66577
+0;
+#X obj 286 115 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X msg 286 135 \; pd dsp \$1;
+#X obj 32 308 dac~ 1 2;
+#X obj 62 192 nbx 5 14 0 1 0 0 empty empty empty 0 -8 0 10 -262144
+-1 -1 0 256;
+#X obj 62 149 loadbang;
+#X msg 62 171 0;
+#X text 10 36 The first argument is the name of the file FAUST DSP
+file to read. The path is relative to the patch. Extra arguments can
+be used to define compilation options \, see the FAUST documentation
+for further information. Use the debug level 3 to displays information
+about the code in the Pd console.;
+#X text 26 351 FAUST institution: GRAME;
+#X text 26 365 FAUST website: faust.grame.fr;
+#X text 132 380 Yann Orlarey \, Stéphane Letz \, Dominique Fober \,
+...;
+#X text 26 379 FAUST developers:;
+#X text 26 449 This object is inspired by faustgen~ for Max developed
+by Martin Di Rollo and Stéphane Letz., f 50;
+#X text 95 16 the FAUST compiler embedded in a Pd external;
+#X text 26 479 Another faust~ object has been developed by Albert Graef
+using the programming language "Pure" : https://github.com/agraef/pure-lang.
+, f 67;
+#X text 125 189 Control the parameters with their names, f 15;
+#X text 26 399 faustgen~ institutions: CICM - ANR MUSICOLL;
+#X text 26 427 faustgen~ developer: Pierre Guillot;
+#X msg 62 211 gain \$1;
+#X obj 32 118 osc~ 220;
+#N canvas 766 136 471 246 options 0;
+#X text 16 70 Change the compile options and recompile;
+#X msg 17 91 compileoptions -vec -vs 64;
+#X text 56 141 Use the compile options as default arguments;
+#X text 19 196 All the compile options are listed page 54 and page
+55 of the PDF file faust-quick-reference, f 46;
+#X text 21 27 Use the compile options to optimize the CPU or improve
+the redering, f 55;
+#X msg 41 115 print;
+#X text 84 116 Print faustgen~ informations;
+#X obj 405 65 switch~;
+#X obj 405 43 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 17 165 faustgen~ examples/gain -vec -lv 1;
+#X connect 1 0 9 0;
+#X connect 5 0 9 0;
+#X connect 8 0 7 0;
+#X restore 287 185 pd options;
+#N canvas 287 129 524 202 recompilation 0;
+#X obj 17 75 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
+;
+#X msg 17 134 autocompile \$1 100;
+#X obj 17 166 faustgen~ examples/dummy;
+#X text 14 11 The automatic compilation can be used during the Faust
+code edition to recompile the code each time the file has been modified.
+;
+#X text 50 62 Active/deactivate the autocompilation when the dsp file
+changed., f 37;
+#X text 50 92 The second argument is the time between each check.,
+f 37;
+#X msg 155 134 compile;
+#X text 214 128 Reload and recompile the FAUST file manually, f 23
+;
+#X obj 339 90 switch~;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 6 0 2 0;
+#X restore 287 214 pd recompilation;
+#N canvas 575 109 646 630 control 0;
+#X obj 30 598 dac~ 1 2;
+#X msg 45 195 print;
+#N canvas 0 22 450 278 (subpatch) 0;
+#X array \$0-gains 20 float 3;
+#A 0 0.706521 0.597826 0.521739 0.521739 0.521739 0.378572 0.442858
+0.528573 0.621431 0.685717 0.792861 0.921433 0.950004 0.950004 0.950004
+0.871432 0.792861 0.607145 0.578574 0.3;
+#X coords 0 1 20 0 199 92 1 0 0;
+#X restore 397 74 graph;
+#N canvas 0 22 450 278 (subpatch) 0;
+#X array \$0-decays 20 float 3;
+#A 0 0.0652173 0.0978258 0.119565 0.152173 0.206521 0.260868 0.326085
+0.402172 0.456519 0.521736 0.65217 0.706518 0.771735 0.804344 0.804344
+0.804344 0.771735 0.749996 0.66304 0.608692;
+#X coords 0 1 20 0 199 92 1 0 0;
+#X restore 397 198 graph;
+#N canvas 0 22 450 278 (subpatch) 0;
+#X array \$0-freq 20 float 3;
+#A 0 0.0652173 6956.52 6956.52 8260.87 9347.82 10434.8 11956.5 13478.2
+15000 16521.7 17608.7 18478.2 19130.4 18913 18260.8 14782.6 11304.3
+9347.82 8695.65 0.608692;
+#X coords 0 20000 20 0 199 92 1 0 0;
+#X restore 397 328 graph;
+#X obj 30 107 noise~;
+#X obj 30 525 faustgen~ examples/resonator;
+#X obj 119 177 list trim;
+#X obj 119 155 list prepend gain 0;
+#X obj 119 133 array get \$0-gains;
+#X obj 119 112 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X text 17 13 Use lists of values to control the lists of parameters.
+The first element of the list must be the name of the parameter \,
+the second argument is the index of the first parameters the other
+arguments are the list., f 44;
+#X obj 139 291 list trim;
+#X obj 139 227 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 139 248 array get \$0-decays 2 4;
+#X obj 139 270 list prepend decay 2;
+#X text 44 145 Print to display the parameters' information, f 11
+;
+#X obj 203 320 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X msg 203 362 freq 4 \$1;
+#X obj 203 341 array get \$0-decays 3 1;
+#X text 395 10 Change the value of the arrays and use the bangs to
+send them to the faustgen~ object, f 33;
+#X text 116 84 Set the values of all the "gain" parameters, f 23;
+#X text 137 199 Set the values of 4 "decay" parameters starting with
+the index 2, f 36;
+#X text 201 292 Set the value of the 3rd "freq" parameter, f 23;
+#X obj 201 481 list trim;
+#X obj 201 417 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 256 416 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
+-262144 -1 -1 0 256;
+#X obj 312 416 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
+-262144 -1 -1 0 256;
+#X obj 201 438 array get \$0-decays;
+#X obj 201 460 list prepend decay 0;
+#X text 199 388 Dynamic approach, f 9;
+#X text 254 398 Index;
+#X text 312 398 Size;
+#X obj 303 107 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X text 301 86 Turn DSP on;
+#X obj 303 128 switch~;
+#X connect 1 0 6 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
+#X connect 7 0 6 0;
+#X connect 8 0 7 0;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X connect 12 0 6 0;
+#X connect 13 0 14 0;
+#X connect 14 0 15 0;
+#X connect 15 0 12 0;
+#X connect 17 0 19 0;
+#X connect 18 0 6 0;
+#X connect 19 0 18 0;
+#X connect 24 0 6 0;
+#X connect 25 0 28 0;
+#X connect 26 0 28 1;
+#X connect 26 0 29 1;
+#X connect 27 0 28 2;
+#X connect 28 0 29 0;
+#X connect 29 0 24 0;
+#X connect 33 0 35 0;
+#X restore 287 243 pd control lists;
+#X obj 103 305 snapshot~;
+#X obj 103 326 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10
+-262144 -1 -1 0 256;
+#X obj 103 284 metro 100;
+#X obj 103 264 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 31 242 faustgen~ examples/gain;
+#X text 26 413 faustgen~ website: github.com/CICM/faust-pd;
+#X connect 1 0 2 0;
+#X connect 4 0 18 0;
+#X connect 5 0 6 0;
+#X connect 6 0 4 0;
+#X connect 18 0 27 0;
+#X connect 19 0 27 0;
+#X connect 23 0 24 0;
+#X connect 25 0 23 0;
+#X connect 26 0 25 0;
+#X connect 27 0 3 0;
+#X connect 27 0 3 1;
+#X connect 27 0 23 0;
diff --git a/external/faust~-help.pd b/external/faust~-help.pd
deleted file mode 100644
index 7b2479d..0000000
--- a/external/faust~-help.pd
+++ /dev/null
@@ -1,46 +0,0 @@
-#N canvas 364 281 470 537 10;
-#X obj 12 15 cnv 15 360 17 empty empty faust~ 2 9 0 14 -233017 -66577
-0;
-#X obj 286 155 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
-1;
-#X msg 286 175 \; pd dsp \$1;
-#X obj 32 308 dac~ 1 2;
-#X obj 32 255 faust~ noise;
-#X msg 62 208 reload;
-#X obj 32 158 nbx 5 14 0 1 0 0 empty empty empty 0 -8 0 10 -262144
--1 -1 0 256;
-#X msg 32 177 Volume \$1;
-#X obj 32 116 loadbang;
-#X msg 32 137 0;
-#X text 10 36 The first argument is the name of the file FAUST DSP
-file to read. The path is relative to the patch. Extra arguments can
-be used to define compilation options \, see the FAUST documentation
-for further information. Use the debug level 3 to displays information
-about the code in the Pd console.;
-#X obj 192 305 faust~ noise -vs 64 -vec;
-#X text 26 341 FAUST institution: GRAME;
-#X text 26 355 FAUST website: faust.grame.fr;
-#X text 132 370 Yann Orlarey \, Stéphane Letz \, Dominique Fober \,
-...;
-#X text 26 369 FAUST developers:;
-#X text 26 417 faust~ developer: Pierre Guillot;
-#X text 26 439 This object is inspired by faustgen~ for Max developed
-by Martin Di Rollo and Stéphane Letz., f 50;
-#X text 26 389 faust~ institutions: CICM - ANR MUSICOLL;
-#X text 192 256 Use compilation options. See the FAUST documentation
-for further information, f 24;
-#X text 95 16 the FAUST compiler embedded in a Pd external;
-#X text 26 403 fauts~ website: github.com/grame-cncm/faust-pd;
-#X text 26 469 Another faust~ object has been developed by Albert Graef
-using the programming language "Pure" : https://github.com/agraef/pure-lang.
-, f 67;
-#X text 95 155 Control the parameters with their names, f 15;
-#X text 113 206 Reload the FAUST file;
-#X connect 1 0 2 0;
-#X connect 4 0 3 0;
-#X connect 4 0 3 1;
-#X connect 5 0 4 0;
-#X connect 6 0 7 0;
-#X connect 7 0 4 0;
-#X connect 8 0 9 0;
-#X connect 9 0 6 0;
diff --git a/external/noise.dsp b/external/noise.dsp
deleted file mode 100644
index 8544f4a..0000000
--- a/external/noise.dsp
+++ /dev/null
@@ -1,52 +0,0 @@
-// WARNING: This a "legacy example based on a deprecated library". Check noises.lib
-// for more accurate examples of noise functions
-
-declare name "Noise";
-declare version "1.1";
-declare author "Grame";
-declare license "BSD";
-declare copyright "(c)GRAME 2009";
-
-//-----------------------------------------------------------------
-// Noise generator and demo file for the Faust math documentation
-//-----------------------------------------------------------------
-
-
-\section{Presentation of the "noise.dsp" Faust program}
-This program describes a white noise generator with an interactive volume, using a random function.
-
-\subsection{The random function}
-The \texttt{random} function describes a generator of random numbers, which equation follows. You should notice hereby the use of an integer arithmetic on 32 bits, relying on integer wrapping for big numbers.
-random
-
-\subsection{The noise function}
-The white noise then corresponds to:
-noise
-
-
-random = +(12345)~*(1103515245);
-noise = random/2147483647.0;
-
-
-\subsection{Just add a user interface element to play volume!}
-Endly, the sound level of this program is controlled by a user slider, which gives the following equation:
-process
-
-
-
-\section{Block-diagram schema of process}
-This process is illustrated on figure 1.
-process
-
-
-process = noise * vslider("Volume[style:knob][acc: 0 0 -10 0 10]", 0.5, 0, 1, 0.1);
-
-
-\section{Notice of this documentation}
-You might be careful of certain information and naming conventions used in this documentation:
-
-
-\section{Listing of the input code}
-The following listing shows the input Faust code, parsed to compile this mathematical documentation.
-
-
diff --git a/faust b/faust
index 3b7e311..2b54fef 160000
--- a/faust
+++ b/faust
@@ -1 +1 @@
-Subproject commit 3b7e311c6a25f55ffc9ec282ecb746618a344855
+Subproject commit 2b54fef899f84c31e0874fd19292f787bb7b4b19
diff --git a/pd.build b/pd.build
index 5365682..ed7591e 160000
--- a/pd.build
+++ b/pd.build
@@ -1 +1 @@
-Subproject commit 53656824ee7977f0084a801208effe20e640c8f5
+Subproject commit ed7591eecb239970158bd2fa2550b63280a16e2d
diff --git a/pure-data b/pure-data
index f83c88b..f9b0ad8 160000
--- a/pure-data
+++ b/pure-data
@@ -1 +1 @@
-Subproject commit f83c88ba7ac68368248797ef0d0febc3526432bb
+Subproject commit f9b0ad81387d4af3091857dc16852e221fe96310
diff --git a/src/faust_tilde.c b/src/faust_tilde.c
deleted file mode 100644
index 66687d6..0000000
--- a/src/faust_tilde.c
+++ /dev/null
@@ -1,809 +0,0 @@
-/*
-// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
-// For information on usage and redistribution, and for a DISCLAIMER OF ALL
-// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
-*/
-
-#include
-
-#include
-#include
-
-#include
-
-#define MAXFAUSTSTRING 4096
-#define MAXFAUSTOPTIONS 128
-
-typedef struct _faust_param
-{
- t_symbol* p_label;
- int p_type;
- FAUSTFLOAT* p_zone;
- FAUSTFLOAT p_min;
- FAUSTFLOAT p_max;
- FAUSTFLOAT p_step;
- FAUSTFLOAT p_saved;
-}t_faust_param;
-
-typedef struct _faust_tilde
-{
- t_object f_obj;
- llvm_dsp_factory* f_dsp_factory;
- llvm_dsp* f_dsp_instance;
- size_t f_nsignals;
- t_sample** f_signals;
- t_float f_f;
-
- MetaGlue f_meta_glue;
- UIGlue f_ui_glue;
- size_t f_nparams;
- t_faust_param* f_params;
-
- t_canvas* f_canvas;
- t_symbol* f_dsp_name;
-
- size_t f_ncompile_options;
- char* f_compile_options[MAXFAUSTOPTIONS];
-
- size_t f_ninlets;
- t_inlet** f_inlets;
- size_t f_noutlets;
- t_outlet** f_outlets;
- char f_allocated;
-} t_faust_tilde;
-
-static t_class *faust_tilde_class;
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-// PURE DATA IO DYNAMIC //
-//////////////////////////////////////////////////////////////////////////////////////////////////
-static void faust_tilde_free_ioputs(t_faust_tilde *x)
-{
- if(x->f_inlets)
- {
- freebytes(x->f_inlets, sizeof(t_inlet*) * x->f_ninlets);
- x->f_inlets = NULL;
- x->f_ninlets = 0;
- }
- if(x->f_outlets)
- {
- freebytes(x->f_outlets, sizeof(t_outlet*) * x->f_noutlets);
- x->f_outlets = NULL;
- x->f_noutlets = 0;
- }
- if(x->f_signals)
- {
- freebytes(x->f_signals, sizeof(t_sample*) * x->f_nsignals);
- x->f_signals = NULL;
- x->f_nsignals = 0;
- }
-}
-
-static char faust_tilde_resize_inputs(t_faust_tilde *x, int const nins)
-{
- t_inlet** ninlets;
- size_t i;
- size_t const cins = x->f_ninlets > 1 ? x->f_ninlets : 1;
- size_t const rnins = (size_t)nins > 1 ? (size_t)nins : 1;
- if(rnins == cins)
- {
- return 0;
- }
- for(i = rnins; i < cins; ++i)
- {
- inlet_free(x->f_inlets[i]);
- x->f_inlets[i] = NULL;
- }
- ninlets = (t_inlet **)resizebytes(x->f_inlets, sizeof(t_inlet*) * cins, sizeof(t_inlet*) * rnins);
- if(ninlets)
- {
- for(i = cins; i < rnins; ++i)
- {
- ninlets[i] = signalinlet_new((t_object *)x, 0);
- }
- x->f_inlets = ninlets;
- x->f_ninlets = rnins;
- return 0;
- }
- pd_error(x, "faust~: memory allocation failed - inputs");
- return 1;
-}
-
-static char faust_tilde_resize_outputs(t_faust_tilde *x, int const nins)
-{
- t_outlet** noutlets;
- size_t i;
- size_t const couts = x->f_noutlets;
- size_t const rnouts = (size_t)nins > 0 ? (size_t)nins : 0;
- if(rnouts == couts)
- {
- return 0;
- }
- for(i = rnouts; i < couts; ++i)
- {
- outlet_free(x->f_outlets[i]);
- x->f_outlets[i] = NULL;
- }
- noutlets = (t_outlet **)resizebytes(x->f_outlets, sizeof(t_outlet*) * couts, sizeof(t_outlet*) * rnouts);
- if(noutlets)
- {
- for(i = couts; i < rnouts; ++i)
- {
- noutlets[i] = outlet_new((t_object *)x, &s_signal);
- }
- x->f_outlets = noutlets;
- x->f_noutlets = rnouts;
- return 0;
- }
- pd_error(x, "faust~: memory allocation failed - outputs");
- return 1;
-}
-
-static char faust_tilde_resize_ioputs(t_faust_tilde *x, int const nins, int const nouts)
-{
- char valid = 0;
- t_sample** nsignals;
- int const redraw = (x->f_canvas && glist_isvisible(x->f_canvas) && (!x->f_canvas->gl_isdeleting)
- && glist_istoplevel(x->f_canvas) && x->f_allocated);
- if(redraw)
- {
- gobj_vis((t_gobj *)x, x->f_canvas, 0);
- }
- valid = faust_tilde_resize_inputs(x, nins) ? 1 : valid;
- valid = faust_tilde_resize_outputs(x, nouts) ? 1 : valid;
- nsignals = (t_sample **)resizebytes(x->f_signals,
- x->f_nsignals * sizeof(t_sample *),
- (x->f_noutlets + x->f_ninlets) * sizeof(t_sample *));
-
- if(nsignals)
- {
- x->f_nsignals = x->f_noutlets + x->f_ninlets;
- x->f_signals = nsignals;
- }
- else
- {
- pd_error(x, "faust~: memory allocation failed - signals");
- valid = 1;
- }
- if(redraw)
- {
- gobj_vis((t_gobj *)x, x->f_canvas, 1);
- canvas_fixlinesfor(x->f_canvas, (t_text *)x);
- }
- return valid;
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-// FILE LOCALIZATION //
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-static char* faust_tilde_get_dsp_file_path(t_faust_tilde *x)
-{
- if(x->f_canvas)
- {
- t_symbol const* name = x->f_dsp_name;
- t_symbol const* path = canvas_getdir(x->f_canvas);
- if(path && path->s_name && name && name->s_name)
- {
- char* file = (char *)calloc(MAXFAUSTSTRING, sizeof(char));
- if(file)
- {
- sprintf(file, "%s/%s.dsp", path->s_name, name->s_name);
- return file;
- }
- else
- {
- pd_error(x, "faust~: memory allocation failed");
- }
- }
- else
- {
- pd_error(x, "faust~: invalid canvas directory or DSP file name");
- }
- }
- else
- {
- pd_error(x, "faust~: invalid canvas");
- }
- return NULL;
-}
-
-static char* faust_tilde_get_default_include_path(t_faust_tilde *x)
-{
- char const* path = class_gethelpdir(faust_tilde_class);
- if(path)
- {
- char* include_path = (char *)calloc(MAXFAUSTSTRING, sizeof(char));
- if(include_path)
- {
- sprintf(include_path, "%s/libs/", path);
- return include_path;
- }
- else
- {
- pd_error(x, "faust~: memory allocation failed - include path");
- }
- }
- else
- {
- pd_error(x, "faust~: cannot locate the include path");
- }
- return NULL;
-}
-
-static int faust_tilde_parse_compile_options(t_faust_tilde *x, int argc, t_atom* argv)
-{
- int i = 0;
- char has_include = 0;
- for(i = 0; i < argc && i < MAXFAUSTOPTIONS; ++i)
- {
- x->f_compile_options[i] = (char *)calloc(MAXFAUSTSTRING, sizeof(char));
- if(x->f_compile_options[i])
- {
- if(argv[i].a_type == A_FLOAT)
- {
- sprintf(x->f_compile_options[i], "%i", (int)argv[i].a_w.w_float);
- }
- else if(argv[i].a_type == A_SYMBOL && argv[i].a_w.w_symbol)
- {
- sprintf(x->f_compile_options[i], "%s", argv[i].a_w.w_symbol->s_name);
- if(!strncmp(x->f_compile_options[i], "-I", 2))
- {
- has_include = 1;
- }
- }
- else
- {
- pd_error(x, "faust~: option type invalid");
- memset(x->f_compile_options[i], 0, MAXFAUSTSTRING);
- }
- x->f_ncompile_options = i+1;
- }
- else
- {
- pd_error(x, "faust~: memory allocation failed - compile option");
- x->f_ncompile_options = i;
- return -1;
- }
- }
- if(!has_include)
- {
- x->f_compile_options[i] = (char *)calloc(MAXFAUSTSTRING, sizeof(char));
- if(x->f_compile_options[i])
- {
- sprintf(x->f_compile_options[i], "%s", "-I");
- }
- else
- {
- pd_error(x, "faust~: memory allocation failed - compile option");
- x->f_ncompile_options = i;
- return -1;
- }
- ++i;
- x->f_compile_options[i] = faust_tilde_get_default_include_path(x);
- if(!x->f_compile_options[i])
- {
- pd_error(x, "faust~: memory allocation failed - compile option");
- x->f_ncompile_options = i;
- return -1;
- }
- x->f_ncompile_options = i+1;
- }
- return 0;
-}
-
-static void faust_tilde_free_compile_options(t_faust_tilde *x)
-{
- if(x->f_compile_options)
- {
- size_t i;
- for(i = 0; i < x->f_ncompile_options; ++i)
- {
- if(x->f_compile_options[i])
- {
- free(x->f_compile_options[i]);
- }
- }
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-// FAUST INTERFACE //
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-static void faust_tilde_delete_instance(t_faust_tilde *x)
-{
- if(x->f_dsp_instance)
- {
- deleteCDSPInstance(x->f_dsp_instance);
- x->f_dsp_instance = NULL;
- }
-}
-
-static void faust_tilde_delete_factory(t_faust_tilde *x)
-{
- if(x->f_dsp_factory)
- {
- faust_tilde_delete_instance(x);
- deleteCDSPFactory(x->f_dsp_factory);
- x->f_dsp_factory = NULL;
- }
-}
-
-static void faust_tilde_ui_open_tab_box(t_faust_tilde* x, const char* label)
-{
- //pd_error(x, "faust~: open tab box not supported yet (%s)", label);
-}
-
-static void faust_tilde_ui_open_horizontal_box(t_faust_tilde* x, const char* label)
-{
- //pd_error(x, "faust~: open horizontal box not supported yet (%s)", label);
-}
-
-static void faust_tilde_ui_open_vertical_box(t_faust_tilde* x, const char* label)
-{
- //pd_error(x, "faust~: open vertical box not supported yet (%s)", label);
-}
-
-static void faust_tilde_ui_close_box(t_faust_tilde* x)
-{
- //pd_error(x, "faust~: close box not supported yet");
-}
-
-
-
-static void faust_tilde_delete_params(t_faust_tilde *x)
-{
- if(x->f_params)
- {
- freebytes(x->f_params, x->f_nparams * sizeof(t_faust_param));
- x->f_params = NULL;
- x->f_nparams = 0;
- }
-}
-
-static void faust_tilde_save_params(t_faust_tilde *x)
-{
- size_t i;
- for(i = 0; i < x->f_nparams; ++i)
- {
- x->f_params[i].p_saved = *x->f_params[i].p_zone;
- }
-}
-
-static void faust_tilde_restore_params(t_faust_tilde *x)
-{
- size_t i;
- for(i = 0; i < x->f_nparams; ++i)
- {
- *x->f_params[i].p_zone = x->f_params[i].p_saved;
- }
-}
-
-static void faust_tilde_add_params(t_faust_tilde *x, const char* label, int const type, FAUSTFLOAT* zone,
- FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
-{
- t_faust_param *newmemory;
- size_t size = x->f_nparams;
- if(x->f_params)
- {
- newmemory = (t_faust_param *)resizebytes(x->f_params, size * sizeof(t_faust_param), (size + 1) * sizeof(t_faust_param));
- if(!newmemory)
- {
- pd_error(x, "faust~: memory allocation failed - parameter");
- return;
- }
- }
- else
- {
- newmemory = (t_faust_param *)getbytes(sizeof(t_faust_param));
- if(!newmemory)
- {
- pd_error(x, "faust~: memory allocation failed - parameter");
- return;
- }
- }
- if(strnlen(label, MAXFAUSTSTRING) == 0 || label[0] == '0')
- {
- char temp[MAXFAUSTSTRING];
- sprintf(temp, "param%i", (int)size+1);
- newmemory[size].p_label = gensym(temp);
- logpost(x, 3, "faust~: parameter has no label, empty string replace with '%s'", temp);
- }
- else
- {
- newmemory[size].p_label = gensym(label);
- }
- newmemory[size].p_type = type;
- newmemory[size].p_zone = zone;
- newmemory[size].p_min = min;
- newmemory[size].p_max = max;
- newmemory[size].p_step = step;
- *newmemory[size].p_zone = init;
- x->f_params = (t_faust_param *)newmemory;
- x->f_nparams++;
-}
-
-static void faust_tilde_ui_add_button(t_faust_tilde* x, const char* label, FAUSTFLOAT* zone)
-{
- faust_tilde_add_params(x, label, 0, zone, 0, 0, 0, 0);
-}
-
-static void faust_tilde_ui_add_check_button(t_faust_tilde* x, const char* label, FAUSTFLOAT* zone)
-{
- faust_tilde_add_params(x, label, 1, zone,0, 0, 1, 1);
-}
-
-static void faust_tilde_ui_add_vertical_slider(t_faust_tilde* x, const char* label, FAUSTFLOAT* zone,
- FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
-{
- faust_tilde_add_params(x, label, 2, zone, init, min, max, step);
-}
-
-static void faust_tilde_ui_add_horizontal_slider(t_faust_tilde* x, const char* label, FAUSTFLOAT* zone,
- FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
-{
- faust_tilde_add_params(x, label, 2, zone, init, min, max, step);
-}
-
-static void faust_tilde_ui_add_number_entry(t_faust_tilde* x, const char* label, FAUSTFLOAT* zone,
- FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
-{
- faust_tilde_add_params(x, label, 2, zone, init, min, max, step);
-}
-
-
-
-
-static void faust_tilde_ui_add_horizontal_bargraph(t_faust_tilde* x, const char* label,
- FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
-{
- pd_error(x, "faust~: add horizontal bargraph not supported yet");
-}
-
-static void faust_tilde_ui_add_vertical_bargraph(t_faust_tilde* x, const char* label,
- FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
-{
- pd_error(x, "faust~: add vertical bargraph not supported yet");
-}
-
-static void faust_tilde_ui_add_sound_file(t_faust_tilde* x, const char* label, const char* filename, struct Soundfile** sf_zone)
-{
- pd_error(x, "faust~: add sound file not supported yet");
-}
-
-static void faust_tilde_ui_declare(t_faust_tilde* x, FAUSTFLOAT* zone, const char* key, const char* value)
-{
- //pd_error(x, "faust~: ui declare %s: %s", key, value);
-}
-
-
-
-
-static void faust_tilde_meta_declare(t_faust_tilde* x, const char* key, const char* value)
-{
- logpost(x, 3, " %s: %s", key, value);
-}
-
-static void faust_tilde_print(t_faust_tilde *x)
-{
- size_t i;
- startpost("faust~: compile options\n");
- for(i = 0; i < x->f_ncompile_options; i++)
- {
- poststring(x->f_compile_options[i]);
- }
- endpost();
-}
-
-static void faust_tilde_reload(t_faust_tilde *x)
-{
- int dspstate = canvas_suspend_dsp();
- char* filepath = faust_tilde_get_dsp_file_path(x);
- if(filepath)
- {
- char errors[MAXFAUSTSTRING];
- faust_tilde_delete_instance(x);
- faust_tilde_delete_factory(x);
- faust_tilde_delete_params(x);
-
- x->f_dsp_factory = createCDSPFactoryFromFile(filepath,
- (int)x->f_ncompile_options, (const char**)x->f_compile_options,
- "", errors, -1);
- if(strnlen(errors, MAXFAUSTSTRING))
- {
- pd_error(x, "faust~: try to load %s", filepath);
- size_t i;
- for (i = 0; i < x->f_ncompile_options; ++i)
- {
- if(x->f_compile_options[i])
- {
- pd_error(x, "faust~: option %s", x->f_compile_options[i]);
- }
- }
- pd_error(x, "faust~: %s", errors);
- x->f_dsp_factory = NULL;
- }
- else
- {
- x->f_dsp_instance = createCDSPInstance(x->f_dsp_factory);
- if(x->f_dsp_instance)
- {
- if(!faust_tilde_resize_ioputs(x,
- getNumInputsCDSPInstance(x->f_dsp_instance),
- getNumOutputsCDSPInstance(x->f_dsp_instance)))
- {
- logpost(x, 3, "\nfaust~: compilation from source '%s' succeeded", x->f_dsp_name->s_name);
- metadataCDSPInstance(x->f_dsp_instance, &x->f_meta_glue);
- buildUserInterfaceCDSPInstance(x->f_dsp_instance, &x->f_ui_glue);
-
- logpost(x, 3, " %s: %i", "number of inputs",
- getNumInputsCDSPInstance(x->f_dsp_instance));
- logpost(x, 3, " %s: %i", "number of outputs",
- getNumOutputsCDSPInstance(x->f_dsp_instance));
- size_t i;
- for (i = 0; i < x->f_nparams; ++i)
- {
- logpost(x, 3, " parameter %i: %s", (int)i, x->f_params[i].p_label->s_name);
- }
- }
-
- }
- else
- {
- pd_error(x, "faust~: memory allocation failed - instance");
- }
- }
- free(filepath);
- }
- else
- {
- pd_error(x, "faust~: source file not defined");
- }
- canvas_resume_dsp(dspstate);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////////////
-// PURE DATA GENERIC INTERFACE //
-//////////////////////////////////////////////////////////////////////////////////////////////////
-
-static void faust_tilde_anything(t_faust_tilde *x, t_symbol* s, int argc, t_atom* argv)
-{
- t_float value;
- if(x->f_dsp_instance)
- {
- size_t i;
- for(i = 0; i < x->f_nparams; ++i)
- {
- if(x->f_params[i].p_label == s)
- {
- if(x->f_params[i].p_type == 0)
- {
- *x->f_params[i].p_zone = !(*x->f_params[i].p_zone != 0.f);
- if(argc)
- {
- pd_error(x, "faust~: parameter '%s' too many arguments: 0 expected", s->s_name);
- }
- }
- else if(x->f_params[i].p_type == 1)
- {
- if(argc < 1 || argv[0].a_type != A_FLOAT)
- {
- pd_error(x, "faust~: parameter '%s' wrong arguments: 0 expected", s->s_name);
- return;
- }
- *x->f_params[i].p_zone = argv[0].a_w.w_float != 0.f;
- if(argc > 1)
- {
- pd_error(x, "faust~: parameter '%s' too many arguments: 1 float expected", s->s_name);
- }
- }
- else if(x->f_params[i].p_type == 2)
- {
- if(argc < 1 || argv[0].a_type != A_FLOAT)
- {
- pd_error(x, "faust~: parameter '%s' wrong arguments: 0 expected", s->s_name);
- return;
- }
- value = argv[0].a_w.w_float;
- value = value > x->f_params[i].p_min ? value : x->f_params[i].p_min;
- value = value < x->f_params[i].p_max ? value : x->f_params[i].p_max;
- *x->f_params[i].p_zone = value;
- if(argc > 1)
- {
- pd_error(x, "faust~: parameter '%s' too many arguments: 1 float expected", s->s_name);
- }
- }
- else
- {
- pd_error(x, "faust~: wrong parameter '%s'", s->s_name);
- }
- return;
- }
- }
- pd_error(x, "faust~: parameter '%s' not defined", s->s_name);
- }
-}
-
-static void faust_tilde_bang(t_faust_tilde *x, t_float f)
-{
- faust_tilde_anything(x, &s_, 0, NULL);
-}
-
-static void faust_tilde_symbol(t_faust_tilde *x, t_symbol* s)
-{
- faust_tilde_anything(x, s, 0, NULL);
-}
-
-static void faust_tilde_list(t_faust_tilde *x, t_symbol* s, int argc, t_atom* argv)
-{
- faust_tilde_anything(x, s, argc, argv);
-}
-
-static t_int *faust_tilde_perform(t_int *w)
-{
- computeCDSPInstance((llvm_dsp *)w[1], (int)w[2], (float **)w[3], (float **)w[4]);
- return (w+5);
-}
-
-static char faust_tilde_is_valid(t_faust_tilde *x)
-{
- size_t fnins, fnouts;
- if(!x->f_dsp_instance)
- {
- return -1;
- }
- fnins = (size_t)getNumInputsCDSPInstance(x->f_dsp_instance);
- fnouts = (size_t)getNumOutputsCDSPInstance(x->f_dsp_instance);
- if(fnins == 0)
- fnins = 1;
- if(fnins != x->f_ninlets)
- {
- pd_error(x, "faust~: number of inlets is invalid");
- return -1;
- }
- if(fnouts!= x->f_noutlets)
- {
- pd_error(x, "faust~: number of outlets is invalid");
- return -1;
- }
- if(x->f_nsignals != x->f_ninlets + x->f_ninlets)
- {
- pd_error(x, "faust~: number of signals is invalid");
- return -1;
- }
- if(!x->f_signals)
- {
- pd_error(x, "faust~: signals are not allocated");
- return -1;
- }
- return 0;
-}
-
-static void faust_tilde_dsp(t_faust_tilde *x, t_signal **sp)
-{
- if(!faust_tilde_is_valid(x))
- {
- size_t i;
- size_t const ninlets = x->f_ninlets;
- size_t const noutlets = x->f_noutlets;
- faust_tilde_save_params(x);
- initCDSPInstance(x->f_dsp_instance, sp[0]->s_sr);
- for(i = 0; i < ninlets + noutlets; ++i)
- {
- x->f_signals[i] = sp[i]->s_vec;
- }
- dsp_add((t_perfroutine)faust_tilde_perform, 4,
- (t_int)x->f_dsp_instance, (t_int)sp[0]->s_n, (t_int)x->f_signals, (t_int)(x->f_signals+ninlets));
- faust_tilde_restore_params(x);
- }
-}
-
-static void faust_tilde_free(t_faust_tilde *x)
-{
- faust_tilde_delete_instance(x);
- faust_tilde_delete_factory(x);
- faust_tilde_delete_params(x);
- faust_tilde_free_compile_options(x);
- faust_tilde_free_ioputs(x);
-}
-
-static void *faust_tilde_new(t_symbol* s, int argc, t_atom* argv)
-{
- t_faust_tilde* x = (t_faust_tilde *)pd_new(faust_tilde_class);
- if(x)
- {
- size_t i;
- x->f_dsp_factory = NULL;
- x->f_dsp_instance = NULL;
- x->f_nsignals = 0;
- x->f_signals = NULL;
- x->f_f = 0;
-
- x->f_meta_glue.metaInterface = x;
- x->f_meta_glue.declare = (metaDeclareFun)faust_tilde_meta_declare;
-
- x->f_ui_glue.uiInterface = x;
- x->f_ui_glue.openTabBox = (openTabBoxFun)faust_tilde_ui_open_tab_box;
- x->f_ui_glue.openHorizontalBox = (openHorizontalBoxFun)faust_tilde_ui_open_horizontal_box;
- x->f_ui_glue.openVerticalBox = (openVerticalBoxFun)faust_tilde_ui_open_vertical_box;
- x->f_ui_glue.closeBox = (closeBoxFun)faust_tilde_ui_close_box;
-
- x->f_ui_glue.addButton = (addButtonFun)faust_tilde_ui_add_button;
- x->f_ui_glue.addCheckButton = (addCheckButtonFun)faust_tilde_ui_add_check_button;
- x->f_ui_glue.addVerticalSlider = (addVerticalSliderFun)faust_tilde_ui_add_vertical_slider;
- x->f_ui_glue.addHorizontalSlider = (addHorizontalSliderFun)faust_tilde_ui_add_horizontal_slider;
- x->f_ui_glue.addNumEntry = (addNumEntryFun)faust_tilde_ui_add_number_entry;
-
- x->f_ui_glue.addHorizontalBargraph = (addHorizontalBargraphFun)faust_tilde_ui_add_horizontal_bargraph;
- x->f_ui_glue.addVerticalBargraph = (addVerticalBargraphFun)faust_tilde_ui_add_vertical_bargraph;
- x->f_ui_glue.addSoundFile = (addSoundFileFun)faust_tilde_ui_add_sound_file;
- x->f_ui_glue.declare = (declareFun)faust_tilde_ui_declare;
-
- x->f_nparams = 0;
- x->f_params = NULL;
-
- x->f_canvas = canvas_getcurrent();
- x->f_dsp_name = atom_getsymbolarg(0, argc, argv);
-
- x->f_ncompile_options = 0;
- for(i = 0; i < MAXFAUSTOPTIONS; ++i)
- {
- x->f_compile_options[i] = NULL;
- }
- x->f_ninlets = 1;
- x->f_inlets = NULL;
- x->f_noutlets = 0;
- x->f_outlets = NULL;
- x->f_allocated = 0;
-
- if(argc == 0 || argv == NULL)
- {
- return x;
- }
- if(faust_tilde_parse_compile_options(x, argc-1, argv+1))
- {
- faust_tilde_free(x);
- return NULL;
- }
- faust_tilde_reload(x);
- x->f_allocated = 1;
- if(!x->f_dsp_instance)
- {
- faust_tilde_free(x);
- return NULL;
- }
- }
- return x;
-}
-
-void faust_tilde_setup(void)
-{
- t_class* c = class_new(gensym("faust~"),
- (t_newmethod)faust_tilde_new, (t_method)faust_tilde_free,
- sizeof(t_faust_tilde), CLASS_DEFAULT, A_GIMME, 0);
- if(c)
- {
- class_addmethod(c, (t_method)faust_tilde_dsp, gensym("dsp"), A_CANT);
- class_addmethod(c, (t_method)faust_tilde_reload, gensym("reload"), A_NULL);
- class_addmethod(c, (t_method)faust_tilde_print, gensym("print"), A_NULL);
- class_addbang(c, (t_method)faust_tilde_bang);
- class_addsymbol(c, (t_method)faust_tilde_symbol);
- class_addlist(c, (t_method)faust_tilde_list);
- class_addanything(c, (t_method)faust_tilde_anything);
-
- CLASS_MAINSIGNALIN(c, t_faust_tilde, f_f);
-
- logpost(NULL, 3, "Faust website: faust.grame.fr");
- logpost(NULL, 3, "Faust development: GRAME");
-
- logpost(NULL, 3, "faust~ compiler version: %s", getCLibFaustVersion());
- logpost(NULL, 3, "faust~ include directory: %s", class_gethelpdir(c));
- logpost(NULL, 3, "faust~ institutions: CICM - ANR MUSICOLL");
- logpost(NULL, 3, "faust~ external author: Pierre Guillot");
- logpost(NULL, 3, "faust~ website: github.com/grame-cncm/faust-pd");
- }
-
- faust_tilde_class = c;
-}
-
diff --git a/src/faust_tilde_io.c b/src/faust_tilde_io.c
new file mode 100644
index 0000000..eeb35ca
--- /dev/null
+++ b/src/faust_tilde_io.c
@@ -0,0 +1,327 @@
+/*
+// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+*/
+
+
+#include "faust_tilde_io.h"
+#include
+#include
+
+typedef struct _faust_io_manager
+{
+ t_object* f_owner;
+ t_canvas* f_canvas;
+
+ size_t f_nsignals;
+ t_sample** f_signals;
+
+ size_t f_ninlets;
+ t_inlet** f_inlets;
+
+ size_t f_noutlets;
+ t_outlet** f_outlets;
+ t_outlet* f_extra_outlet;
+
+ char f_valid;
+}t_faust_io_manager;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// PURE DATA IO DYNAMIC //
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// FREE METHODS
+//////////////////////////////////////////////////////////////////////////////////////////////////
+static void faust_io_manager_free_signals(t_faust_io_manager *x)
+{
+ if(x->f_signals)
+ {
+ freebytes(x->f_signals, sizeof(t_sample*) * x->f_nsignals);
+ }
+ x->f_signals = NULL;
+ x->f_nsignals = 0;
+}
+
+static void faust_io_manager_free_inputs(t_faust_io_manager *x)
+{
+ if(x->f_inlets && x->f_ninlets)
+ {
+ freebytes(x->f_inlets, sizeof(t_inlet*) * x->f_ninlets);
+ }
+ x->f_inlets = NULL;
+ x->f_ninlets = 0;
+}
+
+static void faust_io_manager_free_outputs(t_faust_io_manager *x)
+{
+ if(x->f_outlets && x->f_noutlets)
+ {
+ freebytes(x->f_outlets, sizeof(t_outlet*) * x->f_noutlets);
+ }
+ x->f_outlets = NULL;
+ x->f_noutlets = 0;
+}
+
+// ALLOCATE-RESIZE METHODS
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static char faust_io_manager_resize_signals(t_faust_io_manager *x, size_t nsignals)
+{
+ t_sample** nsigs;
+ if(x->f_nsignals == nsignals)
+ {
+ return 0;
+ }
+ nsigs = (t_sample **)resizebytes(x->f_signals, x->f_nsignals * sizeof(t_sample*), nsignals * sizeof(t_sample*));
+ if(nsigs)
+ {
+ x->f_nsignals = nsignals;
+ x->f_signals = nsigs;
+ return 0;
+ }
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - signals");
+ return 4;
+}
+
+static char faust_io_manager_resize_inputs(t_faust_io_manager *x, size_t const nins)
+{
+ t_inlet** ninlets;
+ size_t i;
+ size_t const cins = faust_io_manager_get_ninputs(x);
+ size_t const rnins = nins;
+ if(rnins == cins)
+ {
+ return 0;
+ }
+ for(i = cins; i > rnins; --i)
+ {
+ inlet_free(x->f_inlets[i-1]);
+ x->f_inlets[i-1] = NULL;
+ }
+ ninlets = (t_inlet **)resizebytes(x->f_inlets, sizeof(t_inlet*) * cins, sizeof(t_inlet*) * rnins);
+ if(ninlets)
+ {
+ for(i = cins; i < rnins; ++i)
+ {
+ ninlets[i] = signalinlet_new((t_object *)x->f_owner, 0);
+ if(!ninlets[i])
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - input %i", (int)i);
+ }
+ }
+ x->f_inlets = ninlets;
+ x->f_ninlets = rnins;
+ return 0;
+ }
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - inputs");
+ return 2;
+}
+
+static char faust_io_manager_resize_outputs(t_faust_io_manager *x, size_t const nouts, char const extraout)
+{
+ t_outlet** noutlets;
+ size_t i;
+ size_t const couts = faust_io_manager_get_noutputs(x);
+ size_t const rnouts = nouts;
+
+ if(rnouts == couts)
+ {
+ if(faust_io_manager_has_extra_output(x) && !extraout)
+ {
+ outlet_free(x->f_extra_outlet);
+ x->f_extra_outlet = NULL;
+ return 0;
+ }
+ else if(!faust_io_manager_has_extra_output(x) && extraout)
+ {
+ x->f_extra_outlet = outlet_new((t_object *)x->f_owner, NULL);
+ if(x->f_extra_outlet)
+ {
+ return 0;
+ }
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - extra output");
+ return 1;
+ }
+ return 0;
+ }
+
+ if(faust_io_manager_has_extra_output(x))
+ {
+ outlet_free(x->f_extra_outlet);
+ x->f_extra_outlet = NULL;
+ }
+ for(i = couts; i > rnouts; --i)
+ {
+ outlet_free(x->f_outlets[i-1]);
+ x->f_outlets[i-1] = NULL;
+ }
+ noutlets = (t_outlet **)resizebytes(x->f_outlets, sizeof(t_outlet*) * couts, sizeof(t_outlet*) * rnouts);
+ if(noutlets)
+ {
+ for(i = couts; i < rnouts; ++i)
+ {
+ noutlets[i] = outlet_new((t_object *)x->f_owner, gensym("signal"));
+ if(!noutlets[i])
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - output %i", (int)i);
+ }
+ }
+ x->f_outlets = noutlets;
+ x->f_noutlets = rnouts;
+ if(extraout)
+ {
+ x->f_extra_outlet = outlet_new((t_object *)x->f_owner, NULL);
+ if(x->f_extra_outlet)
+ {
+ return 0;
+ }
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - extra output");
+ return 1;
+ }
+ return 0;
+ }
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - output");
+ return 1;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC INTERFACE //
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+t_faust_io_manager* faust_io_manager_new(t_object* owner, t_canvas* canvas)
+{
+ t_faust_io_manager* x = (t_faust_io_manager*)getbytes(sizeof(t_faust_io_manager));
+ if(x)
+ {
+ x->f_owner = owner;
+ x->f_canvas = canvas;
+ x->f_nsignals = 0;
+ x->f_signals = NULL;
+ x->f_ninlets = 1;
+ x->f_inlets = getbytes(sizeof(t_inlet *));
+ x->f_noutlets = 0;
+ x->f_outlets = NULL;
+ x->f_extra_outlet = NULL;
+ x->f_valid = 0;
+ }
+ return x;
+}
+
+void faust_io_manager_free(t_faust_io_manager* x)
+{
+ faust_io_manager_free_inputs(x);
+ faust_io_manager_free_outputs(x);
+ faust_io_manager_free_signals(x);
+ freebytes(x, sizeof(t_faust_io_manager));
+}
+
+size_t faust_io_manager_get_ninputs(t_faust_io_manager *x)
+{
+ return x->f_ninlets;
+}
+
+size_t faust_io_manager_get_noutputs(t_faust_io_manager *x)
+{
+ return x->f_noutlets;
+}
+
+char faust_io_manager_has_extra_output(t_faust_io_manager *x)
+{
+ return x->f_extra_outlet != NULL;
+}
+
+t_outlet* faust_io_manager_get_extra_output(t_faust_io_manager *x)
+{
+ return x->f_extra_outlet;
+}
+
+char faust_io_manager_init(t_faust_io_manager *x, int const nins, int const nouts, char const extraout)
+{
+ char valid = 0;
+ char const redraw = x->f_owner->te_binbuf && gobj_shouldvis((t_gobj *)x->f_owner, x->f_canvas) && glist_isvisible(x->f_canvas);
+ if(redraw)
+ {
+ gobj_vis((t_gobj *)x->f_owner, x->f_canvas, 0);
+ }
+ size_t const rnins = nins > 1 ? nins : 1;
+ valid += faust_io_manager_resize_inputs(x, (size_t)rnins);
+ valid += faust_io_manager_resize_outputs(x, (size_t)nouts, extraout);
+ valid += faust_io_manager_resize_signals(x, (size_t)rnins + (size_t)nouts);
+ if(redraw)
+ {
+ gobj_vis((t_gobj *)x->f_owner, x->f_canvas, 1);
+ canvas_fixlinesfor(x->f_canvas, (t_text *)x->f_owner);
+ }
+ x->f_valid = (valid == 0);
+ return valid;
+}
+
+#include
+
+static char faust_io_manager_is_valid(t_faust_io_manager *x)
+{
+ if(!x->f_signals || !x->f_valid)
+ {
+ pd_error(x->f_owner, "faustgen~: something wrong happened during iolets allocation");
+ return 0;
+ }
+ if(obj_nsiginlets(x->f_owner) != x->f_ninlets)
+ {
+ pd_error(x->f_owner, "faustgen~: number of signal inlets %i incompatible with internal %i", (int)x->f_ninlets, (int)obj_nsiginlets(x->f_owner));
+ return 0;
+ }
+ if(obj_nsiginlets(x->f_owner) != x->f_ninlets)
+ {
+ pd_error(x->f_owner, "faustgen~: number of signal inlets %i incompatible with internal %i", (int)x->f_ninlets, (int)obj_nsiginlets(x->f_owner));
+ return 0;
+ }
+ if(obj_nsigoutlets(x->f_owner) != x->f_noutlets)
+ {
+ pd_error(x->f_owner, "faustgen~: number of signal outlets %i incompatible with internal %i", (int)x->f_noutlets, (int)obj_nsigoutlets(x->f_owner));
+ return 0;
+ }
+ if(x->f_ninlets + x->f_noutlets != x->f_nsignals)
+ {
+ pd_error(x->f_owner, "faustgen~: number of signals %i incompatible with number of iolets %i", (int)x->f_nsignals, (int)(x->f_ninlets + x->f_noutlets));
+ return 0;
+ }
+ return 1;
+}
+
+char faust_io_manager_prepare(t_faust_io_manager *x, t_signal **sp)
+{
+ size_t i;
+ if(!faust_io_manager_is_valid)
+ {
+ return 1;
+ }
+ for(i = 0; i < x->f_nsignals; ++i)
+ {
+ x->f_signals[i] = sp[i]->s_vec;
+ if(x->f_signals[i] == NULL)
+ {
+ pd_error(x->f_owner, "faustgen~: the signal vector %i is empty", (int)i);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+t_sample** faust_io_manager_get_input_signals(t_faust_io_manager *x)
+{
+ return x->f_signals;
+}
+
+t_sample** faust_io_manager_get_output_signals(t_faust_io_manager *x)
+{
+ return x->f_signals+x->f_ninlets;
+}
+
+void faust_io_manager_print(t_faust_io_manager* x, char const log)
+{
+ logpost(x->f_owner, 2+log, " number of inputs: %i", (int)faust_io_manager_get_ninputs(x));
+ logpost(x->f_owner, 2+log, " number of outputs: %i", (int)faust_io_manager_get_noutputs(x));
+ logpost(x->f_owner, 2+log, " extra output: %s", faust_io_manager_has_extra_output(x) ? "true" : "false");
+}
diff --git a/src/faust_tilde_io.h b/src/faust_tilde_io.h
new file mode 100644
index 0000000..1f606a3
--- /dev/null
+++ b/src/faust_tilde_io.h
@@ -0,0 +1,37 @@
+/*
+// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+*/
+
+#ifndef FAUST_TILDE_IO_H
+#define FAUST_TILDE_IO_H
+
+#include
+
+struct _faust_io_manager;
+typedef struct _faust_io_manager t_faust_io_manager;
+
+t_faust_io_manager* faust_io_manager_new(t_object* owner, t_canvas* canvas);
+
+void faust_io_manager_free(t_faust_io_manager* x);
+
+size_t faust_io_manager_get_ninputs(t_faust_io_manager *x);
+
+size_t faust_io_manager_get_noutputs(t_faust_io_manager *x);
+
+char faust_io_manager_has_extra_output(t_faust_io_manager *x);
+
+t_outlet* faust_io_manager_get_extra_output(t_faust_io_manager *x);
+
+char faust_io_manager_init(t_faust_io_manager *x, int const nins, int const nouts, char const extraout);
+
+char faust_io_manager_prepare(t_faust_io_manager *x, t_signal **sp);
+
+t_sample** faust_io_manager_get_input_signals(t_faust_io_manager *x);
+
+t_sample** faust_io_manager_get_output_signals(t_faust_io_manager *x);
+
+void faust_io_manager_print(t_faust_io_manager* x, char const log);
+
+#endif
diff --git a/src/faust_tilde_options.c b/src/faust_tilde_options.c
new file mode 100644
index 0000000..e3afbc0
--- /dev/null
+++ b/src/faust_tilde_options.c
@@ -0,0 +1,223 @@
+/*
+// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+*/
+
+
+#include "faust_tilde_options.h"
+#include
+
+#define MAXFAUSTSTRING 4096
+
+typedef struct _faust_opt_manager
+{
+ t_object* f_owner;
+ char* f_default_include;
+ size_t f_noptions;
+ char** f_options;
+ t_symbol* f_directory;
+ t_symbol* f_temp_path;
+ char f_use_default_include;
+}t_faust_opt_manager;
+
+
+// LOCATE DEFAULT INCLUDE PATH
+//////////////////////////////////////////////////////////////////////////////////////////////////
+static void faust_opt_manager_get_default_include_path(t_faust_opt_manager *x)
+{
+ char const* path = class_gethelpdir(pd_class((t_pd *)x->f_owner));
+ if(path)
+ {
+ x->f_default_include = (char *)getbytes((strnlen(path, MAXPDSTRING) + 7) * sizeof(char));
+ if(x->f_default_include)
+ {
+ sprintf(x->f_default_include, "%s/libs/", path);
+ return;
+ }
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - include path");
+ return;
+ }
+ pd_error(x->f_owner, "faustgen~: cannot locate the include path");
+ return;
+}
+
+static void faust_opt_manager_free_default_include_path(t_faust_opt_manager *x)
+{
+ if(x->f_default_include)
+ {
+ freebytes(x->f_default_include, strnlen(x->f_default_include, MAXPDSTRING) * sizeof(char));
+ }
+ x->f_default_include = NULL;
+}
+
+// COMPILE OPTIONS
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faust_opt_manager_free_compile_options(t_faust_opt_manager *x)
+{
+ if(x->f_options && x->f_noptions)
+ {
+ size_t i;
+ size_t noptions = x->f_use_default_include ? x->f_noptions - 1 : x->f_noptions;
+ for(i = 0; i < noptions; ++i)
+ {
+ if(x->f_options[i])
+ {
+ freebytes(x->f_options[i], strnlen(x->f_options[i], MAXFAUSTSTRING));
+ }
+ x->f_options[i] = NULL;
+ }
+ freebytes(x->f_options, x->f_noptions * sizeof(char *));
+ }
+ x->f_options = NULL;
+ x->f_noptions = 0;
+ x->f_use_default_include = 0;
+}
+
+char faust_opt_manager_parse_compile_options(t_faust_opt_manager *x, size_t const argc, const t_atom* argv)
+{
+ size_t i;
+ char has_include = 0;
+ faust_opt_manager_free_compile_options(x);
+ x->f_options = getbytes(argc * sizeof(char *));
+ if(x->f_options)
+ {
+ for(i = 0; i < argc; ++i)
+ {
+ x->f_options[i] = (char *)getbytes(MAXFAUSTSTRING * sizeof(char));
+ if(x->f_options[i])
+ {
+ if(argv[i].a_type == A_FLOAT)
+ {
+ sprintf(x->f_options[i], "%i", (int)argv[i].a_w.w_float);
+ }
+ else if(argv[i].a_type == A_SYMBOL && argv[i].a_w.w_symbol)
+ {
+ sprintf(x->f_options[i], "%s", argv[i].a_w.w_symbol->s_name);
+ if(!strncmp(x->f_options[i], "-I", 2))
+ {
+ has_include = 1;
+ }
+ }
+ else
+ {
+ pd_error(x->f_owner, "faustgen~: option type invalid");
+ memset(x->f_options[i], 0, MAXFAUSTSTRING);
+ }
+ x->f_noptions = i+1;
+ }
+ else
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - compile option %i", (int)i);
+ x->f_noptions = i;
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - compile options");
+ x->f_noptions = 0;
+ return -1;
+ }
+ if(!has_include)
+ {
+ char **temp = resizebytes(x->f_options, (argc * sizeof(char *)), ((argc + 2) * sizeof(char *)));
+ if(temp)
+ {
+ x->f_options = temp;
+ x->f_options[argc] = (char *)getbytes(3 * sizeof(char));
+ if(x->f_options[argc])
+ {
+ sprintf(x->f_options[argc], "%s", "-I");
+ }
+ else
+ {
+ pd_error(x, "faustgen~: memory allocation failed - compile option");
+ x->f_noptions = argc;
+ return -1;
+ }
+
+ x->f_options[argc+1] = x->f_default_include;
+ x->f_noptions = argc+2;
+ x->f_use_default_include = 1;
+ return 0;
+ }
+ else
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - compile options for default include");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC INTERFACE //
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+t_faust_opt_manager* faust_opt_manager_new(t_object* owner, t_canvas* canvas)
+{
+ t_faust_opt_manager* x = (t_faust_opt_manager*)getbytes(sizeof(t_faust_opt_manager));
+ if(x)
+ {
+ x->f_owner = owner;
+ x->f_default_include = NULL;
+ x->f_options = NULL;
+ x->f_noptions = 0;
+ x->f_use_default_include = 0;
+ x->f_directory = canvas_getdir(canvas);
+ faust_opt_manager_get_default_include_path(x);
+ }
+ return x;
+}
+
+void faust_opt_manager_free(t_faust_opt_manager* x)
+{
+ faust_opt_manager_free_default_include_path(x);
+ freebytes(x, sizeof(t_faust_opt_manager));
+}
+
+size_t faust_opt_manager_get_noptions(t_faust_opt_manager* x)
+{
+ return x->f_noptions;
+}
+
+char const** faust_opt_manager_get_options(t_faust_opt_manager* x)
+{
+ return (char const**)x->f_options;
+}
+
+char const* faust_opt_manager_get_full_path(t_faust_opt_manager* x, char const* name)
+{
+ if(sys_isabsolutepath(name))
+ {
+ return name;
+ }
+ else if(x->f_directory && x->f_directory->s_name && name)
+ {
+ char* file = (char *)getbytes(MAXFAUSTSTRING * sizeof(char));
+ if(file)
+ {
+ sprintf(file, "%s/%s.dsp", x->f_directory->s_name, name);
+ x->f_temp_path = gensym(file);
+ freebytes(file, MAXFAUSTSTRING * sizeof(char));
+ return x->f_temp_path->s_name;
+ }
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - path");
+ return NULL;
+ }
+ pd_error(x->f_owner, "faustgen~: invalid path or name");
+ return NULL;
+}
+
+void faust_opt_manager_print(t_faust_opt_manager* x, char const log)
+{
+ size_t i;
+ for(i = 0; i < x->f_noptions; ++i)
+ {
+ logpost(x->f_owner, 2+log, " option %i: %s", (int)i, x->f_options[i]);
+ }
+}
diff --git a/src/faust_tilde_options.h b/src/faust_tilde_options.h
new file mode 100644
index 0000000..a984cff
--- /dev/null
+++ b/src/faust_tilde_options.h
@@ -0,0 +1,29 @@
+/*
+// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+*/
+
+#ifndef FAUST_TILDE_OPTIONS_H
+#define FAUST_TILDE_OPTIONS_H
+
+#include
+
+struct _faust_opt_manager;
+typedef struct _faust_opt_manager t_faust_opt_manager;
+
+t_faust_opt_manager* faust_opt_manager_new(t_object* owner, t_canvas* canvas);
+
+void faust_opt_manager_free(t_faust_opt_manager* x);
+
+char faust_opt_manager_parse_compile_options(t_faust_opt_manager *x, size_t const argc, const t_atom* argv);
+
+size_t faust_opt_manager_get_noptions(t_faust_opt_manager* x);
+
+char const** faust_opt_manager_get_options(t_faust_opt_manager* x);
+
+char const* faust_opt_manager_get_full_path(t_faust_opt_manager* x, char const* name);
+
+void faust_opt_manager_print(t_faust_opt_manager* x, char const log);
+
+#endif
diff --git a/src/faust_tilde_ui.c b/src/faust_tilde_ui.c
new file mode 100644
index 0000000..3cbefb4
--- /dev/null
+++ b/src/faust_tilde_ui.c
@@ -0,0 +1,481 @@
+/*
+// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+*/
+
+
+#include "faust_tilde_ui.h"
+#include
+#include
+#include
+
+#define MAXFAUSTSTRING 4096
+#define FAUST_UI_TYPE_BUTTON 0
+#define FAUST_UI_TYPE_TOGGLE 1
+#define FAUST_UI_TYPE_NUMBER 2
+#define FAUST_UI_TYPE_BARGRAPH 3
+
+typedef struct _faust_ui
+{
+ t_symbol* p_name;
+ t_symbol* p_longname;
+ int p_type;
+ FAUSTFLOAT* p_zone;
+ FAUSTFLOAT p_min;
+ FAUSTFLOAT p_max;
+ FAUSTFLOAT p_step;
+ FAUSTFLOAT p_default;
+ FAUSTFLOAT p_saved;
+}t_faust_ui;
+
+typedef struct _faust_ui_manager
+{
+ UIGlue f_glue;
+ t_object* f_owner;
+ t_clock* f_clock;
+ t_faust_ui* f_active_uis;
+ size_t f_nactive_uis;
+ t_faust_ui* f_temp_ui;
+ t_faust_ui* f_passive_uis;
+ size_t f_npassive_uis;
+ t_symbol** f_names;
+ size_t f_nnames;
+ MetaGlue f_meta_glue;
+}t_faust_ui_manager;
+
+
+static void faust_ui_manager_clear_active_uis(t_faust_ui_manager *x)
+{
+ if(x->f_active_uis && x->f_nactive_uis)
+ {
+ freebytes(x->f_active_uis, x->f_nactive_uis * sizeof(t_faust_ui));
+ }
+ x->f_active_uis = NULL;
+ x->f_nactive_uis = 0;
+}
+
+static void faust_ui_manager_clear_passive_uis(t_faust_ui_manager *x)
+{
+ if(x->f_passive_uis && x->f_npassive_uis)
+ {
+ freebytes(x->f_passive_uis, x->f_npassive_uis * sizeof(t_faust_ui));
+ }
+ x->f_passive_uis = NULL;
+ x->f_npassive_uis = 0;
+}
+
+static void faust_ui_manager_clear_names(t_faust_ui_manager *x)
+{
+ if(x->f_names && x->f_nnames)
+ {
+ freebytes(x->f_names, x->f_nnames * sizeof(t_symbol *));
+ }
+ x->f_names = NULL;
+ x->f_nnames = 0;
+}
+
+static t_faust_ui* faust_ui_manager_get_active_uis(t_faust_ui_manager *x, t_symbol* name)
+{
+ size_t i;
+ for(i = 0; i < x->f_nactive_uis; ++i)
+ {
+ if(x->f_active_uis[i].p_name == name ||
+ x->f_active_uis[i].p_longname == name)
+ {
+ return x->f_active_uis+i;
+ }
+ }
+ return NULL;
+}
+
+static t_faust_ui* faust_ui_manager_get_passive_uis(t_faust_ui_manager *x, t_symbol* name)
+{
+ size_t i;
+ for(i = 0; i < x->f_npassive_uis; ++i)
+ {
+ if(x->f_passive_uis[i].p_name == name ||
+ x->f_passive_uis[i].p_longname == name)
+ {
+ return x->f_passive_uis+i;
+ }
+ }
+ return NULL;
+}
+
+static t_symbol* faust_ui_manager_get_long_name(t_faust_ui_manager *x, const char* label)
+{
+ size_t i;
+ char name[MAXFAUSTSTRING];
+ memset(name, 0, MAXFAUSTSTRING);
+ for(i = 0; i < x->f_nnames; ++i)
+ {
+ strncat(name, x->f_names[i]->s_name, MAXFAUSTSTRING);
+ strncat(name, "/", 1);
+ }
+ strncat(name, label, MAXFAUSTSTRING);
+ return gensym(name);
+}
+
+static void faust_ui_manager_add_params(t_faust_ui_manager *x, const char* label, int const type, FAUSTFLOAT* zone,
+ FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+ t_faust_ui *newmemory = NULL;
+ t_faust_ui *oldmemory = (type == FAUST_UI_TYPE_BARGRAPH) ? x->f_passive_uis : x->f_active_uis;
+ size_t size = (type == FAUST_UI_TYPE_BARGRAPH) ? x->f_npassive_uis : x->f_nactive_uis;
+ if(oldmemory)
+ {
+ newmemory = (t_faust_ui *)resizebytes(oldmemory, size * sizeof(t_faust_ui), (size + 1) * sizeof(t_faust_ui));
+ if(!newmemory)
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - ui glue");
+ return;
+ }
+ }
+ else
+ {
+ newmemory = (t_faust_ui *)getbytes(sizeof(t_faust_ui));
+ if(!newmemory)
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - ui glue");
+ return;
+ }
+ }
+
+ newmemory[size].p_name = gensym(label);
+ newmemory[size].p_longname = faust_ui_manager_get_long_name(x, label);
+ newmemory[size].p_type = type;
+ newmemory[size].p_zone = zone;
+ newmemory[size].p_min = min;
+ newmemory[size].p_max = max;
+ newmemory[size].p_step = step;
+ newmemory[size].p_default = init;
+ newmemory[size].p_saved = init;
+ *(newmemory[size].p_zone) = init;
+ if(type == FAUST_UI_TYPE_BARGRAPH)
+ {
+ x->f_passive_uis = (t_faust_ui *)newmemory;
+ x->f_npassive_uis = size + 1;
+ }
+ else
+ {
+ x->f_active_uis = (t_faust_ui *)newmemory;
+ x->f_nactive_uis = size + 1;
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// PRIVATE INTERFACE //
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+// NAME PATH
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faust_ui_manager_ui_open_box(t_faust_ui_manager* x, const char* label)
+{
+ if(x->f_nnames)
+ {
+ t_symbol** temp = (t_symbol**)resizebytes(x->f_names, x->f_nnames * sizeof(t_symbol *), (x->f_nnames + 1) * sizeof(t_symbol *));
+ if(temp)
+ {
+ x->f_names = temp;
+ x->f_names[x->f_nnames] = gensym(label);
+ x->f_nnames = x->f_nnames + 1;
+ return;
+ }
+ else
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - ui box");
+ return;
+ }
+ }
+ else
+ {
+ x->f_names = getbytes(sizeof(t_symbol *));
+ if(x->f_names)
+ {
+ x->f_names[0] = gensym(label);
+ x->f_nnames = 1;
+ return;
+ }
+ else
+ {
+ pd_error(x->f_owner, "faustgen~: memory allocation failed - ui box");
+ return;
+ }
+ }
+}
+
+static void faust_ui_manager_ui_close_box(t_faust_ui_manager* x)
+{
+ if(x->f_nnames > 1)
+ {
+ t_symbol** temp = (t_symbol**)resizebytes(x->f_names, x->f_nnames * sizeof(t_symbol *), (x->f_nnames - 1) * sizeof(t_symbol *));
+ if(temp)
+ {
+ x->f_names = temp;
+ x->f_nnames = x->f_nnames - 1;
+ return;
+ }
+ else
+ {
+ pd_error(x->f_owner, "faustgen~: memory de-allocation failed - ui box");
+ return;
+ }
+ }
+ else if(x->f_nnames)
+ {
+ freebytes(x->f_names, sizeof(t_symbol *));
+ x->f_names = NULL;
+ x->f_nnames = 0;
+ }
+}
+
+
+// ACTIVE UIS
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faust_ui_manager_ui_add_button(t_faust_ui_manager* x, const char* label, FAUSTFLOAT* zone)
+{
+ faust_ui_manager_add_params(x, label, FAUST_UI_TYPE_BUTTON, zone, 0, 0, 0, 0);
+}
+
+static void faust_ui_manager_ui_add_toggle(t_faust_ui_manager* x, const char* label, FAUSTFLOAT* zone)
+{
+ faust_ui_manager_add_params(x, label, FAUST_UI_TYPE_TOGGLE, zone, 0, 0, 1, 1);
+}
+
+static void faust_ui_manager_ui_add_number(t_faust_ui_manager* x, const char* label, FAUSTFLOAT* zone,
+ FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+{
+ faust_ui_manager_add_params(x, label, FAUST_UI_TYPE_NUMBER, zone, init, min, max, step);
+}
+
+// PASSIVE UIS
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faust_ui_manager_ui_add_bargraph(t_faust_ui_manager* x, const char* label,
+ FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
+{
+ faust_ui_manager_add_params(x, label, FAUST_UI_TYPE_BARGRAPH, zone, 0, min, max, 0);
+}
+
+static void faust_ui_manager_ui_add_sound_file(t_faust_ui_manager* x, const char* label, const char* filename, struct Soundfile** sf_zone)
+{
+ pd_error(x->f_owner, "faustgen~: add sound file not supported yet");
+}
+
+// DECLARE UIS
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faust_ui_manager_ui_declare(t_faust_ui_manager* x, FAUSTFLOAT* zone, const char* key, const char* value)
+{
+ //logpost(x->f_owner, 3, "%s: %s - %f", key, value, *zone);
+}
+
+// META UIS
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faust_ui_manager_meta_declare(t_faust_ui_manager* x, const char* key, const char* value)
+{
+ logpost(x->f_owner, 3, " %s: %s", key, value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC INTERFACE //
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faust_ui_manager_tick(t_faust_ui_manager* x);
+
+t_faust_ui_manager* faust_ui_manager_new(t_object* owner)
+{
+ t_faust_ui_manager* ui_manager = (t_faust_ui_manager*)getbytes(sizeof(t_faust_ui_manager));
+ if(ui_manager)
+ {
+ ui_manager->f_glue.uiInterface = ui_manager;
+ ui_manager->f_glue.openTabBox = (openTabBoxFun)faust_ui_manager_ui_open_box;
+ ui_manager->f_glue.openHorizontalBox = (openHorizontalBoxFun)faust_ui_manager_ui_open_box;
+ ui_manager->f_glue.openVerticalBox = (openVerticalBoxFun)faust_ui_manager_ui_open_box;
+ ui_manager->f_glue.closeBox = (closeBoxFun)faust_ui_manager_ui_close_box;
+
+ ui_manager->f_glue.addButton = (addButtonFun)faust_ui_manager_ui_add_button;
+ ui_manager->f_glue.addCheckButton = (addCheckButtonFun)faust_ui_manager_ui_add_toggle;
+ ui_manager->f_glue.addVerticalSlider = (addVerticalSliderFun)faust_ui_manager_ui_add_number;
+ ui_manager->f_glue.addHorizontalSlider = (addHorizontalSliderFun)faust_ui_manager_ui_add_number;
+ ui_manager->f_glue.addNumEntry = (addNumEntryFun)faust_ui_manager_ui_add_number;
+
+ ui_manager->f_glue.addHorizontalBargraph = (addHorizontalBargraphFun)faust_ui_manager_ui_add_bargraph;
+ ui_manager->f_glue.addVerticalBargraph = (addVerticalBargraphFun)faust_ui_manager_ui_add_bargraph;
+ ui_manager->f_glue.addSoundFile = (addSoundFileFun)faust_ui_manager_ui_add_sound_file;
+ ui_manager->f_glue.declare = (declareFun)faust_ui_manager_ui_declare;
+
+ ui_manager->f_owner = owner;
+ ui_manager->f_clock = clock_new(ui_manager, (t_method)faust_ui_manager_tick);
+ ui_manager->f_active_uis = NULL;
+ ui_manager->f_nactive_uis = 0;
+ ui_manager->f_passive_uis = NULL;
+ ui_manager->f_npassive_uis = 0;
+ ui_manager->f_names = NULL;
+ ui_manager->f_nnames = 0;
+
+ ui_manager->f_meta_glue.metaInterface = ui_manager;
+ ui_manager->f_meta_glue.declare = (metaDeclareFun)faust_ui_manager_meta_declare;
+ }
+ return ui_manager;
+}
+
+void faust_ui_manager_free(t_faust_ui_manager *x)
+{
+ faust_ui_manager_clear(x);
+ freebytes(x, sizeof(t_faust_ui_manager));
+}
+
+void faust_ui_manager_init(t_faust_ui_manager *x, void* dspinstance)
+{
+ faust_ui_manager_clear(x);
+ buildUserInterfaceCDSPInstance((llvm_dsp *)dspinstance, (UIGlue *)&(x->f_glue));
+ faust_ui_manager_clear_names(x);
+ metadataCDSPInstance((llvm_dsp *)dspinstance, &x->f_meta_glue);
+}
+
+void faust_ui_manager_clear(t_faust_ui_manager *x)
+{
+ faust_ui_manager_clear_active_uis(x);
+ faust_ui_manager_clear_passive_uis(x);
+ faust_ui_manager_clear_names(x);
+}
+
+static void faust_ui_manager_tick(t_faust_ui_manager* x)
+{
+ if(x->f_temp_ui)
+ {
+ *(x->f_temp_ui->p_zone) = 0;
+ }
+ x->f_temp_ui = NULL;
+}
+
+char faust_ui_manager_has_passive_ui(t_faust_ui_manager *x)
+{
+ return x->f_npassive_uis > 0;
+}
+
+char faust_ui_manager_set(t_faust_ui_manager *x, t_symbol* name, t_float f)
+{
+ t_faust_ui* ui = faust_ui_manager_get_active_uis(x, name);
+ if(ui)
+ {
+ if(ui->p_type == FAUST_UI_TYPE_BUTTON)
+ {
+ *(ui->p_zone) = 0;
+ *(ui->p_zone) = 1;
+ x->f_temp_ui = ui;
+ clock_delay(x->f_clock, 1.5);
+ return 0;
+ }
+ else if(ui->p_type == FAUST_UI_TYPE_TOGGLE)
+ {
+ *(ui->p_zone) = (FAUSTFLOAT)(f > FLT_EPSILON);
+ return 0;
+ }
+ else if(ui->p_type == FAUST_UI_TYPE_NUMBER)
+ {
+ const FAUSTFLOAT v = (FAUSTFLOAT)(f);
+ if(v < ui->p_min)
+ {
+ *(ui->p_zone) = ui->p_min;
+ return 0;
+ }
+ if(v > ui->p_max)
+ {
+ *(ui->p_zone) = ui->p_max;
+ return 0;
+ }
+ *(ui->p_zone) = v;
+ return 0;
+ }
+ }
+ return 1;
+}
+
+char faust_ui_manager_get(t_faust_ui_manager *x, t_symbol* name, t_float* f)
+{
+ t_faust_ui* ui = faust_ui_manager_get_passive_uis(x, name);
+ if(ui)
+ {
+ *f = (t_float)(*(ui->p_zone));
+ return 0;
+ }
+ return 1;
+}
+
+void faust_ui_manager_save_states(t_faust_ui_manager *x)
+{
+ size_t i;
+ for(i = 0; i < x->f_nactive_uis; ++i)
+ {
+ x->f_active_uis[i].p_saved = *(x->f_active_uis[i].p_zone);
+ }
+}
+
+void faust_ui_manager_restore_states(t_faust_ui_manager *x)
+{
+ size_t i;
+ for(i = 0; i < x->f_nactive_uis; ++i)
+ {
+ *(x->f_active_uis[i].p_zone) = x->f_active_uis[i].p_saved;
+ }
+}
+
+void faust_ui_manager_restore_default(t_faust_ui_manager *x)
+{
+ size_t i;
+ for(i = 0; i < x->f_nactive_uis; ++i)
+ {
+ *(x->f_active_uis[i].p_zone) = x->f_active_uis[i].p_default;
+ }
+}
+
+const char* faust_ui_manager_get_parameter_char(int type)
+{
+ if(type == FAUST_UI_TYPE_BUTTON)
+ return "button";
+ else if(type == FAUST_UI_TYPE_TOGGLE)
+ return "toggle";
+ else if(type == FAUST_UI_TYPE_NUMBER)
+ return "number";
+ else
+ return "bargraph";
+}
+
+void faust_ui_manager_print(t_faust_ui_manager* x, char const log)
+{
+ size_t i;
+ logpost(x->f_owner, 2+log, " active parameters: %i", (int)x->f_nactive_uis);
+ for(i = 0; i < x->f_nactive_uis; ++i)
+ {
+ logpost(x->f_owner, 2+log, " %i: %s [path:%s - type:%s - init:%g - min:%g - max:%g - current:%g]", (int)i,
+ x->f_active_uis[i].p_name->s_name,
+ x->f_active_uis[i].p_longname->s_name,
+ faust_ui_manager_get_parameter_char(x->f_active_uis[i].p_type),
+ x->f_active_uis[i].p_default,
+ x->f_active_uis[i].p_min,
+ x->f_active_uis[i].p_max,
+ *x->f_active_uis[i].p_zone);
+ }
+ logpost(x->f_owner, 2+log, " passive parameters: %i", (int)x->f_npassive_uis);
+ for(i = 0; i < x->f_npassive_uis; ++i)
+ {
+ logpost(x->f_owner, 2+log, " %i: %s [path:%s - type:%s - init:%g - min:%g - max:%g - current:%g]", (int)i,
+ x->f_passive_uis[i].p_name->s_name,
+ x->f_passive_uis[i].p_longname->s_name,
+ faust_ui_manager_get_parameter_char(x->f_passive_uis[i].p_type),
+ x->f_passive_uis[i].p_default,
+ x->f_passive_uis[i].p_min,
+ x->f_passive_uis[i].p_max,
+ *x->f_passive_uis[i].p_zone);
+ }
+}
+
+
diff --git a/src/faust_tilde_ui.h b/src/faust_tilde_ui.h
new file mode 100644
index 0000000..3806e98
--- /dev/null
+++ b/src/faust_tilde_ui.h
@@ -0,0 +1,35 @@
+/*
+// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+*/
+
+#ifndef FAUST_TILDE_UI_H
+#define FAUST_TILDE_UI_H
+
+#include
+
+struct _faust_ui_manager;
+typedef struct _faust_ui_manager t_faust_ui_manager;
+
+t_faust_ui_manager* faust_ui_manager_new(t_object* owner);
+
+void faust_ui_manager_init(t_faust_ui_manager *x, void* dspinstance);
+
+void faust_ui_manager_free(t_faust_ui_manager *x);
+
+void faust_ui_manager_clear(t_faust_ui_manager *x);
+
+char faust_ui_manager_has_passive_ui(t_faust_ui_manager *x);
+
+char faust_ui_manager_set(t_faust_ui_manager *x, t_symbol* name, t_float f);
+
+char faust_ui_manager_get(t_faust_ui_manager *x, t_symbol* name, t_float* f);
+
+void faust_ui_manager_save_states(t_faust_ui_manager *x);
+
+void faust_ui_manager_restore_states(t_faust_ui_manager *x);
+
+void faust_ui_manager_print(t_faust_ui_manager* x, char const log);
+
+#endif
diff --git a/src/faustgen_tilde.c b/src/faustgen_tilde.c
new file mode 100644
index 0000000..0462cb6
--- /dev/null
+++ b/src/faustgen_tilde.c
@@ -0,0 +1,409 @@
+/*
+// Copyright (c) 2018 - GRAME CNCM - CICM - ANR MUSICOLL - Pierre Guillot.
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "faust_tilde_ui.h"
+#include "faust_tilde_io.h"
+#include "faust_tilde_options.h"
+
+#define MAXFAUSTSTRING 4096
+#define MAXFAUSTOPTIONS 128
+
+typedef struct _faustgen_tilde
+{
+ t_object f_obj;
+ llvm_dsp_factory* f_dsp_factory;
+ llvm_dsp* f_dsp_instance;
+
+ FAUSTFLOAT** f_signal_matrix;
+ FAUSTFLOAT* f_signal_aligned;
+ size_t f_signal_aligned_size;
+
+ t_faust_ui_manager* f_ui_manager;
+ t_faust_io_manager* f_io_manager;
+ t_faust_opt_manager* f_opt_manager;
+
+ t_symbol* f_dsp_name;
+ t_float f_dummy;
+ t_clock* f_clock;
+ double f_clock_time;
+ long f_time;
+} t_faustgen_tilde;
+
+static t_class *faustgen_tilde_class;
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// FAUST INTERFACE //
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faustgen_tilde_delete_instance(t_faustgen_tilde *x)
+{
+ if(x->f_dsp_instance)
+ {
+ deleteCDSPInstance(x->f_dsp_instance);
+ }
+ x->f_dsp_instance = NULL;
+}
+
+static void faustgen_tilde_delete_factory(t_faustgen_tilde *x)
+{
+ faustgen_tilde_delete_instance(x);
+ if(x->f_dsp_factory)
+ {
+ deleteCDSPFactory(x->f_dsp_factory);
+ }
+ x->f_dsp_factory = NULL;
+}
+
+static void faustgen_tilde_compile(t_faustgen_tilde *x)
+{
+ char const* filepath;
+ int dspstate = canvas_suspend_dsp();
+ if(!x->f_dsp_name)
+ {
+ return;
+ }
+ filepath = faust_opt_manager_get_full_path(x->f_opt_manager, x->f_dsp_name->s_name);
+ if(filepath)
+ {
+ char errors[MAXFAUSTSTRING];
+ int noptions = (int)faust_opt_manager_get_noptions(x->f_opt_manager);
+ char const** options = faust_opt_manager_get_options(x->f_opt_manager);
+ faustgen_tilde_delete_instance(x);
+ faustgen_tilde_delete_factory(x);
+ faust_ui_manager_clear(x->f_ui_manager);
+
+ x->f_dsp_factory = createCDSPFactoryFromFile(filepath, noptions, options, "", errors, -1);
+ if(strnlen(errors, MAXFAUSTSTRING))
+ {
+ pd_error(x, "faustgen~: try to load %s", filepath);
+ pd_error(x, "faustgen~: %s", errors);
+ x->f_dsp_factory = NULL;
+
+ canvas_resume_dsp(dspstate);
+ return;
+ }
+
+ x->f_dsp_instance = createCDSPInstance(x->f_dsp_factory);
+ if(x->f_dsp_instance)
+ {
+ const int ninputs = getNumInputsCDSPInstance(x->f_dsp_instance);
+ const int noutputs = getNumOutputsCDSPInstance(x->f_dsp_instance);
+ logpost(x, 3, "\nfaustgen~: compilation from source '%s' succeeded", x->f_dsp_name->s_name);
+ faust_ui_manager_init(x->f_ui_manager, x->f_dsp_instance);
+ faust_io_manager_init(x->f_io_manager, ninputs, noutputs, faust_ui_manager_has_passive_ui(x->f_ui_manager));
+
+ canvas_resume_dsp(dspstate);
+ return;
+ }
+
+ pd_error(x, "faustgen~: memory allocation failed - instance");
+ canvas_resume_dsp(dspstate);
+ return;
+ }
+ pd_error(x, "faustgen~: source file not found %s", x->f_dsp_name->s_name);
+ canvas_resume_dsp(dspstate);
+}
+
+static void faustgen_tilde_compile_options(t_faustgen_tilde *x, t_symbol* s, int argc, t_atom* argv)
+{
+ faust_opt_manager_parse_compile_options(x->f_opt_manager, argc, argv);
+ faustgen_tilde_compile(x);
+}
+
+static void faustgen_tilde_read(t_faustgen_tilde *x, t_symbol* s)
+{
+ x->f_dsp_name = s;
+ faustgen_tilde_compile(x);
+}
+
+static long faustgen_tilde_get_time(t_faustgen_tilde *x)
+{
+ struct stat attrib;
+ stat(faust_opt_manager_get_full_path(x->f_opt_manager, x->f_dsp_name->s_name), &attrib);
+ return attrib.st_ctime;
+}
+
+static void faustgen_tilde_autocompile_tick(t_faustgen_tilde *x)
+{
+ long ntime = faustgen_tilde_get_time(x);
+ if(ntime != x->f_time)
+ {
+ x->f_time = ntime;
+ faustgen_tilde_compile(x);
+ }
+ clock_delay(x->f_clock, x->f_clock_time);
+}
+
+static void faustgen_tilde_autocompile(t_faustgen_tilde *x, t_symbol* s, int argc, t_atom* argv)
+{
+ float state = atom_getfloatarg(0, argc, argv);
+ if(fabsf(state) > FLT_EPSILON)
+ {
+ float time = atom_getfloatarg(1, argc, argv);
+ x->f_clock_time = (time > FLT_EPSILON) ? (double)time : 100.;
+ x->f_time = faustgen_tilde_get_time(x);
+ clock_delay(x->f_clock, x->f_clock_time);
+ }
+ else
+ {
+ clock_unset(x->f_clock);
+ }
+}
+
+static void faustgen_tilde_print_parameters(t_faustgen_tilde *x)
+{
+ faust_io_manager_print(x->f_io_manager, 0);
+ faust_opt_manager_print(x->f_opt_manager, 0);
+ faust_ui_manager_print(x->f_ui_manager, 0);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+// PURE DATA GENERIC INTERFACE //
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+static void faustgen_tilde_anything(t_faustgen_tilde *x, t_symbol* s, int argc, t_atom* argv)
+{
+ if(x->f_dsp_instance)
+ {
+ if(!argc)
+ {
+ t_float value;
+ if(!faust_ui_manager_get(x->f_ui_manager, s, &value))
+ {
+ t_atom av;
+ SETFLOAT(&av, value);
+ outlet_anything(faust_io_manager_get_extra_output(x->f_io_manager), s, 0, &av);
+ return;
+ }
+ pd_error(x, "faustgen~: passive parameter '%s' not defined", s->s_name);
+ return;
+ }
+ else if(argc == 1)
+ {
+ if(argv[0].a_type != A_FLOAT)
+ {
+ pd_error(x, "faustgen~: active parameter requires a float value");
+ return;
+ }
+ if(!faust_ui_manager_set(x->f_ui_manager, s, argv[0].a_w.w_float))
+ {
+ return;
+ }
+ pd_error(x, "faustgen~: active parameter '%s' not defined", s->s_name);
+ return;
+ }
+ else
+ {
+ int i, start;
+ char name[MAXFAUSTSTRING];
+ if(argv[0].a_type != A_FLOAT)
+ {
+ pd_error(x, "faustgen~: list parameters requires a first index");
+ return;
+ }
+ start = (int)argv[0].a_w.w_float;
+ for(i = 0; i < argc - 1; ++i)
+ {
+ if(start+i < 10)
+ {
+ sprintf(name, "%s %i", s->s_name, start+i);
+ }
+ else if(start+i < 100)
+ {
+ sprintf(name, "%s %i", s->s_name, start+i);
+ }
+ else
+ {
+ sprintf(name, "%s%i", s->s_name, start+i);
+ }
+ if(argv[i+1].a_type != A_FLOAT)
+ {
+ pd_error(x, "faustgen~: active parameter requires a float value");
+ }
+ if(faust_ui_manager_set(x->f_ui_manager, gensym(name), argv[i+1].a_w.w_float))
+ {
+ pd_error(x, "faustgen~: active parameter '%s' not defined", name);
+ return;
+ }
+ }
+ return;
+ }
+ }
+ pd_error(x, "faustgen~: no dsp instance");
+}
+
+static t_int *faustgen_tilde_perform(t_int *w)
+{
+ int i, j;
+ llvm_dsp *dsp = (llvm_dsp *)w[1];
+ int const nsamples = (int)w[2];
+ int const ninputs = (int)w[3];
+ int const noutputs = (int)w[4];
+ FAUSTFLOAT** faustsigs = (FAUSTFLOAT **)w[5];
+ t_sample const** realinputs = (t_sample const**)w[6];
+ t_sample** realoutputs = (t_sample **)w[7];
+ for(i = 0; i < ninputs; ++i)
+ {
+ for(j = 0; j < nsamples; ++j)
+ {
+ faustsigs[i][j] = (FAUSTFLOAT)realinputs[i][j];
+ }
+ }
+ computeCDSPInstance(dsp, nsamples, faustsigs, faustsigs+ninputs);
+ for(i = 0; i < noutputs; ++i)
+ {
+ for(j = 0; j < nsamples; ++j)
+ {
+ realoutputs[i][j] = (t_sample)faustsigs[ninputs+i][j];
+ }
+ }
+ return (w+8);
+}
+
+static void faustgen_tilde_free_signal(t_faustgen_tilde *x)
+{
+ if(x->f_signal_aligned)
+ {
+ free(x->f_signal_aligned);
+ }
+ x->f_signal_aligned = NULL;
+ if(x->f_signal_matrix)
+ {
+ free(x->f_signal_matrix);
+ }
+ x->f_signal_matrix = NULL;
+}
+
+static void faustgen_tilde_dsp(t_faustgen_tilde *x, t_signal **sp)
+{
+ if(x->f_dsp_instance)
+ {
+ char initialized = getSampleRateCDSPInstance(x->f_dsp_instance) != sp[0]->s_sr;
+ if(initialized)
+ {
+ faust_ui_manager_save_states(x->f_ui_manager);
+ initCDSPInstance(x->f_dsp_instance, sp[0]->s_sr);
+ }
+ if(!faust_io_manager_prepare(x->f_io_manager, sp))
+ {
+ size_t i;
+ size_t const ninputs = faust_io_manager_get_ninputs(x->f_io_manager);
+ size_t const noutputs = faust_io_manager_get_noutputs(x->f_io_manager);
+ size_t const nsamples = (size_t)sp[0]->s_n;
+
+ faustgen_tilde_free_signal(x);
+ x->f_signal_aligned = (t_sample *)malloc((ninputs + noutputs) * nsamples * sizeof(FAUSTFLOAT));
+ if(!x->f_signal_aligned)
+ {
+ pd_error(x, "memory allocation failed");
+ return;
+ }
+ x->f_signal_matrix = (FAUSTFLOAT **)malloc((ninputs + noutputs) * sizeof(FAUSTFLOAT *));
+ if(!x->f_signal_matrix)
+ {
+ pd_error(x, "memory allocation failed");
+ return;
+ }
+ for(i = 0; i < (ninputs + noutputs); ++i)
+ {
+ x->f_signal_matrix[i] = (x->f_signal_aligned+(i*nsamples));
+ }
+ dsp_add((t_perfroutine)faustgen_tilde_perform, 7,
+ (t_int)x->f_dsp_instance, (t_int)nsamples, (t_int)ninputs, (t_int)noutputs,
+ (t_int)x->f_signal_matrix,
+ (t_int)faust_io_manager_get_input_signals(x->f_io_manager),
+ (t_int)faust_io_manager_get_output_signals(x->f_io_manager));
+ }
+ if(initialized)
+ {
+ faust_ui_manager_restore_states(x->f_ui_manager);
+ }
+ }
+}
+
+static void faustgen_tilde_free(t_faustgen_tilde *x)
+{
+ faustgen_tilde_delete_instance(x);
+ faustgen_tilde_delete_factory(x);
+ faust_ui_manager_free(x->f_ui_manager);
+ faust_io_manager_free(x->f_io_manager);
+ faust_opt_manager_free(x->f_opt_manager);
+}
+
+static void *faustgen_tilde_new(t_symbol* s, int argc, t_atom* argv)
+{
+ t_faustgen_tilde* x = (t_faustgen_tilde *)pd_new(faustgen_tilde_class);
+ if(x)
+ {
+ x->f_dsp_factory = NULL;
+ x->f_dsp_instance = NULL;
+
+ x->f_signal_matrix = NULL;
+ x->f_signal_aligned = NULL;
+ x->f_signal_aligned_size = 0;
+
+ x->f_ui_manager = faust_ui_manager_new((t_object *)x);
+ x->f_io_manager = faust_io_manager_new((t_object *)x, canvas_getcurrent());
+ x->f_opt_manager = faust_opt_manager_new((t_object *)x, canvas_getcurrent());
+ x->f_dsp_name = atom_getsymbolarg(0, argc, argv);
+ x->f_clock = clock_new(x, (t_method)faustgen_tilde_autocompile_tick);
+ faust_opt_manager_parse_compile_options(x->f_opt_manager, argc-1, argv+1);
+ if(!argc)
+ {
+ return x;
+ }
+ faustgen_tilde_compile(x);
+ if(!x->f_dsp_instance)
+ {
+ faustgen_tilde_free(x);
+ return NULL;
+ }
+ }
+ return x;
+}
+
+void faustgen_tilde_setup(void)
+{
+ t_class* c = class_new(gensym("faustgen~"),
+ (t_newmethod)faustgen_tilde_new, (t_method)faustgen_tilde_free,
+ sizeof(t_faustgen_tilde), CLASS_DEFAULT, A_GIMME, 0);
+
+ if(c)
+ {
+ class_addmethod(c, (t_method)faustgen_tilde_dsp, gensym("dsp"), A_CANT);
+ class_addmethod(c, (t_method)faustgen_tilde_compile, gensym("compile"), A_NULL);
+ class_addmethod(c, (t_method)faustgen_tilde_compile_options, gensym("compileoptions"), A_GIMME);
+ class_addmethod(c, (t_method)faustgen_tilde_autocompile, gensym("autocompile"), A_GIMME);
+ class_addmethod(c, (t_method)faustgen_tilde_print_parameters, gensym("print"), A_NULL);
+
+ //class_addmethod(c, (t_method)faustgen_tilde_read, gensym("read"), A_SYMBOL);
+ class_addanything(c, (t_method)faustgen_tilde_anything);
+
+ CLASS_MAINSIGNALIN(c, t_faustgen_tilde, f_dummy);
+ logpost(NULL, 3, "Faust website: faust.grame.fr");
+ logpost(NULL, 3, "Faust development: GRAME");
+
+ logpost(NULL, 3, "faustgen~ compiler version: %s", getCLibFaustVersion());
+ logpost(NULL, 3, "faustgen~ default include directory: %s", class_gethelpdir(c));
+ logpost(NULL, 3, "faustgen~ institutions: CICM - ANR MUSICOLL");
+ logpost(NULL, 3, "faustgen~ external author: Pierre Guillot");
+ logpost(NULL, 3, "faustgen~ website: github.com/CICM/faust-pd");
+ }
+
+ faustgen_tilde_class = c;
+}
+