diff --git a/.idea/artifacts/TerrarumBuild.xml b/.idea/artifacts/TerrarumBuild.xml
index a83413779..15917597f 100644
--- a/.idea/artifacts/TerrarumBuild.xml
+++ b/.idea/artifacts/TerrarumBuild.xml
@@ -13,84 +13,110 @@
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/github_psambit9791_jdsp.xml b/.idea/libraries/github_psambit9791_jdsp.xml
new file mode 100644
index 000000000..18532f1e4
--- /dev/null
+++ b/.idea/libraries/github_psambit9791_jdsp.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TerrarumBuild.iml b/TerrarumBuild.iml
index 7dc4c4a4e..f8b477537 100644
--- a/TerrarumBuild.iml
+++ b/TerrarumBuild.iml
@@ -27,5 +27,6 @@
+
\ No newline at end of file
diff --git a/lib/VectorGraphics2D-0.13-sources.jar b/lib/VectorGraphics2D-0.13-sources.jar
new file mode 100644
index 000000000..3662c3b5b
--- /dev/null
+++ b/lib/VectorGraphics2D-0.13-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:527461c88c94585ed336add8fe5681bd42e4e721de46327ad054a1584b27309b
+size 101837
diff --git a/lib/VectorGraphics2D-0.13.jar b/lib/VectorGraphics2D-0.13.jar
new file mode 100644
index 000000000..04600efc8
--- /dev/null
+++ b/lib/VectorGraphics2D-0.13.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1b1c6248f1e70c52b8e9c09873350185aad081e70f83649ef85571ff269a71a2
+size 94027
diff --git a/lib/animated-gif-lib-1.4-sources.jar b/lib/animated-gif-lib-1.4-sources.jar
new file mode 100644
index 000000000..a04bde828
--- /dev/null
+++ b/lib/animated-gif-lib-1.4-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2c39b676cc289fa389ab31b0622996aa8eb0f87d17e4d1a73ddea9324fcee72d
+size 18744
diff --git a/lib/animated-gif-lib-1.4.jar b/lib/animated-gif-lib-1.4.jar
new file mode 100644
index 000000000..df7903b18
--- /dev/null
+++ b/lib/animated-gif-lib-1.4.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:49ad396efc16a076df137881e3a815922959bfb8d485e25f56bc3d3978c498cd
+size 20742
diff --git a/lib/apiguardian-api-1.0.0-sources.jar b/lib/apiguardian-api-1.0.0-sources.jar
new file mode 100644
index 000000000..8d4c7462b
--- /dev/null
+++ b/lib/apiguardian-api-1.0.0-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:793b50c98fa62e6eec08cc8fa4364b95d4815c1b17ef17e5e9e59c457e54ce2e
+size 2229
diff --git a/lib/apiguardian-api-1.0.0.jar b/lib/apiguardian-api-1.0.0.jar
new file mode 100644
index 000000000..e95586faf
--- /dev/null
+++ b/lib/apiguardian-api-1.0.0.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1f58b77470d8d147a0538d515347dd322f49a83b9e884b8970051160464b65b3
+size 2164
diff --git a/lib/colt-1.2.0.jar b/lib/colt-1.2.0.jar
new file mode 100644
index 000000000..bc481ecd3
--- /dev/null
+++ b/lib/colt-1.2.0.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e1fcbfbdd0d0caedadfb59febace5a62812db3b9425f3a03ef4c4cbba3ed0ee3
+size 581945
diff --git a/lib/common-java5-2.19.1-sources.jar b/lib/common-java5-2.19.1-sources.jar
new file mode 100644
index 000000000..e3601835e
--- /dev/null
+++ b/lib/common-java5-2.19.1-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:52545eb98af7d060f8bed8c3aac2a2714a89d9275efe5ec70205ebe6ca7b552f
+size 12229
diff --git a/lib/common-java5-2.19.1.jar b/lib/common-java5-2.19.1.jar
new file mode 100644
index 000000000..f70aa4437
--- /dev/null
+++ b/lib/common-java5-2.19.1.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:831f47a1fb1446f6bd8653ea4183c4b1601eab943da6c8ec160d7b83b19de1d0
+size 44127
diff --git a/lib/commons-logging-1.2-sources.jar b/lib/commons-logging-1.2-sources.jar
new file mode 100644
index 000000000..a6a1ff1b0
--- /dev/null
+++ b/lib/commons-logging-1.2-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:44347acfe5860461728e9cb33251e97345be36f8a0dfd5c5130c172559455f41
+size 73295
diff --git a/lib/commons-logging-1.2.jar b/lib/commons-logging-1.2.jar
new file mode 100644
index 000000000..13ec090d0
--- /dev/null
+++ b/lib/commons-logging-1.2.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636
+size 61829
diff --git a/lib/concurrent-1.3.4-sources.jar b/lib/concurrent-1.3.4-sources.jar
new file mode 100644
index 000000000..63cec6013
--- /dev/null
+++ b/lib/concurrent-1.3.4-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e728f7fad4bf80d41bcaefa761f1ddeb30cd31226b0f2b58db666bde419342fd
+size 877597
diff --git a/lib/concurrent-1.3.4.jar b/lib/concurrent-1.3.4.jar
new file mode 100644
index 000000000..f158bb98d
--- /dev/null
+++ b/lib/concurrent-1.3.4.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:12639def9a5b5ebf56040ab764bd42b7e662523d3b983e5d5da04bf37be152f9
+size 189284
diff --git a/lib/fontbox-2.0.24-sources.jar b/lib/fontbox-2.0.24-sources.jar
new file mode 100644
index 000000000..71539f75d
--- /dev/null
+++ b/lib/fontbox-2.0.24-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6cac29129a3ab7226cfe7adee6ae9aff0036f30c0d97ef34ec05d6cc499b5d8e
+size 1498085
diff --git a/lib/fontbox-2.0.24.jar b/lib/fontbox-2.0.24.jar
new file mode 100644
index 000000000..1fb98ace7
--- /dev/null
+++ b/lib/fontbox-2.0.24.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2e8c0a569a90b04734fbc0c805d77f4ec03f98c11f5705055ccd7718c1953d68
+size 1564111
diff --git a/lib/graphics2d-0.32-sources.jar b/lib/graphics2d-0.32-sources.jar
new file mode 100644
index 000000000..ea542a293
--- /dev/null
+++ b/lib/graphics2d-0.32-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dfbab3557c66510849814cd82355abdc85fed6423e9ee5dc9bd3a8195e9ef957
+size 43005
diff --git a/lib/graphics2d-0.32.jar b/lib/graphics2d-0.32.jar
new file mode 100644
index 000000000..2adc7257b
--- /dev/null
+++ b/lib/graphics2d-0.32.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:37f8f387395f96c214ac44f7475c7a2e1f832dfc1de289a3610e0ffbf728f679
+size 73911
diff --git a/lib/iirj-1.5-sources.jar b/lib/iirj-1.5-sources.jar
new file mode 100644
index 000000000..6bc7caa86
--- /dev/null
+++ b/lib/iirj-1.5-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2c50069701a12874d5e4b57cd7b79e2d9a54c035b6932c5922c6717a8594d276
+size 26372
diff --git a/lib/iirj-1.5.jar b/lib/iirj-1.5.jar
new file mode 100644
index 000000000..3f7d442dd
--- /dev/null
+++ b/lib/iirj-1.5.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7260d395ce4fc54e96f2f2bbc6211a126a597ebeafb1f761b79895cf76a5f993
+size 30869
diff --git a/lib/jcommon-1.0.15.jar b/lib/jcommon-1.0.15.jar
new file mode 100644
index 000000000..79a4c6895
--- /dev/null
+++ b/lib/jcommon-1.0.15.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:acf524cbcd1ba61db2593b16b75a35fc1c7c58fd4d2d36e16ebb585d0f2cc509
+size 309294
diff --git a/lib/jdsp-2.0.1-sources.jar b/lib/jdsp-2.0.1-sources.jar
new file mode 100644
index 000000000..79c14def9
--- /dev/null
+++ b/lib/jdsp-2.0.1-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:556aa9a146e48c865fd769d19e61aecfc08f5dd271b3847e96ae0977d2a341bb
+size 6273823
diff --git a/lib/jdsp-2.0.1.jar b/lib/jdsp-2.0.1.jar
new file mode 100644
index 000000000..dd7f61bdf
--- /dev/null
+++ b/lib/jdsp-2.0.1.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3214c26541df92935453c4860941ac63bcdc2b0e4dab1fc6c654086f0368e10c
+size 6288038
diff --git a/lib/jfreechart-1.0.12.jar b/lib/jfreechart-1.0.12.jar
new file mode 100644
index 000000000..41b0b52b6
--- /dev/null
+++ b/lib/jfreechart-1.0.12.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b90e35874f89cf910c20214dce84c4906a09b908e4761ac32e248fe1b36102c3
+size 1368681
diff --git a/lib/junit-jupiter-api-5.0.3-sources.jar b/lib/junit-jupiter-api-5.0.3-sources.jar
new file mode 100644
index 000000000..078d0b333
--- /dev/null
+++ b/lib/junit-jupiter-api-5.0.3-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:af50a21c85de863b853e62f5c4612c37ed6397f279f0b45570f60e1357053b1c
+size 77621
diff --git a/lib/junit-jupiter-api-5.0.3.jar b/lib/junit-jupiter-api-5.0.3.jar
new file mode 100644
index 000000000..d8141ce41
--- /dev/null
+++ b/lib/junit-jupiter-api-5.0.3.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7312eb2d7e7950186f487da0bf4ea6004b06204a8726f8f8976965a701815d7e
+size 76193
diff --git a/lib/junit-jupiter-engine-5.0.3-sources.jar b/lib/junit-jupiter-engine-5.0.3-sources.jar
new file mode 100644
index 000000000..75e912777
--- /dev/null
+++ b/lib/junit-jupiter-engine-5.0.3-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:548f645638efa310478934775808b04add8b674012c262e7e149271953ce1e3a
+size 77231
diff --git a/lib/junit-jupiter-engine-5.0.3.jar b/lib/junit-jupiter-engine-5.0.3.jar
new file mode 100644
index 000000000..5f1d2ec85
--- /dev/null
+++ b/lib/junit-jupiter-engine-5.0.3.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ebce96103ba236c716d09ba92622cbf0e2f9d846f2b446afcb5fae246b157e85
+size 119274
diff --git a/lib/junit-platform-commons-1.0.3-sources.jar b/lib/junit-platform-commons-1.0.3-sources.jar
new file mode 100644
index 000000000..6d9f7aa61
--- /dev/null
+++ b/lib/junit-platform-commons-1.0.3-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:70fb33a96ad963a02e40b2357575dbb85888e4d42be6cbc805898ac0e24c920d
+size 50815
diff --git a/lib/junit-platform-commons-1.0.3.jar b/lib/junit-platform-commons-1.0.3.jar
new file mode 100644
index 000000000..27573a14f
--- /dev/null
+++ b/lib/junit-platform-commons-1.0.3.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8fedb05efbe03eb450573c6feec038485c2c97aaf00213be98f43542d3e3a070
+size 62666
diff --git a/lib/junit-platform-engine-1.0.3-sources.jar b/lib/junit-platform-engine-1.0.3-sources.jar
new file mode 100644
index 000000000..8f1322156
--- /dev/null
+++ b/lib/junit-platform-engine-1.0.3-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b123e7ddc1dd78fa6d62ef4355edb8163eef05d60ea98c8ecb2507b7adf1c6a2
+size 77251
diff --git a/lib/junit-platform-engine-1.0.3.jar b/lib/junit-platform-engine-1.0.3.jar
new file mode 100644
index 000000000..713eeafe8
--- /dev/null
+++ b/lib/junit-platform-engine-1.0.3.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eabb36cc5acd989bd33a97f2ef0019a71a06d19cfd5be1cbaf0aa3c1753491a4
+size 87818
diff --git a/lib/junit-platform-launcher-1.0.0-sources.jar b/lib/junit-platform-launcher-1.0.0-sources.jar
new file mode 100644
index 000000000..4404c87a8
--- /dev/null
+++ b/lib/junit-platform-launcher-1.0.0-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c5c1f9dbadcfd91e8ba4ed8ab31fecf4e60b0e2bbaa22b59d4f8c48deeea76a4
+size 39171
diff --git a/lib/junit-platform-launcher-1.0.0.jar b/lib/junit-platform-launcher-1.0.0.jar
new file mode 100644
index 000000000..a3b150da6
--- /dev/null
+++ b/lib/junit-platform-launcher-1.0.0.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6c660f6e41149921e6865d5a7715f08f414eb0a49c96874d3cc9c05ccfcbb0e3
+size 54139
diff --git a/lib/junit-platform-surefire-provider-1.0.0-sources.jar b/lib/junit-platform-surefire-provider-1.0.0-sources.jar
new file mode 100644
index 000000000..f8a5fa362
--- /dev/null
+++ b/lib/junit-platform-surefire-provider-1.0.0-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:baf35c85691648609b2c3394a1870f84bec3c70f38a87df080bcf6160df3a246
+size 10896
diff --git a/lib/junit-platform-surefire-provider-1.0.0.jar b/lib/junit-platform-surefire-provider-1.0.0.jar
new file mode 100644
index 000000000..f6f98fe1f
--- /dev/null
+++ b/lib/junit-platform-surefire-provider-1.0.0.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:02bd3009b1f000733694fcefe3937900b5dee4624255bd8d3896e0dcfa96b246
+size 14927
diff --git a/lib/opentest4j-1.0.0-sources.jar b/lib/opentest4j-1.0.0-sources.jar
new file mode 100644
index 000000000..5a69edffb
--- /dev/null
+++ b/lib/opentest4j-1.0.0-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:68e5bbe7dbe3b8cfe2b98976a3271830a366ac5c5f5a450ed301c6b4f08bb822
+size 7452
diff --git a/lib/opentest4j-1.0.0.jar b/lib/opentest4j-1.0.0.jar
new file mode 100644
index 000000000..c228e5881
--- /dev/null
+++ b/lib/opentest4j-1.0.0.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6a05b14e8764a1fa51551ccef29e7271681d65fa907a8136136b94de92a0b862
+size 6588
diff --git a/lib/optimization-1.3-sources.jar b/lib/optimization-1.3-sources.jar
new file mode 100644
index 000000000..a7289c16d
--- /dev/null
+++ b/lib/optimization-1.3-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4e8e623468f60cfc8712025efd1a026ae3744e654e87fc0328559123e2c9eb2a
+size 93326
diff --git a/lib/optimization-1.3.jar b/lib/optimization-1.3.jar
new file mode 100644
index 000000000..bbec1bf04
--- /dev/null
+++ b/lib/optimization-1.3.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ecdf55d24cbf1ac4c48917f67de82178a128f4ae088de1611c8837acc4dd5f6d
+size 67951
diff --git a/lib/pdfbox-2.0.24-sources.jar b/lib/pdfbox-2.0.24-sources.jar
new file mode 100644
index 000000000..c1de73d9e
--- /dev/null
+++ b/lib/pdfbox-2.0.24-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6f12c05d9ef4cf724910a56d7dd91f9b3b1ad9948a2dd996229207762ce014ff
+size 2566166
diff --git a/lib/pdfbox-2.0.24.jar b/lib/pdfbox-2.0.24.jar
new file mode 100644
index 000000000..5b02e48d3
--- /dev/null
+++ b/lib/pdfbox-2.0.24.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3c2c0553ec0e7533c490b4c952e1af113621de5275af6e380e11d0d9a0a4f3d6
+size 2745079
diff --git a/lib/ssj-3.3.1-sources.jar b/lib/ssj-3.3.1-sources.jar
new file mode 100644
index 000000000..4a1af867d
--- /dev/null
+++ b/lib/ssj-3.3.1-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fddcdf985a76dea70145367419bef2568b039759f2467e492a210568a4a88f3e
+size 1515213
diff --git a/lib/ssj-3.3.1.jar b/lib/ssj-3.3.1.jar
new file mode 100644
index 000000000..a34a944be
--- /dev/null
+++ b/lib/ssj-3.3.1.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:39625d7ddef108b42307583a75346d36300cd64a5c11b944b1681d556fd0180d
+size 1288980
diff --git a/lib/surefire-api-2.19.1-sources.jar b/lib/surefire-api-2.19.1-sources.jar
new file mode 100644
index 000000000..8ab233781
--- /dev/null
+++ b/lib/surefire-api-2.19.1-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:56fa9b514c53b9c2dcac0709a2387ef2276b3f6c4ec0e060eeac1739cb6de88f
+size 112686
diff --git a/lib/surefire-api-2.19.1.jar b/lib/surefire-api-2.19.1.jar
new file mode 100644
index 000000000..51c6b2ffe
--- /dev/null
+++ b/lib/surefire-api-2.19.1.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:de34106fd8799d9cc690aded4eb329c5c2c9f96929b2fea032ec9a5bdf036613
+size 196073
diff --git a/lib/wavfile-0.1-sources.jar b/lib/wavfile-0.1-sources.jar
new file mode 100644
index 000000000..7ae054cb6
--- /dev/null
+++ b/lib/wavfile-0.1-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1918b88fdc32afb9d5e9a2146480e2b63b22173bb7705943e48d8934f7f78fe4
+size 6475
diff --git a/lib/wavfile-0.1.jar b/lib/wavfile-0.1.jar
new file mode 100644
index 000000000..0b2f715db
--- /dev/null
+++ b/lib/wavfile-0.1.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e3f1e1ed4c6b86495d060a135954cbaf1edd3835efc727eafd956c08ce79d982
+size 9831
diff --git a/lib/xchart-3.8.1-sources.jar b/lib/xchart-3.8.1-sources.jar
new file mode 100644
index 000000000..5256905f5
--- /dev/null
+++ b/lib/xchart-3.8.1-sources.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b67dda9dbc481c3270d0b04de58b2926f633b47e1aad91367f317c6c3e6f53b5
+size 194367
diff --git a/lib/xchart-3.8.1.jar b/lib/xchart-3.8.1.jar
new file mode 100644
index 000000000..78c22dea1
--- /dev/null
+++ b/lib/xchart-3.8.1.jar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:610bb64d90bac7d2aeb25e7476d8b8df3d0f484315442dcab62685ff707c5ba5
+size 364996
diff --git a/src/net/torvald/terrarum/audio/AudioMixer.kt b/src/net/torvald/terrarum/audio/AudioMixer.kt
index a1df2e47c..f329d6b87 100644
--- a/src/net/torvald/terrarum/audio/AudioMixer.kt
+++ b/src/net/torvald/terrarum/audio/AudioMixer.kt
@@ -6,6 +6,7 @@ import com.badlogic.gdx.backends.lwjgl3.audio.Lwjgl3Audio
import com.badlogic.gdx.utils.Disposable
import com.jme3.math.FastMath
import net.torvald.terrarum.App
+import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATE
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
import net.torvald.terrarum.modulebasegame.MusicContainer
@@ -102,7 +103,7 @@ object AudioMixer: Disposable {
init {
// musicTrack.filters[0] = BinoPan((Math.random() * 2.0 - 1.0).toFloat())
- musicTrack.filters[1] = Reverb(36f, 0.92f, 1200f)
+// musicTrack.filters[1] = Reverb(36f, 0.92f, 1200f)
masterTrack.filters[0] = SoftClp
masterTrack.filters[1] = Buffer
@@ -112,6 +113,7 @@ object AudioMixer: Disposable {
fadeBus.addSidechainInput(ambientTrack, 1.0)
fadeBus.addSidechainInput(sfxMixTrack, 1.0)
fadeBus.filters[0] = Lowpass(SAMPLING_RATE / 2f)
+ fadeBus.filters[1] = Convolv(ModMgr.getFile("basegame", "audio/convolution/EchoThief - TransitCenter.bin"))
masterTrack.addSidechainInput(fadeBus, 1.0)
masterTrack.addSidechainInput(guiTrack, 1.0)
diff --git a/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt b/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt
index e7b4394f1..2ed9603fd 100644
--- a/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt
+++ b/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt
@@ -1,11 +1,16 @@
package net.torvald.terrarum.audio
+import com.github.psambit9791.jdsp.transform.FastFourier
+import com.github.psambit9791.jdsp.transform.InverseFastFourier
import com.jme3.math.FastMath
import com.jme3.math.FastMath.sin
import net.torvald.terrarum.audio.AudioMixer.SPEED_OF_SOUND
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.BUFFER_SIZE
+import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATED
import net.torvald.terrarum.audio.TerrarumAudioMixerTrack.Companion.SAMPLING_RATEF
import net.torvald.terrarum.roundToFloat
+import org.apache.commons.math3.complex.Complex
+import java.io.File
import kotlin.math.absoluteValue
import kotlin.math.roundToInt
import kotlin.math.tanh
@@ -293,6 +298,119 @@ class Reverb(val delayMS: Float = 36f, var feedback: Float = 0.92f, var lowpass:
}
}
+class Convolv(ir: File, val gain: Float = decibelsToFullscale(-12.0).toFloat()): TerrarumAudioFilter() {
+
+ private val fftLen: Int
+ private val convFFT: Array>
+ private val inbuf: Array
+// private val outbuf: Array
+
+ private val BLOCKSIZE = BUFFER_SIZE / 4
+
+ init {
+ if (!ir.exists()) {
+ throw IllegalArgumentException("Impulse Response file '${ir.path}' does not exist.")
+ }
+
+ val sampleCount = ir.length().toInt() / 8
+ fftLen = FastMath.nextPowerOfTwo(sampleCount)
+
+ println("IR Sample Count = $sampleCount; FFT Length = $fftLen")
+
+ val conv = Array(2) { DoubleArray(fftLen) }
+ inbuf = Array(2) { DoubleArray(fftLen) }
+// outbuf = Array(2) { DoubleArray(fftLen) }
+
+ ir.inputStream().let {
+ for (i in 0 until sampleCount) {
+ val f1 = Float.fromBits(it.read().and(255) or
+ it.read().and(255).shl(8) or
+ it.read().and(255).shl(16) or
+ it.read().and(255).shl(24))
+ val f2 = Float.fromBits(it.read().and(255) or
+ it.read().and(255).shl(8) or
+ it.read().and(255).shl(16) or
+ it.read().and(255).shl(24))
+ conv[0][i] = f1.toDouble()
+ conv[1][i] = f2.toDouble()
+ }
+
+ it.close()
+ }
+
+ // fourier-transform the 'conv'
+ convFFT = Array(2) {
+ FastFourier(conv[it]).let { it.transform(); it.getComplex(false) }
+ }
+
+ println("convFFT Length = ${convFFT[0].size}")
+ }
+
+ /**
+ * https://thewolfsound.com/fast-convolution-fft-based-overlap-add-overlap-save-partitioned/
+ */
+ override fun thru(inbuf0: List, inbuf1: List, outbuf0: List, outbuf1: List) {
+// println("Convolv thru")
+
+ val t1 = System.nanoTime()
+ for (ch in outbuf1.indices) {
+
+ push(inbuf1[ch].toDoubleArray(), inbuf[ch])
+
+ val inputFFT = FastFourier(inbuf[ch]).let { it.transform(); it.getComplex(false) }
+
+ val Ny = inputFFT.size// + convFFT[ch].size - 1
+
+// println("inputFFT.size=${inputFFT.size} convFFT[ch].size=${convFFT[ch].size} Ny=$Ny")
+
+ val Y = multiply(inputFFT, convFFT[ch])
+ val y = real(ifft(Y))
+
+ val u = y.sliceArray(Ny - BLOCKSIZE until Ny).toFloatArray(gain)
+
+ System.arraycopy(u, 0, outbuf1[ch], 0, BLOCKSIZE)
+ }
+ val t2 = System.nanoTime()
+ val ptime = (t2 - t1).toDouble()
+ val realtime = BLOCKSIZE / SAMPLING_RATED * 1000000000L
+ if (realtime >= ptime) {
+ println("Processing speed: ${realtime / ptime}x FASTER than realtime")
+ }
+ else {
+ println("Processing speed: ${ptime / realtime}x SLOWER than realtime")
+ }
+ }
+
+ private fun real(cs: Array): DoubleArray {
+ return cs.map { it.real }.toDoubleArray()
+ }
+
+ private fun ifft(y: Array): Array {
+ return InverseFastFourier(y, false).let { it.transform(); it.complex }
+ }
+
+ private fun multiply(X: Array, H: Array): Array {
+ if (X.size != H.size) throw IllegalArgumentException()
+ return Array(X.size) {
+ X[it].multiply(H[it])
+ }
+ }
+
+
+ private fun push(sample: Double, buf: DoubleArray) {
+ System.arraycopy(buf, 1, buf, 0, buf.size - 1)
+ buf[buf.lastIndex] = sample
+ }
+
+ private fun push(samples: DoubleArray, buf: DoubleArray) {
+ System.arraycopy(buf, samples.size, buf, 0, buf.size - samples.size)
+ System.arraycopy(samples, 0, buf, buf.size - samples.size - 1, samples.size)
+ }
+
+ private fun FloatArray.toDoubleArray() = this.map { it.toDouble() }.toDoubleArray()
+ private fun DoubleArray.toFloatArray(gain: Float = 1f) = this.map { it.toFloat() * gain }.toFloatArray()
+}
+
object XYtoMS: TerrarumAudioFilter() {
override fun thru(inbuf0: List, inbuf1: List, outbuf0: List, outbuf1: List) {
for (i in 0 until BUFFER_SIZE / 4) {
diff --git a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt
index 3b0918283..37378183c 100644
--- a/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt
+++ b/src/net/torvald/terrarum/ui/BasicDebugInfoWindow.kt
@@ -404,7 +404,7 @@ class BasicDebugInfoWindow : UICanvas() {
private val meterTroughHeight = 16 * 11 + 5
private val meterHeight = meterTroughHeight - 4
- private val trackCount = (AudioMixer.tracks + AudioMixer.masterTrack).size
+ private val trackCount = 64//(AudioMixer.tracks + AudioMixer.masterTrack).size
private val mixerLastTimeHadClipping = Array(trackCount) { arrayOf(0L, 0L) }
private val clippingHoldTime = 60000L * 3 // 3 mins