diff --git a/COPYING.md b/COPYING.md
index d9adde496..c190b5bbd 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -1,5 +1,3 @@
-*Terrarum*
-
Copyright (C) 2013-2023 Minjae Song ("CuriousTorvald")
This program is free software: you can redistribute it and/or modify
@@ -14,598 +12,3 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
-
-----
-
-*Terrarum Sans Bitmap*
-
-Copyright (c) 2017-2022 Minjae Song ("CuriousTorvald") and the contributors
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-----
-
-*Joise*
-
-Copyright (C) 2013 Jason Taylor
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-*Accidental Noise Library*
-
-Joise is a derivative work based on Josua Tippetts' C++ library:
-
-
-Copyright (C) 2011 Joshua Tippetts
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
-----
-
-*Vector2.java*, *Epsilon.java*
-
-Copyright (c) 2010-2015 William Bittle
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted
-provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this list of conditions
- and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
- and the following disclaimer in the documentation and/or other materials provided with the
- distribution.
-* Neither the name of dyn4j nor the names of its contributors may be used to endorse or
- promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Kotlin translated and modified code Copyright (C) 2016 Minjae Song ("CuriousTorvald")
-
-----
-
-*PRTree*, a Priority R-Tree, a spatial index for java code
-
-Copyright (c) 2008-2012 Robert Olofsson.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-3. Neither the name of the authors nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-----
-
-*HUSLColorConverter.java*
-
-Copyright (c) 2016 Alexei Boronine
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----
-
-Ambient sound recordings:
-
- ambient_forest_01.ogg
- ambient_meadow_01.ogg
- ambient_windy_01.ogg
- ambient_woods_01.ogg
- crickets_01.ogg
- crickets_02.ogg
-
-Copyright (C) 2012, 2013, 2015, 2016, 2017 Klankbeeld
-Sound from
-
-----
-
- Product License - GraalVM Community Edition
-
-This is a release of GraalVM Community Edition. GraalVM Community Edition
-consists of multiple modules. The software as a whole, as well as the JVMCI
-and VisualVM modules, are released under version 2 of the GNU General Public
-License with the “Classpath” Exception.
-The text of the foregoing licenses is reproduced below.
-
-Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
-
-===========================================================================
-
-The GNU General Public License (GPL)
-
-Version 2, June 1991
-
-Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Everyone is permitted to copy and distribute verbatim copies of this license
-document, but changing it is not allowed.
-
-Preamble
-
-The licenses for most software are designed to take away your freedom to share
-and change it. By contrast, the GNU General Public License is intended to
-guarantee your freedom to share and change free software--to make sure the
-software is free for all its users. This General Public License applies to
-most of the Free Software Foundation's software and to any other program whose
-authors commit to using it. (Some other Free Software Foundation software is
-covered by the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
-When we speak of free software, we are referring to freedom, not price. Our
-General Public Licenses are designed to make sure that you have the freedom to
-distribute copies of free software (and charge for this service if you wish),
-that you receive source code or can get it if you want it, that you can change
-the software or use pieces of it in new free programs; and that you know you
-can do these things.
-
-To protect your rights, we need to make restrictions that forbid anyone to deny
-you these rights or to ask you to surrender the rights. These restrictions
-translate to certain responsibilities for you if you distribute copies of the
-software, or if you modify it.
-
-For example, if you distribute copies of such a program, whether gratis or for
-a fee, you must give the recipients all the rights that you have. You must
-make sure that they, too, receive or can get the source code. And you must
-show them these terms so they know their rights.
-
-We protect your rights with two steps: (1) copyright the software, and (2)
-offer you this license which gives you legal permission to copy, distribute
-and/or modify the software.
-
-Also, for each author's protection and ours, we want to make certain that
-everyone understands that there is no warranty for this free software. If the
-software is modified by someone else and passed on, we want its recipients to
-know that what they have is not the original, so that any problems introduced
-by others will not reflect on the original authors' reputations.
-
-Finally, any free program is threatened constantly by software patents. We
-wish to avoid the danger that redistributors of a free program will
-individually obtain patent licenses, in effect making the program proprietary.
-To prevent this, we have made it clear that any patent must be licensed for
-everyone's free use or not licensed at all.
-
-The precise terms and conditions for copying, distribution and modification
-follow.
-
-TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-0. This License applies to any program or other work which contains a notice
- placed by the copyright holder saying it may be distributed under the terms of
- this General Public License. The "Program", below, refers to any such program
- or work, and a "work based on the Program" means either the Program or any
- derivative work under copyright law: that is to say, a work containing the
- Program or a portion of it, either verbatim or with modifications and/or
- translated into another language. (Hereinafter, translation is included
- without limitation in the term "modification".) Each licensee is addressed as
- "you".
-
-Activities other than copying, distribution and modification are not covered by
-this License; they are outside its scope. The act of running the Program is
-not restricted, and the output from the Program is covered only if its contents
-constitute a work based on the Program (independent of having been made by
-running the Program). Whether that is true depends on what the Program does.
-
-1. You may copy and distribute verbatim copies of the Program's source code as
- you receive it, in any medium, provided that you conspicuously and
- appropriately publish on each copy an appropriate copyright notice and
- disclaimer of warranty; keep intact all the notices that refer to this License
- and to the absence of any warranty; and give any other recipients of the
- Program a copy of this License along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and you may
-at your option offer warranty protection in exchange for a fee.
-
-2. You may modify your copy or copies of the Program or any portion of it, thus
- forming a work based on the Program, and copy and distribute such modifications
- or work under the terms of Section 1 above, provided that you also meet all of
- these conditions:
-
- a) You must cause the modified files to carry prominent notices stating
- that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in whole or
- in part contains or is derived from the Program or any part thereof, to be
- licensed as a whole at no charge to all third parties under the terms of
- this License.
-
- c) If the modified program normally reads commands interactively when run,
- you must cause it, when started running for such interactive use in the
- most ordinary way, to print or display an announcement including an
- appropriate copyright notice and a notice that there is no warranty (or
- else, saying that you provide a warranty) and that users may redistribute
- the program under these conditions, and telling the user how to view a copy
- of this License. (Exception: if the Program itself is interactive but does
- not normally print such an announcement, your work based on the Program is
- not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If identifiable
-sections of that work are not derived from the Program, and can be reasonably
-considered independent and separate works in themselves, then this License, and
-its terms, do not apply to those sections when you distribute them as separate
-works. But when you distribute the same sections as part of a whole which is a
-work based on the Program, the distribution of the whole must be on the terms
-of this License, whose permissions for other licensees extend to the entire
-whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest your
-rights to work written entirely by you; rather, the intent is to exercise the
-right to control the distribution of derivative or collective works based on
-the Program.
-
-In addition, mere aggregation of another work not based on the Program with the
-Program (or with a work based on the Program) on a volume of a storage or
-distribution medium does not bring the other work under the scope of this
-License.
-
-3. You may copy and distribute the Program (or a work based on it, under
- Section 2) in object code or executable form under the terms of Sections 1 and
- 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable source
- code, which must be distributed under the terms of Sections 1 and 2 above
- on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three years, to
- give any third party, for a charge no more than your cost of physically
- performing source distribution, a complete machine-readable copy of the
- corresponding source code, to be distributed under the terms of Sections 1
- and 2 above on a medium customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer to
- distribute corresponding source code. (This alternative is allowed only
- for noncommercial distribution and only if you received the program in
- object code or executable form with such an offer, in accord with
- Subsection b above.)
-
-The source code for a work means the preferred form of the work for making
-modifications to it. For an executable work, complete source code means all
-the source code for all modules it contains, plus any associated interface
-definition files, plus the scripts used to control compilation and installation
-of the executable. However, as a special exception, the source code
-distributed need not include anything that is normally distributed (in either
-source or binary form) with the major components (compiler, kernel, and so on)
-of the operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the source
-code from the same place counts as distribution of the source code, even though
-third parties are not compelled to copy the source along with the object code.
-
-4. You may not copy, modify, sublicense, or distribute the Program except as
- expressly provided under this License. Any attempt otherwise to copy, modify,
- sublicense or distribute the Program is void, and will automatically terminate
- your rights under this License. However, parties who have received copies, or
- rights, from you under this License will not have their licenses terminated so
- long as such parties remain in full compliance.
-
-5. You are not required to accept this License, since you have not signed it.
- However, nothing else grants you permission to modify or distribute the Program
- or its derivative works. These actions are prohibited by law if you do not
- accept this License. Therefore, by modifying or distributing the Program (or
- any work based on the Program), you indicate your acceptance of this License to
- do so, and all its terms and conditions for copying, distributing or modifying
- the Program or works based on it.
-
-6. Each time you redistribute the Program (or any work based on the Program),
- the recipient automatically receives a license from the original licensor to
- copy, distribute or modify the Program subject to these terms and conditions.
- You may not impose any further restrictions on the recipients' exercise of the
- rights granted herein. You are not responsible for enforcing compliance by
- third parties to this License.
-
-7. If, as a consequence of a court judgment or allegation of patent
- infringement or for any other reason (not limited to patent issues), conditions
- are imposed on you (whether by court order, agreement or otherwise) that
- contradict the conditions of this License, they do not excuse you from the
- conditions of this License. If you cannot distribute so as to satisfy
- simultaneously your obligations under this License and any other pertinent
- obligations, then as a consequence you may not distribute the Program at all.
- For example, if a patent license would not permit royalty-free redistribution
- of the Program by all those who receive copies directly or indirectly through
- you, then the only way you could satisfy both it and this License would be to
- refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply and
-the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any patents or
-other property right claims or to contest validity of any such claims; this
-section has the sole purpose of protecting the integrity of the free software
-distribution system, which is implemented by public license practices. Many
-people have made generous contributions to the wide range of software
-distributed through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing to
-distribute software through any other system and a licensee cannot impose that
-choice.
-
-This section is intended to make thoroughly clear what is believed to be a
-consequence of the rest of this License.
-
-8. If the distribution and/or use of the Program is restricted in certain
- countries either by patents or by copyrighted interfaces, the original
- copyright holder who places the Program under this License may add an explicit
- geographical distribution limitation excluding those countries, so that
- distribution is permitted only in or among countries not thus excluded. In
- such case, this License incorporates the limitation as if written in the body
- of this License.
-
-9. The Free Software Foundation may publish revised and/or new versions of the
- General Public License from time to time. Such new versions will be similar in
- spirit to the present version, but may differ in detail to address new problems
- or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any later
-version", you have the option of following the terms and conditions either of
-that version or of any later version published by the Free Software Foundation.
-If the Program does not specify a version number of this License, you may
-choose any version ever published by the Free Software Foundation.
-
-10. If you wish to incorporate parts of the Program into other free programs
- whose distribution conditions are different, write to the author to ask for
- permission. For software which is copyrighted by the Free Software Foundation,
- write to the Free Software Foundation; we sometimes make exceptions for this.
- Our decision will be guided by the two goals of preserving the free status of
- all derivatives of our free software and of promoting the sharing and reuse of
- software generally.
-
-NO WARRANTY
-
-11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
- THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
- STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
- PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
- PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
- YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
- ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
- PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
- GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
- FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
- OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-END OF TERMS AND CONDITIONS
-
-How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest possible
-use to the public, the best way to achieve this is to make it free software
-which everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program. It is safest to attach
-them to the start of each source file to most effectively convey the exclusion
-of warranty; and each file should have at least the "copyright" line and a
-pointer to where the full notice is found.
-
- One line to give the program's name and a brief idea of what it does.
-
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc., 59
- Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this when it
-starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
- with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free
- software, and you are welcome to redistribute it under certain conditions;
- type 'show c' for details.
-
-The hypothetical commands 'show w' and 'show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may be
-called something other than 'show w' and 'show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your school,
-if any, to sign a "copyright disclaimer" for the program, if necessary. Here
-is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- 'Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- signature of Ty Coon, 1 April 1989
-
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General Public
-License instead of this License.
-
-
-"CLASSPATH" EXCEPTION TO THE GPL
-
-Certain source files distributed by Oracle America and/or its affiliates
-are subject to the following clarification and special exception to the GPLv2,
-based on the GNU Project exception for its Classpath libraries, known as the
-GNU Classpath Exception, but only where Oracle has expressly included in the
-particular source file's header the words "Oracle designates this particular
-file as subject to the "Classpath" exception as provided by Oracle in the
-LICENSE file that accompanied this code."
-
-You should also note that Oracle includes multiple, independent programs in
-this software package. Some of those programs are provided under licenses
-deemed incompatible with the GPLv2 by the Free Software Foundation and others.
-For example, the package includes programs licensed under the Apache License,
-Version 2.0. Such programs are licensed to you under their original licenses.
-
-Oracle facilitates your further distribution of this package by adding the
-Classpath Exception to the necessary parts of its GPLv2 code, which permits you
-to use that code in combination with other independent modules not licensed
-under the GPLv2. However, note that this would not permit you to commingle code
-under an incompatible license with Oracle's GPLv2 licensed code by, for
-example, cutting and pasting such code into a file also containing Oracle's
-GPLv2 licensed code and then distributing the result.
-
-Additionally, if you were to remove the Classpath Exception from any of the
-files to which it applies and distribute the result, you would likely be
-required to license some or all of the other code in that distribution under
-the GPLv2 as well, and since the GPLv2 is incompatible with the license terms
-of some items included in the distribution by Oracle, removing the Classpath
-Exception could therefore effectively compromise your ability to further
-distribute the package.
-
-Proceed with caution and we recommend that you obtain the advice of a lawyer
-skilled in open source matters before removing the Classpath Exception or
-making modifications to this package which may subsequently be redistributed
-and/or involve the use of third party software.
-
-CLASSPATH EXCEPTION
-
-Linking this library statically or dynamically with other modules is making a
-combined work based on this library. Thus, the terms and conditions of the GNU
-General Public License version 2 cover the whole combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent modules, and
-to copy and distribute the resulting executable under terms of your choice,
-provided that you also meet, for each linked independent module, the terms and
-conditions of the license of that module. An independent module is a module
-which is not derived from or based on this library. If you modify this library,
-you may extend this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this exception
-statement from your version.
-
-===========================================================================
-
- WRITTEN OFFER FOR SOURCE CODE
-For any software that you receive from Oracle in binary form which is licensed
-under an open source license that gives you the right to receive the source
-code for that binary, you can obtain a copy of the applicable source code by
-visiting http://www.oracle.com/goto/opensourcecode. If the source code for the
-binary was not provided to you with the binary, you can also receive a copy of
-the source code on physical media by submitting a written request to the
-address listed below or by sending an email to Oracle using the following link:
-http://www.oracle.com/goto/opensourcecode/request.
-
-Oracle America, Inc.
-Attn: Senior Vice President
-Development and Engineering Legal
-500 Oracle Parkway, 10th Floor
-Redwood Shores, CA 94065
-
-Your request should include:
-• The name of the binary for which you are requesting the source code
-• The name and version number of the Oracle product containing the binary
-• The date you received the Oracle product
-• Your name
-• Your company name (if applicable)
-• Your return mailing address and email, and
-• A telephone number in the event we need to reach you.
-
-We may charge you a fee to cover the cost of physical media and processing.
-Your request must be sent
-a. within three (3) years of the date you received the Oracle product that
-included the binary that is the subject of your request, or
-b. in the case of code licensed under the GPL v3 for as long as Oracle
-offers spare parts or customer support for that product model.
-
-===========================================================================
diff --git a/src/net/torvald/terrarum/CreditSingleton.kt b/src/net/torvald/terrarum/CreditSingleton.kt
index 8e2af4c02..25c9bfe6e 100644
--- a/src/net/torvald/terrarum/CreditSingleton.kt
+++ b/src/net/torvald/terrarum/CreditSingleton.kt
@@ -221,6 +221,67 @@ as well as the JVMCI and VisualVM modules, are released under version 2 of the
GNU General Public License with the “Classpath” Exception.
Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+
+
+
+
+
+$BULLET Jdsp
+
+Copyright (c) 2019 Sambit Paul
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+
+
+
+$BULLET Apache Commons Codec
+Copyright 2002-2023 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (https://www.apache.org/).
+
+
+
+
+
+$BULLET Apache Commons CSV
+Copyright 2005-2023 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (https://www.apache.org/).
+
+
+
+
+
+$BULLET Apache Commons Math
+
+Copyright 2001-2022 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This product includes software developed for Orekit by
+CS Systèmes d'Information (http://www.c-s.fr/)
+Copyright 2010-2012 CS Systèmes d'Information
""").split('\n')
diff --git a/src/net/torvald/terrarum/audio/FFT.kt b/src/net/torvald/terrarum/audio/FFT.kt
new file mode 100644
index 000000000..b62ee26af
--- /dev/null
+++ b/src/net/torvald/terrarum/audio/FFT.kt
@@ -0,0 +1,304 @@
+package net.torvald.terrarum.audio
+
+import org.apache.commons.math3.exception.MathIllegalStateException
+import org.apache.commons.math3.transform.DftNormalization
+import org.apache.commons.math3.transform.TransformType
+import org.apache.commons.math3.util.FastMath
+
+data class FComplex(var real: Float = 0f, var imaginary: Float = 0f) {
+ operator fun times(other: FComplex) = FComplex(
+ this.real * other.real - this.imaginary * other.imaginary,
+ this.real * other.imaginary + this.imaginary * other.real
+ )
+}
+
+/**
+ * Modification of the code form JDSP and Apache Commons Math
+ *
+ * Created by minjaesong on 2023-11-25.
+ */
+object FFT {
+
+ // org.apache.commons.math3.transform.FastFouriesTransformer.java:370
+ fun fft(signal: FloatArray): Array {
+ val dataRI = arrayOf(signal.copyOf(), FloatArray(signal.size))
+
+ transformInPlace(dataRI, DftNormalization.STANDARD, TransformType.FORWARD)
+
+ val output = dataRI.toComplexArray()
+
+ return getComplex(output, false)
+ }
+
+ // org.apache.commons.math3.transform.FastFouriesTransformer.java:404
+ fun ifftAndGetReal(y: Array): FloatArray {
+ val dataRI = Array(2) { FloatArray(y.size) }
+ for (i in y.indices) {
+ dataRI[0][i] = y[i].real
+ dataRI[1][i] = y[i].imaginary
+ }
+
+ transformInPlace(dataRI, DftNormalization.STANDARD, TransformType.INVERSE)
+
+ return dataRI[0]
+ }
+
+ private fun Array.toComplexArray(): Array {
+ return Array(this[0].size) {
+ FComplex(this[0][it], this[1][it])
+ }
+ }
+
+ // com.github.psambit9791.jdsp.transform.FastFourier.java:190
+ /**
+ * Returns the complex value of the fast fourier transformed sequence
+ * @param onlyPositive Set to True if non-mirrored output is required
+ * @throws java.lang.ExceptionInInitializerError if called before executing transform() method
+ * @return Complex[] The complex FFT output
+ */
+ @Throws(ExceptionInInitializerError::class)
+ fun getComplex(output: Array, onlyPositive: Boolean): Array {
+ val dftout: Array = if (onlyPositive) {
+ val numBins: Int = output.size / 2 + 1
+ Array(numBins) { FComplex() }
+ }
+ else {
+ Array(output.size) { FComplex() }
+ }
+ System.arraycopy(output, 0, dftout, 0, dftout.size)
+ return dftout
+ }
+
+ // org.apache.commons.math3.transform.FastFouriesTransformer.java:214
+ /**
+ * Computes the standard transform of the specified complex data. The
+ * computation is done in place. The input data is laid out as follows
+ *
+ * - {@code dataRI[0][i]} is the real part of the {@code i}-th data point,
+ * - {@code dataRI[1][i]} is the imaginary part of the {@code i}-th data point.
+ *
+ *
+ * @param dataRI the two dimensional array of real and imaginary parts of the data
+ * @param normalization the normalization to be applied to the transformed data
+ * @param type the type of transform (forward, inverse) to be performed
+ * @throws DimensionMismatchException if the number of rows of the specified
+ * array is not two, or the array is not rectangular
+ * @throws MathIllegalArgumentException if the number of data points is not
+ * a power of two
+ */
+ private fun transformInPlace(dataRI: Array, normalization: DftNormalization, type: TransformType) {
+ val dataR = dataRI[0]
+ val dataI = dataRI[1]
+ val n = dataR.size
+
+ if (n == 1) {
+ return
+ }
+ else if (n == 2) {
+ val srcR0 = dataR[0]
+ val srcI0 = dataI[0]
+ val srcR1 = dataR[1]
+ val srcI1 = dataI[1]
+
+ // X_0 = x_0 + x_1
+ dataR[0] = srcR0 + srcR1
+ dataI[0] = srcI0 + srcI1
+ // X_1 = x_0 - x_1
+ dataR[1] = srcR0 - srcR1
+ dataI[1] = srcI0 - srcI1
+ normalizeTransformedData(dataRI, normalization, type)
+ return
+ }
+
+ bitReversalShuffle2(dataR, dataI)
+
+ // Do 4-term DFT.
+
+ // Do 4-term DFT.
+ if (type == TransformType.INVERSE) {
+ var i0 = 0
+ while (i0 < n) {
+ val i1 = i0 + 1
+ val i2 = i0 + 2
+ val i3 = i0 + 3
+ val srcR0 = dataR[i0]
+ val srcI0 = dataI[i0]
+ val srcR1 = dataR[i2]
+ val srcI1 = dataI[i2]
+ val srcR2 = dataR[i1]
+ val srcI2 = dataI[i1]
+ val srcR3 = dataR[i3]
+ val srcI3 = dataI[i3]
+
+ // 4-term DFT
+ // X_0 = x_0 + x_1 + x_2 + x_3
+ dataR[i0] = srcR0 + srcR1 + srcR2 + srcR3
+ dataI[i0] = srcI0 + srcI1 + srcI2 + srcI3
+ // X_1 = x_0 - x_2 + j * (x_3 - x_1)
+ dataR[i1] = srcR0 - srcR2 + (srcI3 - srcI1)
+ dataI[i1] = srcI0 - srcI2 + (srcR1 - srcR3)
+ // X_2 = x_0 - x_1 + x_2 - x_3
+ dataR[i2] = srcR0 - srcR1 + srcR2 - srcR3
+ dataI[i2] = srcI0 - srcI1 + srcI2 - srcI3
+ // X_3 = x_0 - x_2 + j * (x_1 - x_3)
+ dataR[i3] = srcR0 - srcR2 + (srcI1 - srcI3)
+ dataI[i3] = srcI0 - srcI2 + (srcR3 - srcR1)
+ i0 += 4
+ }
+ }
+ else {
+ var i0 = 0
+ while (i0 < n) {
+ val i1 = i0 + 1
+ val i2 = i0 + 2
+ val i3 = i0 + 3
+ val srcR0 = dataR[i0]
+ val srcI0 = dataI[i0]
+ val srcR1 = dataR[i2]
+ val srcI1 = dataI[i2]
+ val srcR2 = dataR[i1]
+ val srcI2 = dataI[i1]
+ val srcR3 = dataR[i3]
+ val srcI3 = dataI[i3]
+
+ // 4-term DFT
+ // X_0 = x_0 + x_1 + x_2 + x_3
+ dataR[i0] = srcR0 + srcR1 + srcR2 + srcR3
+ dataI[i0] = srcI0 + srcI1 + srcI2 + srcI3
+ // X_1 = x_0 - x_2 + j * (x_3 - x_1)
+ dataR[i1] = srcR0 - srcR2 + (srcI1 - srcI3)
+ dataI[i1] = srcI0 - srcI2 + (srcR3 - srcR1)
+ // X_2 = x_0 - x_1 + x_2 - x_3
+ dataR[i2] = srcR0 - srcR1 + srcR2 - srcR3
+ dataI[i2] = srcI0 - srcI1 + srcI2 - srcI3
+ // X_3 = x_0 - x_2 + j * (x_1 - x_3)
+ dataR[i3] = srcR0 - srcR2 + (srcI3 - srcI1)
+ dataI[i3] = srcI0 - srcI2 + (srcR1 - srcR3)
+ i0 += 4
+ }
+ }
+
+ var lastN0 = 4
+ var lastLogN0 = 2
+ while (lastN0 < n) {
+ val n0 = lastN0 shl 1
+ val logN0 = lastLogN0 + 1
+ val wSubN0R = W_SUB_N_R[logN0]
+ var wSubN0I = W_SUB_N_I[logN0]
+ if (type == TransformType.INVERSE) {
+ wSubN0I = -wSubN0I
+ }
+
+ // Combine even/odd transforms of size lastN0 into a transform of size N0 (lastN0 * 2).
+ var destEvenStartIndex = 0
+ while (destEvenStartIndex < n) {
+ val destOddStartIndex = destEvenStartIndex + lastN0
+ var wSubN0ToRR = 1f
+ var wSubN0ToRI = 0f
+ for (r in 0 until lastN0) {
+ val grR = dataR[destEvenStartIndex + r]
+ val grI = dataI[destEvenStartIndex + r]
+ val hrR = dataR[destOddStartIndex + r]
+ val hrI = dataI[destOddStartIndex + r]
+
+ // dest[destEvenStartIndex + r] = Gr + WsubN0ToR * Hr
+ dataR[destEvenStartIndex + r] = grR + wSubN0ToRR * hrR - wSubN0ToRI * hrI
+ dataI[destEvenStartIndex + r] = grI + wSubN0ToRR * hrI + wSubN0ToRI * hrR
+ // dest[destOddStartIndex + r] = Gr - WsubN0ToR * Hr
+ dataR[destOddStartIndex + r] = grR - (wSubN0ToRR * hrR - wSubN0ToRI * hrI)
+ dataI[destOddStartIndex + r] = grI - (wSubN0ToRR * hrI + wSubN0ToRI * hrR)
+
+ // WsubN0ToR *= WsubN0R
+ val nextWsubN0ToRR = wSubN0ToRR * wSubN0R - wSubN0ToRI * wSubN0I
+ val nextWsubN0ToRI = wSubN0ToRR * wSubN0I + wSubN0ToRI * wSubN0R
+ wSubN0ToRR = nextWsubN0ToRR
+ wSubN0ToRI = nextWsubN0ToRI
+ }
+ destEvenStartIndex += n0
+ }
+ lastN0 = n0
+ lastLogN0 = logN0
+ }
+
+ normalizeTransformedData(dataRI, normalization, type)
+ }
+
+
+ /**
+ * Applies the proper normalization to the specified transformed data.
+ *
+ * @param dataRI the unscaled transformed data
+ * @param normalization the normalization to be applied
+ * @param type the type of transform (forward, inverse) which resulted in the specified data
+ */
+ private fun normalizeTransformedData(
+ dataRI: Array,
+ normalization: DftNormalization, type: TransformType
+ ) {
+ val dataR = dataRI[0]
+ val dataI = dataRI[1]
+ val n = dataR.size
+ assert(dataI.size == n)
+ when (normalization) {
+ DftNormalization.STANDARD -> if (type == TransformType.INVERSE) {
+ val scaleFactor = 1f / n.toFloat()
+ var i = 0
+ while (i < n) {
+ dataR[i] *= scaleFactor
+ dataI[i] *= scaleFactor
+ i++
+ }
+ }
+
+ DftNormalization.UNITARY -> {
+ val scaleFactor = (1.0 / FastMath.sqrt(n.toDouble())).toFloat()
+ var i = 0
+ while (i < n) {
+ dataR[i] *= scaleFactor
+ dataI[i] *= scaleFactor
+ i++
+ }
+ }
+
+ else -> throw MathIllegalStateException()
+ }
+ }
+
+ /**
+ * Performs identical index bit reversal shuffles on two arrays of identical
+ * size. Each element in the array is swapped with another element based on
+ * the bit-reversal of the index. For example, in an array with length 16,
+ * item at binary index 0011 (decimal 3) would be swapped with the item at
+ * binary index 1100 (decimal 12).
+ *
+ * @param a the first array to be shuffled
+ * @param b the second array to be shuffled
+ */
+ private fun bitReversalShuffle2(a: FloatArray, b: FloatArray) {
+ val n = a.size
+ assert(b.size == n)
+ val halfOfN = n shr 1
+ var j = 0
+ for (i in 0 until n) {
+ if (i < j) {
+ // swap indices i & j
+ var temp = a[i]
+ a[i] = a[j]
+ a[j] = temp
+ temp = b[i]
+ b[i] = b[j]
+ b[j] = temp
+ }
+ var k = halfOfN
+ while (k in 1..j) {
+ j -= k
+ k = k shr 1
+ }
+ j += k
+ }
+ }
+
+ private val W_SUB_N_R = FFTConsts.W_SUB_N_R.map { it.toFloat() }.toFloatArray()
+ private val W_SUB_N_I = FFTConsts.W_SUB_N_I.map { it.toFloat() }.toFloatArray()
+
+}
\ No newline at end of file
diff --git a/src/net/torvald/terrarum/audio/FFTConsts.java b/src/net/torvald/terrarum/audio/FFTConsts.java
new file mode 100644
index 000000000..cf2768bd6
--- /dev/null
+++ b/src/net/torvald/terrarum/audio/FFTConsts.java
@@ -0,0 +1,55 @@
+package net.torvald.terrarum.audio;
+
+/**
+ * Created by minjaesong on 2023-11-25.
+ */
+public class FFTConsts {
+
+ // org.apache.commons.math3.transform.FastFouriesTransformer.java:58
+ /**
+ * {@code W_SUB_N_R[i]} is the real part of
+ * {@code exp(- 2 * i * pi / n)}:
+ * {@code W_SUB_N_R[i] = cos(2 * pi/ n)}, where {@code n = 2^i}.
+ */
+ public static final double[] W_SUB_N_R =
+ { 0x1.0p0, -0x1.0p0, 0x1.1a62633145c07p-54, 0x1.6a09e667f3bcdp-1
+ , 0x1.d906bcf328d46p-1, 0x1.f6297cff75cbp-1, 0x1.fd88da3d12526p-1, 0x1.ff621e3796d7ep-1
+ , 0x1.ffd886084cd0dp-1, 0x1.fff62169b92dbp-1, 0x1.fffd8858e8a92p-1, 0x1.ffff621621d02p-1
+ , 0x1.ffffd88586ee6p-1, 0x1.fffff62161a34p-1, 0x1.fffffd8858675p-1, 0x1.ffffff621619cp-1
+ , 0x1.ffffffd885867p-1, 0x1.fffffff62161ap-1, 0x1.fffffffd88586p-1, 0x1.ffffffff62162p-1
+ , 0x1.ffffffffd8858p-1, 0x1.fffffffff6216p-1, 0x1.fffffffffd886p-1, 0x1.ffffffffff621p-1
+ , 0x1.ffffffffffd88p-1, 0x1.fffffffffff62p-1, 0x1.fffffffffffd9p-1, 0x1.ffffffffffff6p-1
+ , 0x1.ffffffffffffep-1, 0x1.fffffffffffffp-1, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0, 0x1.0p0
+ , 0x1.0p0, 0x1.0p0, 0x1.0p0 };
+
+ /**
+ * {@code W_SUB_N_I[i]} is the imaginary part of
+ * {@code exp(- 2 * i * pi / n)}:
+ * {@code W_SUB_N_I[i] = -sin(2 * pi/ n)}, where {@code n = 2^i}.
+ */
+ public static final double[] W_SUB_N_I =
+ { 0x1.1a62633145c07p-52, -0x1.1a62633145c07p-53, -0x1.0p0, -0x1.6a09e667f3bccp-1
+ , -0x1.87de2a6aea963p-2, -0x1.8f8b83c69a60ap-3, -0x1.917a6bc29b42cp-4, -0x1.91f65f10dd814p-5
+ , -0x1.92155f7a3667ep-6, -0x1.921d1fcdec784p-7, -0x1.921f0fe670071p-8, -0x1.921f8becca4bap-9
+ , -0x1.921faaee6472dp-10, -0x1.921fb2aecb36p-11, -0x1.921fb49ee4ea6p-12, -0x1.921fb51aeb57bp-13
+ , -0x1.921fb539ecf31p-14, -0x1.921fb541ad59ep-15, -0x1.921fb5439d73ap-16, -0x1.921fb544197ap-17
+ , -0x1.921fb544387bap-18, -0x1.921fb544403c1p-19, -0x1.921fb544422c2p-20, -0x1.921fb54442a83p-21
+ , -0x1.921fb54442c73p-22, -0x1.921fb54442cefp-23, -0x1.921fb54442d0ep-24, -0x1.921fb54442d15p-25
+ , -0x1.921fb54442d17p-26, -0x1.921fb54442d18p-27, -0x1.921fb54442d18p-28, -0x1.921fb54442d18p-29
+ , -0x1.921fb54442d18p-30, -0x1.921fb54442d18p-31, -0x1.921fb54442d18p-32, -0x1.921fb54442d18p-33
+ , -0x1.921fb54442d18p-34, -0x1.921fb54442d18p-35, -0x1.921fb54442d18p-36, -0x1.921fb54442d18p-37
+ , -0x1.921fb54442d18p-38, -0x1.921fb54442d18p-39, -0x1.921fb54442d18p-40, -0x1.921fb54442d18p-41
+ , -0x1.921fb54442d18p-42, -0x1.921fb54442d18p-43, -0x1.921fb54442d18p-44, -0x1.921fb54442d18p-45
+ , -0x1.921fb54442d18p-46, -0x1.921fb54442d18p-47, -0x1.921fb54442d18p-48, -0x1.921fb54442d18p-49
+ , -0x1.921fb54442d18p-50, -0x1.921fb54442d18p-51, -0x1.921fb54442d18p-52, -0x1.921fb54442d18p-53
+ , -0x1.921fb54442d18p-54, -0x1.921fb54442d18p-55, -0x1.921fb54442d18p-56, -0x1.921fb54442d18p-57
+ , -0x1.921fb54442d18p-58, -0x1.921fb54442d18p-59, -0x1.921fb54442d18p-60 };
+
+}
diff --git a/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt b/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt
index a247a2f20..fc10151a5 100644
--- a/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt
+++ b/src/net/torvald/terrarum/audio/TerrarumAudioFilter.kt
@@ -1,7 +1,5 @@
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
@@ -9,7 +7,6 @@ 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
@@ -298,12 +295,11 @@ 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() {
+class Convolv(ir: File, val gain: Float = decibelsToFullscale(-24.0).toFloat()): TerrarumAudioFilter() {
private val fftLen: Int
- private val convFFT: Array>
- private val inbuf: Array
-// private val outbuf: Array
+ private val convFFT: Array>
+ private val inbuf: Array
private val BLOCKSIZE = BUFFER_SIZE / 4
@@ -317,8 +313,8 @@ class Convolv(ir: File, val gain: Float = decibelsToFullscale(-12.0).toFloat()):
println("IR Sample Count = $sampleCount; FFT Length = $fftLen")
- val conv = Array(2) { DoubleArray(fftLen) }
- inbuf = Array(2) { DoubleArray(fftLen) }
+ val conv = Array(2) { FloatArray(fftLen) }
+ inbuf = Array(2) { FloatArray(fftLen) }
// outbuf = Array(2) { DoubleArray(fftLen) }
ir.inputStream().let {
@@ -331,8 +327,8 @@ class Convolv(ir: File, val gain: Float = decibelsToFullscale(-12.0).toFloat()):
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()
+ conv[0][i] = f1
+ conv[1][i] = f2
}
it.close()
@@ -340,7 +336,7 @@ class Convolv(ir: File, val gain: Float = decibelsToFullscale(-12.0).toFloat()):
// fourier-transform the 'conv'
convFFT = Array(2) {
- FastFourier(conv[it]).let { it.transform(); it.getComplex(false) }
+ FFT.fft(conv[it])
}
println("convFFT Length = ${convFFT[0].size}")
@@ -354,72 +350,33 @@ class Convolv(ir: File, val gain: Float = decibelsToFullscale(-12.0).toFloat()):
val t1 = System.nanoTime()
for (ch in outbuf1.indices) {
+ push(inbuf1[ch].applyGain(gain), inbuf[ch])
- push(inbuf1[ch].toDoubleArray(gain), 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 inputFFT = FFT.fft(inbuf[ch])
val Y = multiply(inputFFT, convFFT[ch])
- val y = real(ifft(Y))
+ val y = FFT.ifftAndGetReal(Y)
-// val u = y.sliceArray(Ny - BLOCKSIZE until Ny).toFloatArray(gain) // y size == Ny
- val u = y.takeLast(BLOCKSIZE).map { it.toFloat() }.toFloatArray()
-
-// println("y size: ${y.size}; Ny=$Ny")
+ val u = y.takeLast(BLOCKSIZE).toFloatArray()
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")
- }
+ println("Processing speed: ${realtime / ptime}x")
}
- private fun real(cs: Array): DoubleArray {
- return cs.map { it.real }.toDoubleArray()
+ private fun multiply(X: Array, H: Array): Array {
+ return Array(X.size) { X[it] * H[it] }
}
- 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])
-
- // following is a snippet of the code from org.apache.commons.math3.complex.multiply,
- // to remove the non-necessary sanity checks
- val a = X[it]
- val b = H[it]
- val re = a.real * b.real - a.imaginary * b.imaginary
- val im = a.real * b.imaginary + a.imaginary * b.real
- Complex(re, im)
- }
- }
-
-
- 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) {
+ private fun push(samples: FloatArray, buf: FloatArray) {
System.arraycopy(buf, samples.size, buf, 0, buf.size - samples.size)
System.arraycopy(samples, 0, buf, buf.size - samples.size, samples.size)
}
- private fun FloatArray.toDoubleArray(gain: Float = 1f) = this.map { it.toDouble() * gain }.toDoubleArray()
- private fun DoubleArray.toFloatArray(gain: Float = 1f) = this.map { it.toFloat() * gain }.toFloatArray()
+ private fun FloatArray.applyGain(gain: Float = 1f) = this.map { it * gain }.toFloatArray()
}
object XYtoMS: TerrarumAudioFilter() {
diff --git a/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt b/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt
index b410423b2..4dfe89b99 100644
--- a/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt
+++ b/src/net/torvald/terrarum/audio/TerrarumAudioMixerTrack.kt
@@ -21,9 +21,6 @@ class TerrarumAudioMixerTrack(val name: String, val isMaster: Boolean = false, v
const val SAMPLING_RATEF = 48000f
const val SAMPLING_RATED = 48000.0
const val BUFFER_SIZE = 512 // n ms -> 384 * n
-
- const val INDEX_BGM = 0
- const val INDEX_AMB = 1
}
val hash = getHashStr()