Bladeren bron

Update to latest SoLoud.

Refactored drivers. SDL and miniaudio now available as backends.
Brucey 5 jaren geleden
bovenliggende
commit
de99b71e28
100 gewijzigde bestanden met toevoegingen van 2092 en 430 verwijderingen
  1. 1 1
      libopenmpt.mod/libopenmpt.bmx
  2. 21 1
      modloader.mod/common.bmx
  3. 21 0
      modloader.mod/modloader.bmx
  4. 4 4
      modloader.mod/openmptloader.cpp
  5. 13 10
      soloud.mod/common.bmx
  6. 1 1
      soloud.mod/file.bmx
  7. 10 8
      soloud.mod/soloud.bmx
  8. 4 0
      soloud.mod/soloud/AUTHORS
  9. 158 3
      soloud.mod/soloud/build/genie.lua
  10. 3 1
      soloud.mod/soloud/contrib/src.cmake
  11. 8 3
      soloud.mod/soloud/demos/enumerate/main.cpp
  12. 1 1
      soloud.mod/soloud/demos/env/main.cpp
  13. 143 0
      soloud.mod/soloud/demos/megademo/annex.cpp
  14. 286 0
      soloud.mod/soloud/demos/megademo/filterfolio.cpp
  15. 26 2
      soloud.mod/soloud/demos/megademo/main.cpp
  16. 31 11
      soloud.mod/soloud/demos/megademo/monotone.cpp
  17. 1 0
      soloud.mod/soloud/demos/megademo/multimusic.cpp
  18. 4 3
      soloud.mod/soloud/demos/megademo/pewpew.cpp
  19. 2 2
      soloud.mod/soloud/demos/megademo/space.cpp
  20. 1 1
      soloud.mod/soloud/demos/megademo/speechfilter.cpp
  21. 1 1
      soloud.mod/soloud/demos/megademo/tedsid.cpp
  22. 1 0
      soloud.mod/soloud/demos/megademo/thebutton.cpp
  23. 3 3
      soloud.mod/soloud/demos/piano/main.cpp
  24. 2 0
      soloud.mod/soloud/demos/piano/soloud_padsynth.cpp
  25. 4 1
      soloud.mod/soloud/docsrc/SoLoud.tex
  26. 21 2
      soloud.mod/soloud/docsrc/attributes.mmd
  27. 3 0
      soloud.mod/soloud/docsrc/audiosource.mmd
  28. 8 5
      soloud.mod/soloud/docsrc/backends.mmd
  29. 12 5
      soloud.mod/soloud/docsrc/basics.mmd
  30. 12 0
      soloud.mod/soloud/docsrc/bassboostfilter.mmd
  31. 12 2
      soloud.mod/soloud/docsrc/biquadfilter.mmd
  32. 16 13
      soloud.mod/soloud/docsrc/concepts.mmd
  33. 1 1
      soloud.mod/soloud/docsrc/concepts3d.mmd
  34. 11 0
      soloud.mod/soloud/docsrc/dcremovalfilter.mmd
  35. 3 2
      soloud.mod/soloud/docsrc/dirstruct.mmd
  36. 42 3
      soloud.mod/soloud/docsrc/downloads.mmd
  37. 11 0
      soloud.mod/soloud/docsrc/echofilter.mmd
  38. 3 0
      soloud.mod/soloud/docsrc/faq.mmd
  39. 11 0
      soloud.mod/soloud/docsrc/fftfilter.mmd
  40. 2 2
      soloud.mod/soloud/docsrc/file.mmd
  41. 19 0
      soloud.mod/soloud/docsrc/filters.mmd
  42. 11 0
      soloud.mod/soloud/docsrc/flangerfilter.mmd
  43. 27 0
      soloud.mod/soloud/docsrc/freeverbfilter.mmd
  44. 1 1
      soloud.mod/soloud/docsrc/htmlpost.txt
  45. 3 0
      soloud.mod/soloud/docsrc/htmlpre.txt
  46. 9 2
      soloud.mod/soloud/docsrc/legal.mmd
  47. 13 0
      soloud.mod/soloud/docsrc/lofifilter.mmd
  48. 15 6
      soloud.mod/soloud/docsrc/makedoc.py
  49. 31 0
      soloud.mod/soloud/docsrc/mixbus.mmd
  50. 16 4
      soloud.mod/soloud/docsrc/monotone.mmd
  51. 1 1
      soloud.mod/soloud/docsrc/newsoundsources.mmd
  52. 88 0
      soloud.mod/soloud/docsrc/noise.mmd
  53. 5 1
      soloud.mod/soloud/docsrc/premake.mmd
  54. 17 13
      soloud.mod/soloud/docsrc/quickstart.mmd
  55. 35 0
      soloud.mod/soloud/docsrc/robotizefilter.mmd
  56. 0 17
      soloud.mod/soloud/docsrc/sfxr.mmd
  57. 1 1
      soloud.mod/soloud/docsrc/wav.mmd
  58. 10 0
      soloud.mod/soloud/docsrc/waveshaperfilter.mmd
  59. 91 50
      soloud.mod/soloud/include/soloud.h
  60. 10 4
      soloud.mod/soloud/include/soloud_audiosource.h
  61. 5 0
      soloud.mod/soloud/include/soloud_bassboostfilter.h
  62. 18 15
      soloud.mod/soloud/include/soloud_biquadresonantfilter.h
  63. 12 1
      soloud.mod/soloud/include/soloud_bus.h
  64. 149 42
      soloud.mod/soloud/include/soloud_c.h
  65. 1 1
      soloud.mod/soloud/include/soloud_dcremovalfilter.h
  66. 15 3
      soloud.mod/soloud/include/soloud_echofilter.h
  67. 4 4
      soloud.mod/soloud/include/soloud_file.h
  68. 2 1
      soloud.mod/soloud/include/soloud_file_hack_off.h
  69. 3 1
      soloud.mod/soloud/include/soloud_file_hack_on.h
  70. 13 1
      soloud.mod/soloud/include/soloud_filter.h
  71. 7 2
      soloud.mod/soloud/include/soloud_flangerfilter.h
  72. 83 0
      soloud.mod/soloud/include/soloud_freeverbfilter.h
  73. 51 11
      soloud.mod/soloud/include/soloud_internal.h
  74. 6 1
      soloud.mod/soloud/include/soloud_lofifilter.h
  75. 53 0
      soloud.mod/soloud/include/soloud_misc.h
  76. 4 10
      soloud.mod/soloud/include/soloud_monotone.h
  77. 74 0
      soloud.mod/soloud/include/soloud_noise.h
  78. 1 1
      soloud.mod/soloud/include/soloud_openmpt.h
  79. 20 8
      soloud.mod/soloud/include/soloud_robotizefilter.h
  80. 3 13
      soloud.mod/soloud/include/soloud_sfxr.h
  81. 1 1
      soloud.mod/soloud/include/soloud_tedsid.h
  82. 1 0
      soloud.mod/soloud/include/soloud_thread.h
  83. 1 1
      soloud.mod/soloud/include/soloud_wav.h
  84. 11 2
      soloud.mod/soloud/include/soloud_waveshaperfilter.h
  85. 1 1
      soloud.mod/soloud/include/soloud_wavstream.h
  86. 2 2
      soloud.mod/soloud/scripts/checkapidoc.py
  87. 1 0
      soloud.mod/soloud/scripts/gen_blitzmax.py
  88. 4 0
      soloud.mod/soloud/scripts/gen_cs.py
  89. 1 0
      soloud.mod/soloud/scripts/gen_d.py
  90. 8 3
      soloud.mod/soloud/scripts/gen_gamemaker.py
  91. 6 2
      soloud.mod/soloud/scripts/gen_python.py
  92. 57 17
      soloud.mod/soloud/scripts/makerel.py
  93. 11 54
      soloud.mod/soloud/src/audiosource/monotone/soloud_monotone.cpp
  94. 133 0
      soloud.mod/soloud/src/audiosource/noise/soloud_noise.cpp
  95. 2 2
      soloud.mod/soloud/src/audiosource/openmpt/soloud_openmpt.cpp
  96. 1 1
      soloud.mod/soloud/src/audiosource/openmpt/soloud_openmpt_dll.c
  97. 1 32
      soloud.mod/soloud/src/audiosource/sfxr/soloud_sfxr.cpp
  98. 1 1
      soloud.mod/soloud/src/audiosource/speech/darray.cpp
  99. 3 3
      soloud.mod/soloud/src/audiosource/speech/klatt.cpp
  100. 1 1
      soloud.mod/soloud/src/audiosource/speech/soloud_speech.cpp

+ 1 - 1
libopenmpt.mod/libopenmpt.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2019 Bruce A Henderson
+' Copyright (c) 2019-2020 Bruce A Henderson
 ' All rights reserved.
 ' 
 ' Redistribution and use in source and binary forms, with or without

+ 21 - 1
modloader.mod/common.bmx

@@ -1,3 +1,24 @@
+' Copyright (c) 2016-2020 Bruce A Henderson
+'
+' 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.
+'
 SuperStrict
 
 Import Audio.Soloud
@@ -7,7 +28,6 @@ Import "../soloud.mod/soloud/include/*.h"
 
 ' audiosource - openmpt
 Import "../soloud.mod/soloud/src/audiosource/openmpt/soloud_openmpt.cpp"
-'Import "soloud/src/audiosource/openmpt/soloud_openmpt_dll.c"
 
 Import "openmptloader.cpp"
 

+ 21 - 0
modloader.mod/modloader.bmx

@@ -1,3 +1,24 @@
+' Copyright (c) 2016-2020 Bruce A Henderson
+'
+' 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.
+'
 SuperStrict
 
 Module Audio.modloader

+ 4 - 4
modloader.mod/openmptloader.cpp

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2016 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -22,7 +22,7 @@ freely, subject to the following restrictions:
    distribution.
 */
 
-/* SoLoud C-Api Code Generator (c)2013-2018 Jari Komppa http://iki.fi/sol/ */
+/* SoLoud C-Api Code Generator (c)2013-2020 Jari Komppa http://iki.fi/sol/ */
 
 #include "../soloud.mod/soloud/src/../include/soloud.h"
 #include "../soloud.mod/soloud/src/../include/soloud_audiosource.h"
@@ -49,13 +49,13 @@ int Openmpt_load(void * aClassPtr, const char * aFilename)
 	return cl->load(aFilename);
 }
 
-int Openmpt_loadMem(void * aClassPtr, unsigned char * aMem, unsigned int aLength)
+int Openmpt_loadMem(void * aClassPtr, const unsigned char * aMem, unsigned int aLength)
 {
 	Openmpt * cl = (Openmpt *)aClassPtr;
 	return cl->loadMem(aMem, aLength);
 }
 
-int Openmpt_loadMemEx(void * aClassPtr, unsigned char * aMem, unsigned int aLength, int aCopy, int aTakeOwnership)
+int Openmpt_loadMemEx(void * aClassPtr, const unsigned char * aMem, unsigned int aLength, int aCopy, int aTakeOwnership)
 {
 	Openmpt * cl = (Openmpt *)aClassPtr;
 	return cl->loadMem(aMem, aLength, !!aCopy, !!aTakeOwnership);

+ 13 - 10
soloud.mod/common.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2016-2019 Bruce A Henderson
+' Copyright (c) 2016-2020 Bruce A Henderson
 '
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
@@ -22,7 +22,6 @@
 SuperStrict
 
 Import BRL.Stream
-Import SDL.SDL
 
 Import "source.bmx"
 
@@ -86,7 +85,7 @@ Extern
 	Function Soloud_setSamplerate(aSoloud:Byte Ptr, aVoiceHandle:Int, aSamplerate:Float)
 	Function Soloud_setPan(aSoloud:Byte Ptr, aVoiceHandle:Int, aPan:Float)
 	Function Soloud_setPanAbsolute(aSoloud:Byte Ptr, aVoiceHandle:Int, aLVolume:Float, aRVolume:Float)
-	Function Soloud_setPanAbsoluteEx(aSoloud:Byte Ptr, aVoiceHandle:Int, aLVolume:Float, aRVolume:Float, aLBVolume:Float, aRBVolume:Float, aCVolume:Float, aSVolume:Float)
+	Function Soloud_setChannelVolume(aSoloud:Byte Ptr, aVoiceHandle:Int, channel:Int, volume:Float)
 	Function Soloud_setVolume(aSoloud:Byte Ptr, aVoiceHandle:Int, aVolume:Float)
 	Function Soloud_setDelaySamples(aSoloud:Byte Ptr, aVoiceHandle:Int, aSamples:Int)
 	Function Soloud_fadeVolume(aSoloud:Byte Ptr, aVoiceHandle:Int, aTo:Float, aTime:Double)
@@ -347,19 +346,23 @@ End Extern
 
 
 Const SOLOUD_AUTO:Int = 0
-Const SOLOUD_SDL:Int = 1
+Const SOLOUD_SDL1:Int = 1
 Const SOLOUD_SDL2:Int = 2
 Const SOLOUD_PORTAUDIO:Int = 3
 Const SOLOUD_WINMM:Int = 4
 Const SOLOUD_XAUDIO2:Int = 5
 Const SOLOUD_WASAPI:Int = 6
 Const SOLOUD_ALSA:Int = 7
-Const SOLOUD_OSS:Int = 8
-Const SOLOUD_OPENAL:Int = 9
-Const SOLOUD_COREAUDIO:Int = 10
-Const SOLOUD_OPENSLES:Int = 11
-Const SOLOUD_NULLDRIVER:Int = 12
-Const SOLOUD_BACKEND_MAX:Int = 13
+Const SOLOUD_JACK:Int = 8
+Const SOLOUD_OSS:Int = 9
+Const SOLOUD_OPENAL:Int = 10
+Const SOLOUD_COREAUDIO:Int = 11
+Const SOLOUD_OPENSLES:Int = 12
+Const SOLOUD_VITA_HOMEBREW:Int = 13
+Const SOLOUD_MINIAUDIO:Int = 14
+Const SOLOUD_NOSOUND:Int = 15
+Const SOLOUD_NULLDRIVER:Int = 16
+Const SOLOUD_BACKEND_MAX:Int = 17
 
 Const SOLOUD_CLIP_ROUNDOFF:Int = 1
 Const SOLOUD_ENABLE_VISUALIZATION:Int = 2

+ 1 - 1
soloud.mod/file.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2016-2019 Bruce A Henderson
+' Copyright (c) 2016-2020 Bruce A Henderson
 '
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages

+ 10 - 8
soloud.mod/soloud.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2016-2019 Bruce A Henderson
+' Copyright (c) 2016-2020 Bruce A Henderson
 '
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
@@ -26,11 +26,14 @@ bbdoc:
 End Rem
 Module Audio.SoLoud
 
-ModuleInfo "Version: 1.00"
+ModuleInfo "Version: 1.01"
 ModuleInfo "License: zlib/libpng"
-ModuleInfo "Copyright: SoLoud - 2013-2018 Jari Komppa"
-ModuleInfo "Copyright: Wrapper - 2016-2019 Bruce A Henderson"
+ModuleInfo "Copyright: SoLoud - 2013-2020 Jari Komppa"
+ModuleInfo "Copyright: Wrapper - 2016-2020 Bruce A Henderson"
 
+ModuleInfo "History: 1.01"
+ModuleInfo "History: Update to latest SoLoud."
+ModuleInfo "History: Refactored drivers. SDL and miniaudio now available as backends."
 ModuleInfo "History: 1.00"
 ModuleInfo "History: Initial Release."
 
@@ -44,12 +47,11 @@ ModuleInfo "CC_OPTS: -msse2"
 ModuleInfo "CC_OPTS: -msse3"
 ?
 ModuleInfo "CC_OPTS: -DWITH_SDL2_STATIC"
+ModuleInfo "CC_OPTS: -DWITH_MINIAUDIO"
 
 Import "file.bmx"
 Import "common.bmx"
 
-SDL_InitSubSystem(SDL_INIT_AUDIO)
-
 Rem
 bbdoc: 
 End Rem
@@ -358,8 +360,8 @@ Type TSoloud
 	Rem
 	bbdoc: Sets absolute left/right volumes.
 	End Rem
-	Method setPanAbsolute(voiceHandle:Int, lVolume:Float, rVolume:Float, lBVolume:Float = 0, rBVolume:Float = 0, cVolume:Float = 0, sVolume:Float = 0)
-		Soloud_setPanAbsoluteEx(slPtr, voiceHandle, lVolume, rVolume, lBVolume, rBVolume, cVolume, sVolume)
+	Method SetChannelVolume(voiceHandle:Int, channel:Int, volume:Float)
+		Soloud_setChannelVolume(slPtr, voiceHandle, channel, volume)
 	End Method
 	
 	Rem

+ 4 - 0
soloud.mod/soloud/AUTHORS

@@ -28,3 +28,7 @@ Danny Angelo Carminati Grein https://github.com/fungos
 Igor Ivanov https://github.com/laptabrok
 Matthew O'Connell https://github.com/matthew-oconnell
 Boris Carvajal https://github.com/BorisCarvajal
+Osman Turan https://osmanturan.com
+Samson Close https://github.com/qwertysam
+Bruce A Henderson https://github.com/woollybah
+Philip Bennefall https://github.com/blastbay/

+ 158 - 3
soloud.mod/soloud/build/genie.lua

@@ -8,9 +8,12 @@ local WITH_XAUDIO2 = 0
 local WITH_WINMM = 0
 local WITH_WASAPI = 0
 local WITH_ALSA = 0
+local WITH_JACK = 0
 local WITH_OSS = 0
 local WITH_COREAUDIO = 0
 local WITH_VITA_HOMEBREW = 0
+local WITH_NOSOUND = 0
+local WITH_MINIAUDIO = 0
 local WITH_NULL = 1
 local WITH_TOOLS = 0
 
@@ -126,6 +129,31 @@ newoption {
 	description = "Shorthand for options used while developing SoLoud"
 }
 
+newoption {
+	trigger		  = "with-nosound",
+	description = "Include nosound backend in build"
+}
+
+newoption {
+	trigger		  = "with-jack",
+	description = "Include JACK backend in build"
+}
+
+newoption {
+	trigger		  = "with-jack-only",
+	description = "Only include JACK backend in build"
+}
+
+newoption {
+    trigger       = "with-miniaudio",
+    description = "Include MiniAudio in build" 
+}
+
+newoption {
+    trigger       = "with-miniaudio-only",
+    description = "Only include MiniAudio in build"
+}
+
 if _OPTIONS["soloud-devel"] then
     WITH_SDL = 0
     WITH_SDL2 = 1
@@ -136,7 +164,9 @@ if _OPTIONS["soloud-devel"] then
     WITH_XAUDIO2 = 0
     WITH_WINMM = 0
     WITH_WASAPI = 0
+    WITH_MINIAUDIO = 1
     WITH_OSS = 1
+    WITH_NOSOUND = 1
     if (os.is("Windows")) then
     	WITH_XAUDIO2 = 0
     	WITH_WINMM = 1
@@ -156,6 +186,8 @@ if _OPTIONS["with-common-backends"] then
     WITH_WINMM = 0
     WITH_WASAPI = 0
     WITH_OSS = 1
+    WITH_NOSOUND = 1
+    WITH_MINIAUDIO = 0
 
     if (os.is("Windows")) then
     	WITH_XAUDIO2 = 0
@@ -186,13 +218,17 @@ if _OPTIONS["with-sdl"] then
 end
 
 if _OPTIONS["with-sdl2"] then
-	WITH_SDL = 1
+	WITH_SDL2 = 1
 end
 
 if _OPTIONS["with-wasapi"] then
 	WITH_WASAPI = 1
 end
 
+if _OPTIONS["with-nosound"] then
+    WITH_NOSOUND = 1
+end
+
 if _OPTIONS["with-sdl-only"] then
 	WITH_SDL = 1
 	WITH_SDL2 = 0
@@ -204,6 +240,8 @@ if _OPTIONS["with-sdl-only"] then
 	WITH_WINMM = 0
 	WITH_WASAPI = 0
 	WITH_OSS = 0
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 0
 end
 
 if _OPTIONS["with-sdl2-only"] then
@@ -217,6 +255,8 @@ if _OPTIONS["with-sdl2-only"] then
 	WITH_WINMM = 0
 	WITH_WASAPI = 0
 	WITH_OSS = 0
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 0
 end
 
 if _OPTIONS["with-sdlstatic-only"] then
@@ -229,6 +269,8 @@ if _OPTIONS["with-sdlstatic-only"] then
 	WITH_WINMM = 0
 	WITH_WASAPI = 0
 	WITH_OSS = 0
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 0
 end
 
 if _OPTIONS["with-sdl2static-only"] then
@@ -242,6 +284,8 @@ if _OPTIONS["with-sdl2static-only"] then
 	WITH_WINMM = 0
 	WITH_WASAPI = 0
 	WITH_OSS = 0
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 0
 end
 
 if _OPTIONS["with-sdl2static-only"] then
@@ -255,6 +299,8 @@ if _OPTIONS["with-sdl2static-only"] then
 	WITH_WINMM = 0
 	WITH_WASAPI = 0
 	WITH_OSS = 0
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 0
 end
 
 if _OPTIONS["with-vita-homebrew-only"] then
@@ -270,12 +316,60 @@ if _OPTIONS["with-vita-homebrew-only"] then
 	WITH_OSS = 0
 	WITH_ALSA = 0
 	WITH_VITA_HOMEBREW = 1
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 0
 
 	premake.gcc.cc = "arm-vita-eabi-gcc"
 	premake.gcc.cxx = "arm-vita-eabi-g++"
 	premake.gcc.ar = "arm-vita-eabi-ar"
 end
 
+if _OPTIONS["with-jack"] then
+	WITH_JACK = 1
+end
+
+if _OPTIONS["with-jack-only"] then
+	WITH_SDL = 0
+	WITH_SDL2 = 0
+	WITH_SDL_STATIC = 0
+	WITH_SDL2_STATIC = 0
+	WITH_PORTAUDIO = 0
+	WITH_OPENAL = 0
+	WITH_XAUDIO2 = 0
+	WITH_WINMM = 0
+	WITH_WASAPI = 0
+	WITH_OSS = 0
+	WITH_ALSA = 0
+	WITH_VITA_HOMEBREW = 0
+	WITH_COREAUDIO = 0
+	WITH_JACK = 1
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 0
+end
+
+if _OPTIONS["with-miniaudio"] then
+    WITH_MINIAUDIO = 1
+end
+
+if _OPTIONS["with-miniaudio-only"] then
+	WITH_SDL = 0
+	WITH_SDL2 = 0
+	WITH_SDL_STATIC = 0
+	WITH_SDL2_STATIC = 0
+	WITH_PORTAUDIO = 0
+	WITH_OPENAL = 0
+	WITH_XAUDIO2 = 0
+	WITH_WINMM = 0
+	WITH_WASAPI = 0
+	WITH_OSS = 0
+	WITH_ALSA = 0
+	WITH_VITA_HOMEBREW = 0
+	WITH_COREAUDIO = 0
+	WITH_JACK = 0
+	WITH_NOSOUND = 0
+	WITH_MINIAUDIO = 1
+end
+
 if _OPTIONS["with-native-only"] then
 	WITH_SDL = 0
 	WITH_SDL2 = 0
@@ -287,6 +381,8 @@ if _OPTIONS["with-native-only"] then
 	WITH_WINMM = 0
 	WITH_WASAPI = 0
 	WITH_OSS = 0
+	WITH_MINIAUDIO = 0
+	WITH_NOSOUND = 0
 	if (os.is("Windows")) then
 		WITH_WINMM = 1
 	elseif (os.is("macosx")) then
@@ -310,7 +406,10 @@ print ("WITH_XAUDIO2    = ", WITH_XAUDIO2)
 print ("WITH_WINMM      = ", WITH_WINMM)
 print ("WITH_WASAPI     = ", WITH_WASAPI)
 print ("WITH_ALSA       = ", WITH_ALSA)
+print ("WITH_JACK       = ", WITH_JACK)
 print ("WITH_OSS        = ", WITH_OSS)
+print ("WITH_MINIAUDIO  = ", WITH_MINIAUDIO)
+print ("WITH_NOSOUND    = ", WITH_NOSOUND)
 print ("WITH_COREAUDIO  = ", WITH_COREAUDIO)
 print ("WITH_VITA_HOMEBREW = ", WITH_VITA_HOMEBREW)
 print ("WITH_TOOLS      = ", WITH_TOOLS)
@@ -374,6 +473,9 @@ end
 if (WITH_ALSA == 1) then
 	links {"asound"}
 end
+if (WITH_JACK == 1) then
+	links { "jack" }
+end
 if (WITH_COREAUDIO == 1) then
 	links {"AudioToolbox.framework"}
 end
@@ -400,6 +502,9 @@ end
 if (WITH_ALSA == 1) then
 	links {"asound"}
 end
+if (WITH_JACK == 1) then
+	links { "jack" }
+end
 if (WITH_COREAUDIO == 1) then
 	links {"AudioToolbox.framework"}
 end
@@ -426,6 +531,9 @@ end
 if (WITH_ALSA == 1) then
 	links {"asound"}
 end
+if (WITH_JACK == 1) then
+	links { "jack" }
+end
 if (WITH_COREAUDIO == 1) then
 	links {"AudioToolbox.framework"}
 end
@@ -453,6 +561,9 @@ end
 if (WITH_ALSA == 1) then
 	links {"asound"}
 end
+if (WITH_JACK == 1) then
+	links { "jack" }
+end
 if (WITH_COREAUDIO == 1) then
 	links {"AudioToolbox.framework"}
 end
@@ -467,7 +578,7 @@ end
 
 -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< -- 8< --
 
-if (WITH_SDL2 == 1) then
+if (WITH_SDL2 == 1 or WITH_SDL2STATIC) then
 
 	project "SoloudDemoCommon"
 		kind "StaticLib"
@@ -540,6 +651,26 @@ if (WITH_OSS == 1) then
 	}
 end
 
+if (WITH_MINIAUDIO == 1) then
+	defines {"WITH_MINIAUDIO"}
+	files {
+	  "../src/backend/miniaudio/**.c*"
+	  }
+	includedirs {
+	  "../include"
+	}
+end
+
+if (WITH_NOSOUND == 1) then
+	defines {"WITH_NOSOUND"}
+	files {
+	  "../src/backend/nosound/**.c*"
+	  }
+	includedirs {
+	  "../include"
+	}
+end
+
 if (WITH_COREAUDIO == 1) then
 	defines {"WITH_COREAUDIO"}
 	files {
@@ -647,6 +778,18 @@ if (WITH_VITA_HOMEBREW == 1) then
 	}
 end
 
+
+if (WITH_JACK == 1) then
+	defines { "WITH_JACK" }
+	links { "jack" }
+	files {
+	  "../src/backend/jack/**.c*"
+	  }
+	includedirs {
+	  "../include"
+	}
+end
+
 if (WITH_NULL == 1) then
     defines { "WITH_NULL" }
 	files {
@@ -674,6 +817,9 @@ if (WITH_TOOLS == 1) then
 		if (WITH_ALSA == 1) then
 			links {"asound"}
 		end
+		if (WITH_JACK == 1) then
+			links { "jack" }
+		end
 		if (WITH_COREAUDIO == 1) then
 			links {"AudioToolbox.framework"}
 		end
@@ -762,6 +908,9 @@ end
 if (WITH_ALSA == 1) then
 	links {"asound"}
 end
+if (WITH_JACK == 1) then
+	links { "jack" }
+end
 if (WITH_COREAUDIO == 1) then
 	links {"AudioToolbox.framework"}
 end
@@ -802,7 +951,7 @@ end
 --  The rest of the projects require SDL
 --
 
-if (WITH_SDL2 == 1) then
+if (WITH_SDL2 == 1 or WITH_SDL2STATIC) then
 
 function sdl2_lib()
     configuration { "x32" } 
@@ -833,6 +982,9 @@ function CommonDemo(_name)
 if (WITH_ALSA == 1) then
 	links {"asound"}
 end
+if (WITH_JACK == 1) then
+	links { "jack" }
+end
 if (WITH_COREAUDIO == 1) then
 	links {"AudioToolbox.framework"}
 end
@@ -879,6 +1031,9 @@ end
 if (WITH_ALSA == 1) then
 	links {"asound"}
 end
+if (WITH_JACK == 1) then
+	links { "jack" }
+end
 if (WITH_COREAUDIO == 1) then
 	links {"AudioToolbox.framework"}
 end

+ 3 - 1
soloud.mod/soloud/contrib/src.cmake

@@ -192,13 +192,15 @@ set (FILTERS_SOURCES
 	${FILTERS_PATH}/soloud_fftfilter.cpp
 	${FILTERS_PATH}/soloud_flangerfilter.cpp
 	${FILTERS_PATH}/soloud_lofifilter.cpp
+	${FILTERS_PATH}/soloud_robotizefilter.cpp
+	${FILTERS_PATH}/soloud_waveshaperfilter.cpp
 )
 
 
 # All together
 source_group ("Includes"		FILES ${TARGET_HEADERS})
 source_group ("Core"			FILES ${CORE_SOURCES})
-source_group ("Audiosources"	FILES ${AUDIOSOURCES_SOURCES})
+source_group ("Audiosources"		FILES ${AUDIOSOURCES_SOURCES})
 source_group ("Backends"		FILES ${BACKENDS_SOURCES})
 source_group ("Filters"			FILES ${FILTERS_SOURCES})
 

+ 8 - 3
soloud.mod/soloud/demos/enumerate/main.cpp

@@ -26,10 +26,11 @@ freely, subject to the following restrictions:
 #include <stdio.h>
 
 #include "soloud.h"
+#include "soloud_thread.h"
 
 const char * getBackendEnumString(int aBackend)
 {
-	SOLOUD_ASSERT(SoLoud::Soloud::BACKEND_MAX == 14); // if this fails, this function needs adjustment
+	SOLOUD_ASSERT(SoLoud::Soloud::BACKEND_MAX == 17); // if this fails, this function needs adjustment
 	switch (aBackend)
 	{
 	case SoLoud::Soloud::AUTO: return "AUTO";
@@ -40,12 +41,15 @@ const char * getBackendEnumString(int aBackend)
 	case SoLoud::Soloud::XAUDIO2: return "XAUDIO2";
 	case SoLoud::Soloud::WASAPI: return "WASAPI";
 	case SoLoud::Soloud::ALSA: return "ALSA";
+	case SoLoud::Soloud::JACK: return "JACK";
 	case SoLoud::Soloud::OSS: return "OSS";
 	case SoLoud::Soloud::OPENAL: return "OPENAL";
 	case SoLoud::Soloud::COREAUDIO: return "COREAUDIO";
 	case SoLoud::Soloud::OPENSLES: return "OPENSLES";
 	case SoLoud::Soloud::VITA_HOMEBREW: return "VITA_HOMEBREW";
 	case SoLoud::Soloud::NULLDRIVER: return "NULLDRIVER";
+	case SoLoud::Soloud::NOSOUND: return "NOSOUND";
+	case SoLoud::Soloud::MINIAUDIO: return "MINIAUDIO";
 	}
 	return "?!";
 }
@@ -101,7 +105,8 @@ int main(int argc, char *argv[])
 				if (res == SoLoud::SO_NO_ERROR && soloud.getBackendChannels() == j)
 				{
 					printf("Channels: %d%s\n", soloud.getBackendChannels(), getChannelString(soloud.getBackendChannels()));
-					soloud.deinit();
+					soloud.deinit();					
+					SoLoud::Thread::sleep(200);
 				}
 			}
 		}
@@ -111,4 +116,4 @@ int main(int argc, char *argv[])
 		}
 	}
 	return 0;
-}
+}

+ 1 - 1
soloud.mod/soloud/demos/env/main.cpp

@@ -265,7 +265,7 @@ int DemoEntry(int argc, char *argv[])
 	gWind.setLooping(1);
 	gMusic.load("audio/tetsno.ogg");
 	gMusic.setLooping(1);
-	gLPFilter.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 44100, 100, 10);
+	gLPFilter.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 100, 10);
 	gMusic.setFilter(0, &gLPFilter);
 
 	gRainHandle = gSoloud.play(gRain, 1);

+ 143 - 0
soloud.mod/soloud/demos/megademo/annex.cpp

@@ -0,0 +1,143 @@
+/*
+SoLoud audio engine
+Copyright (c) 2013-2020 Jari Komppa
+
+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.
+*/
+
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "imgui.h"
+#include "soloud_demo_framework.h"
+
+#include "soloud.h"
+#include "soloud_wavstream.h"
+#include "soloud_lofifilter.h"
+#include "soloud_biquadresonantfilter.h"
+#include "soloud_echofilter.h"
+#include "soloud_freeverbfilter.h"
+
+
+namespace annex
+{
+	SoLoud::Soloud gSoloud;
+	SoLoud::WavStream gMusic;
+	SoLoud::Bus gBus1, gBus2, gBus3, gBus4;
+	SoLoud::LofiFilter gLofi;
+	SoLoud::BiquadResonantFilter gBiquad;
+	SoLoud::EchoFilter gEcho;
+	SoLoud::FreeverbFilter gVerb;
+
+	int gMusichandle;
+	int gBus1handle;
+	int gFrozen;
+
+	int DemoEntry(int argc, char* argv[])
+	{
+		gSoloud.init(SoLoud::Soloud::CLIP_ROUNDOFF | SoLoud::Soloud::ENABLE_VISUALIZATION);
+
+		gFrozen = 0;
+
+		gMusic.load("audio/delphi_loop.ogg");
+		gMusic.setLooping(1);
+
+		gLofi.setParams(1000, 6);
+		gBiquad.setParams(SoLoud::BiquadResonantFilter::HIGHPASS, 500, 2);
+		gEcho.setParams(0.25f,0.9f);
+
+		gBus2.setFilter(0, &gLofi);
+		gBus3.setFilter(0, &gBiquad);
+		gBus4.setFilter(0, &gEcho);
+		gBus1.setFilter(0, &gVerb);
+
+		gBus1handle = gSoloud.play(gBus1);
+		gSoloud.play(gBus2);
+		gSoloud.play(gBus3);
+		gSoloud.play(gBus4);
+		gMusichandle = gBus1.play(gMusic);
+
+		return 0;
+	}
+
+	void DemoMainloop()
+	{
+		DemoUpdateStart();
+
+		float* buf = gSoloud.getWave();
+		float* fft = gSoloud.calcFFT();
+
+		ONCE(ImGui::SetNextWindowPos(ImVec2(500, 20)));
+		ImGui::Begin("Output");
+		ImGui::PlotLines("##Wave", buf, 256, 0, "Wave", -1, 1, ImVec2(264, 80));
+		ImGui::PlotHistogram("##FFT", fft, 256 / 2, 0, "FFT", 0, 10, ImVec2(264, 80), 8);
+		ImGui::Text("Active voices    : %d", gSoloud.getActiveVoiceCount());
+		ImGui::Text("Bus 1 voices     : %d", gBus1.getActiveVoiceCount());
+		ImGui::Text("Bus 2 voices     : %d", gBus2.getActiveVoiceCount());
+		ImGui::Text("Bus 3 voices     : %d", gBus3.getActiveVoiceCount());
+		ImGui::Text("Bus 4 voices     : %d", gBus4.getActiveVoiceCount());
+		ImGui::End();
+
+		ONCE(ImGui::SetNextWindowPos(ImVec2(20, 20)));
+		ImGui::Begin("Control");
+		if (ImGui::Button("Annex sound to bus 1"))
+		{
+			gBus1.annexSound(gMusichandle);
+		}
+		ImGui::SameLine();
+		if (!gFrozen && ImGui::Button("Freeze"))
+		{
+			gSoloud.setFilterParameter(gBus1handle, 0, SoLoud::FreeverbFilter::FREEZE, 1);
+			gFrozen = 1;
+		} 
+		if (gFrozen && ImGui::Button("Thaw"))
+		{
+			gSoloud.setFilterParameter(gBus1handle, 0, SoLoud::FreeverbFilter::FREEZE, 0);
+			gFrozen = 0;
+		}
+
+		if (ImGui::Button("Annex sound to bus 2"))
+		{
+			gBus2.annexSound(gMusichandle);
+		}
+		if (ImGui::Button("Annex sound to bus 3"))
+		{
+			gBus3.annexSound(gMusichandle);
+		}
+		if (ImGui::Button("Annex sound to bus 4"))
+		{
+			gBus4.annexSound(gMusichandle);
+		}		
+		ImGui::End();
+
+		DemoUpdateEnd();
+	}
+}
+
+int DemoEntry_annex(int argc, char* argv[])
+{
+	return annex::DemoEntry(argc, argv);
+}
+
+void DemoMainloop_annex()
+{
+	return annex::DemoMainloop();
+}

+ 286 - 0
soloud.mod/soloud/demos/megademo/filterfolio.cpp

@@ -0,0 +1,286 @@
+/*
+SoLoud audio engine
+Copyright (c) 2013-2020 Jari Komppa
+
+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.
+*/
+
+#include <stdlib.h>
+#include <math.h>
+#include <stdio.h>
+#include "imgui.h"
+#include "soloud_demo_framework.h"
+
+#include "soloud.h"
+#include "soloud_wav.h"
+#include "soloud_wavstream.h"
+#include "soloud_sfxr.h"
+#include "soloud_speech.h"
+#include "soloud_noise.h"
+
+#include "soloud_bassboostfilter.h"
+#include "soloud_biquadresonantfilter.h"
+#include "soloud_dcremovalfilter.h"
+#include "soloud_echofilter.h"
+#include "soloud_fftfilter.h"
+#include "soloud_flangerfilter.h"
+#include "soloud_freeverbfilter.h"
+#include "soloud_lofifilter.h"
+#include "soloud_robotizefilter.h"
+#include "soloud_waveshaperfilter.h"
+
+namespace filterfolio
+{
+	SoLoud::Soloud gSoloud;
+	SoLoud::Sfxr gSfx;
+	SoLoud::Speech gSpeech;
+	SoLoud::WavStream gMusic1, gMusic2, gMusic3;
+	int gMusichandle1, gMusichandle2, gMusichandle3;
+	SoLoud::Filter *gFilter[10];
+	SoLoud::Noise gNoise;
+	int gNoisehandle;
+
+	int gFilterSelect[4] = { 0, 0, 0, 0 };
+
+	int DemoEntry(int argc, char* argv[])
+	{
+		gMusic1.load("audio/plonk_wet.ogg");
+		gMusic2.load("audio/delphi_loop.ogg");
+		gMusic3.load("audio/tetsno.ogg");
+
+		gMusic1.setLooping(1);
+		gMusic2.setLooping(1);
+		gMusic3.setLooping(1);
+
+		gSoloud.init(SoLoud::Soloud::CLIP_ROUNDOFF | SoLoud::Soloud::ENABLE_VISUALIZATION);
+
+		gMusichandle1 = gSoloud.play(gMusic1);
+		gMusichandle2 = gSoloud.play(gMusic2, 0);
+		gMusichandle3 = gSoloud.play(gMusic3, 0);
+		gSoloud.setProtectVoice(gMusichandle1, 1);
+		gSoloud.setProtectVoice(gMusichandle2, 1);
+		gSoloud.setProtectVoice(gMusichandle3, 1);
+
+		gNoisehandle = gSoloud.play(gNoise, 0);
+
+		gFilter[0] = new SoLoud::BassboostFilter;
+		gFilter[1] = new SoLoud::BiquadResonantFilter;
+		gFilter[2] = new SoLoud::DCRemovalFilter;
+		gFilter[3] = new SoLoud::EchoFilter;
+		gFilter[4] = new SoLoud::FFTFilter;
+		gFilter[5] = new SoLoud::FlangerFilter;
+		gFilter[6] = new SoLoud::FreeverbFilter;
+		gFilter[7] = new SoLoud::LofiFilter;
+		gFilter[8] = new SoLoud::RobotizeFilter;
+		gFilter[9] = new SoLoud::WaveShaperFilter;
+
+		gSpeech.setText("My banana is yellow");
+
+		return 0;
+	}
+
+	void DemoMainloop()
+	{
+		DemoUpdateStart();
+
+		float* buf = gSoloud.getWave();
+		float* fft = gSoloud.calcFFT();
+
+		ONCE(ImGui::SetNextWindowPos(ImVec2(500, 20)));
+		ImGui::Begin("Sounds");
+		ImGui::PlotLines("##Wave", buf, 256, 0, "Wave", -1, 1, ImVec2(264, 80));
+		ImGui::PlotHistogram("##FFT", fft, 256 / 2, 0, "FFT", 0, 10, ImVec2(264, 80), 8);
+		ImGui::Text("Active voices    : %d", gSoloud.getActiveVoiceCount());
+		ImGui::End();
+
+		ONCE(ImGui::SetNextWindowPos(ImVec2(20, 20)));
+		ImGui::Begin("Control");
+		bool b = gSoloud.getVolume(gMusichandle1) > 0.5;
+		if (ImGui::Checkbox("Toggle Music 1", &b))
+		{
+			if (gSoloud.getVolume(gMusichandle1) > 0.5)
+				gSoloud.fadeVolume(gMusichandle1, 0, 0.5);
+			else
+				gSoloud.fadeVolume(gMusichandle1, 1, 0.5);
+		}
+		ImGui::SameLine();
+		if (ImGui::Button("SFXR EXPLOSION"))
+		{
+			gSfx.loadPreset(SoLoud::Sfxr::EXPLOSION, rand());
+			gSoloud.play(gSfx, 2, ((rand() % 512) - 256) / 256.0f);
+		}
+		ImGui::SameLine();
+		if (ImGui::Button("SFXR BLIP"))
+		{
+			gSfx.loadPreset(SoLoud::Sfxr::BLIP, rand());
+			gSoloud.play(gSfx, 2, ((rand() % 512) - 256) / 256.0f);
+		}
+		ImGui::SameLine();
+		if (ImGui::Button("SFXR COIN"))
+		{
+			gSfx.loadPreset(SoLoud::Sfxr::COIN, rand());
+			gSoloud.play(gSfx, 2, ((rand() % 512) - 256) / 256.0f);
+		}
+
+		b = gSoloud.getVolume(gMusichandle2) > 0.5;
+		if (ImGui::Checkbox("Toggle Music 2", &b))
+		{
+			if (gSoloud.getVolume(gMusichandle2) > 0.5)
+				gSoloud.fadeVolume(gMusichandle2, 0, 0.5);
+			else
+				gSoloud.fadeVolume(gMusichandle2, 1, 0.5);
+		}
+		ImGui::SameLine();
+		if (ImGui::Button("SFXR HURT"))
+		{
+			gSfx.loadPreset(SoLoud::Sfxr::HURT, rand());
+			gSoloud.play(gSfx, 2, ((rand() % 512) - 256) / 256.0f);
+		}
+		ImGui::SameLine();
+		if (ImGui::Button("SFXR JUMP"))
+		{
+			gSfx.loadPreset(SoLoud::Sfxr::JUMP, rand());
+			gSoloud.play(gSfx, 2, ((rand() % 512) - 256) / 256.0f);
+		}
+		ImGui::SameLine();
+		if (ImGui::Button("SFXR LASER"))
+		{
+			gSfx.loadPreset(SoLoud::Sfxr::LASER, rand());
+			gSoloud.play(gSfx, 2, ((rand() % 512) - 256) / 256.0f);
+		}
+
+		b = gSoloud.getVolume(gMusichandle3) > 0.5;
+		if (ImGui::Checkbox("Toggle Music 3", &b))
+		{
+			if (gSoloud.getVolume(gMusichandle3) > 0.5)
+				gSoloud.fadeVolume(gMusichandle3, 0, 0.5);
+			else
+				gSoloud.fadeVolume(gMusichandle3, 1, 0.5);
+		}
+		ImGui::SameLine();
+		if (ImGui::Button("Speech"))
+		{
+			gSoloud.play(gSpeech, 1);
+		}
+		ImGui::SameLine();
+		b = gSoloud.getVolume(gNoisehandle) > 0.5;
+		if (ImGui::Checkbox("Toggle Noise", &b))
+		{
+			if (gSoloud.getVolume(gNoisehandle) > 0.5)
+				gSoloud.fadeVolume(gNoisehandle, 0, 0.5);
+			else
+				gSoloud.fadeVolume(gNoisehandle, 1, 0.5);
+		}
+
+
+		ImGui::End();
+
+		
+		ONCE(ImGui::SetNextWindowPos(ImVec2(20, 140)));
+		ONCE(ImGui::SetNextWindowSize(ImVec2(350, 250)));
+		ImGui::Begin("Filters");
+		for (int filterindex = 0; filterindex < 4; filterindex++)
+		{
+			if (filterindex != 0)
+				ImGui::Separator();
+
+			char* label[4] = { "Filter 1", "Filter 2", "Filter 3", "Filter 4" };
+
+			if (ImGui::Combo(label[filterindex], &gFilterSelect[filterindex],
+				"None\x00"
+				"BassboostFilter\x00"
+				"BiquadResonantFilter\x00"
+				"DCRemovalFilter\x00"
+				"EchoFilter\x00"
+				"FFTFilter\x00"
+				"FlangerFilter\x00"
+				"FreeverbFilter\x00"
+				"LofiFilter\x00"
+				"RobotizeFilter\x00"
+				"WaveShaperFilter\x00\x00"))
+			{
+				if (gFilterSelect[filterindex])
+					gSoloud.setGlobalFilter(filterindex, gFilter[gFilterSelect[filterindex] - 1]);
+				else
+					gSoloud.setGlobalFilter(filterindex, 0);
+			}
+
+			if (gFilterSelect[filterindex] != 0)
+			{
+				SoLoud::Filter* f = gFilter[gFilterSelect[filterindex] - 1];
+				int count = f->getParamCount();
+				for (int i = 0; i < count; i++)
+				{
+					int filtertype = f->getParamType(i);
+					float filtermin = f->getParamMin(i);
+					float filtermax = f->getParamMax(i);
+
+					if (filtertype == SoLoud::Filter::INT_PARAM)
+					{
+						int v = (int)gSoloud.getFilterParameter(0, filterindex, i);
+						char temp[128];
+						sprintf(temp, "%s##%d-%d", f->getParamName(i), filterindex, i);
+						if (ImGui::SliderInt(temp, &v, (int)filtermin, (int)filtermax))
+						{
+							gSoloud.setFilterParameter(0, filterindex, i, (float)v);
+						}
+					}
+
+					if (filtertype == SoLoud::Filter::FLOAT_PARAM)
+					{
+						float v = gSoloud.getFilterParameter(0, filterindex, i);
+						char temp[128];
+						sprintf(temp, "%s##%d-%d", f->getParamName(i), filterindex, i);
+						if (ImGui::SliderFloat(temp, &v, filtermin, filtermax))
+						{
+							gSoloud.setFilterParameter(0, filterindex, i, v);
+						}
+					}
+
+					if (filtertype == SoLoud::Filter::BOOL_PARAM)
+					{
+						float v = gSoloud.getFilterParameter(0, filterindex, i);
+						bool bv = v > 0.5f;
+						char temp[128];
+						sprintf(temp, "%s##%d-%d", f->getParamName(i), filterindex, i);
+						if (ImGui::Checkbox(temp, &bv))
+							//SliderFloat(temp, &v, filtermin, filtermax))
+						{
+							gSoloud.setFilterParameter(0, filterindex, i, bv?1.0f:0.0f);
+						}
+					}
+				}
+			}
+		}
+		ImGui::End();
+		
+		DemoUpdateEnd();
+	}
+}
+
+int DemoEntry_filterfolio(int argc, char *argv[])
+{
+	return filterfolio::DemoEntry(argc, argv);
+}
+
+void DemoMainloop_filterfolio()
+{
+	return filterfolio::DemoMainloop();
+}

+ 26 - 2
soloud.mod/soloud/demos/megademo/main.cpp

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2018 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -60,6 +60,10 @@ extern void DemoMainloop_speakers();
 extern int DemoEntry_speakers(int argc, char *argv[]);
 extern void DemoMainloop_thebutton();
 extern int DemoEntry_thebutton(int argc, char *argv[]);
+extern void DemoMainloop_annex();
+extern int DemoEntry_annex(int argc, char* argv[]);
+extern void DemoMainloop_filterfolio();
+extern int DemoEntry_filterfolio(int argc, char* argv[]);
 
 void DemoMainloop()
 {
@@ -206,8 +210,28 @@ void DemoMainloop_megademo()
 		        "avoiding actor speaking on top\n"
 		        "of themselves.\n");
 
-	ImGui::End();
+	ImGui::Separator();
+
+	if (ImGui::Button("annex"))
+	{
+		DemoEntry_annex(gArgc, gArgv);
+		DemoMainloopPtr = DemoMainloop_annex;
+	}
+	ImGui::Text("annex test moves a live sound\n"
+	"from one mixing bus to another.\n");
 
+	ImGui::Separator();
+
+	if (ImGui::Button("Filter folio"))
+	{
+		DemoEntry_filterfolio(gArgc, gArgv);
+		DemoMainloopPtr = DemoMainloop_filterfolio;
+	}
+	ImGui::Text("Filter folio is a playground\n"
+		"for various filters and their parameters.\n");
+
+	ImGui::End();
+	
 
 	DemoUpdateEnd();
 }

+ 31 - 11
soloud.mod/soloud/demos/megademo/monotone.cpp

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2018 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -88,24 +88,44 @@ namespace monotone
 		}
 		if (ImGui::CollapsingHeader("Waveform", (const char*)0, true, false))
 		{
-			if (ImGui::RadioButton("Square", waveform == SoLoud::Monotone::SQUARE))
+			if (ImGui::RadioButton("Square", waveform == SoLoud::Soloud::WAVE_SQUARE))
 			{
-				waveform = SoLoud::Monotone::SQUARE;
+				waveform = SoLoud::Soloud::WAVE_SQUARE;
 				gMusic.setParams(hwchannels, waveform);
 			}
-			if (ImGui::RadioButton("Saw", waveform == SoLoud::Monotone::SAW))
+			if (ImGui::RadioButton("Saw", waveform == SoLoud::Soloud::WAVE_SAW))
 			{
-				waveform = SoLoud::Monotone::SAW;
+				waveform = SoLoud::Soloud::WAVE_SAW;
 				gMusic.setParams(hwchannels, waveform);
 			}
-			if (ImGui::RadioButton("Sin", waveform == SoLoud::Monotone::SIN))
+			if (ImGui::RadioButton("Sin", waveform == SoLoud::Soloud::WAVE_SIN))
 			{
-				waveform = SoLoud::Monotone::SIN;
+				waveform = SoLoud::Soloud::WAVE_SIN;
 				gMusic.setParams(hwchannels, waveform);
 			}
-			if (ImGui::RadioButton("SawSin", waveform == SoLoud::Monotone::SAWSIN))
+			if (ImGui::RadioButton("Bounce", waveform == SoLoud::Soloud::WAVE_BOUNCE))
 			{
-				waveform = SoLoud::Monotone::SAWSIN;
+				waveform = SoLoud::Soloud::WAVE_BOUNCE;
+				gMusic.setParams(hwchannels, waveform);
+			}
+			if (ImGui::RadioButton("Jaws", waveform == SoLoud::Soloud::WAVE_JAWS))
+			{
+				waveform = SoLoud::Soloud::WAVE_JAWS;
+				gMusic.setParams(hwchannels, waveform);
+			}
+			if (ImGui::RadioButton("Humps", waveform == SoLoud::Soloud::WAVE_HUMPS))
+			{
+				waveform = SoLoud::Soloud::WAVE_HUMPS;
+				gMusic.setParams(hwchannels, waveform);
+			}
+			if (ImGui::RadioButton("Fourier square", waveform == SoLoud::Soloud::WAVE_FSQUARE))
+			{
+				waveform = SoLoud::Soloud::WAVE_FSQUARE;
+				gMusic.setParams(hwchannels, waveform);
+			}			
+			if (ImGui::RadioButton("Fourier saw", waveform == SoLoud::Soloud::WAVE_FSAW))
+			{
+				waveform = SoLoud::Soloud::WAVE_FSAW;
 				gMusic.setParams(hwchannels, waveform);
 			}
 		}
@@ -137,7 +157,7 @@ namespace monotone
 		gMusic.setParams(10);
 
 		gEcho.setParams(0.2f, 0.5f, 0.05f);
-		gBiquad.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 44100, 4000, 2);
+		gBiquad.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 4000, 2);
 
 		gMusic.setLooping(1);
 		gMusic.setFilter(0, &gBiquad);
@@ -148,7 +168,7 @@ namespace monotone
 		gSoloud.init(SoLoud::Soloud::CLIP_ROUNDOFF | SoLoud::Soloud::ENABLE_VISUALIZATION);
 
 		gMusichandle = gSoloud.play(gMusic);
-		waveform = SoLoud::Monotone::SAW;
+		waveform = SoLoud::Soloud::WAVE_SAW;
 		gMusic.setParams(hwchannels, waveform);
 
 		return 0;

+ 1 - 0
soloud.mod/soloud/demos/megademo/multimusic.cpp

@@ -79,6 +79,7 @@ namespace multimusic
 		ImGui::Text("Music1 volume    : %d%%", (int)floor(gSoloud.getVolume(gMusichandle1) * 100));
 		ImGui::Text("Music2 volume    : %d%%", (int)floor(gSoloud.getVolume(gMusichandle2) * 100));
 		ImGui::Text("Music rel. speed : %d%%", (int)floor(gSoloud.getRelativePlaySpeed(gMusichandle2) * 100));
+		ImGui::Text("Music position   : %d%%", (int)floor(gSoloud.getStreamPosition(gMusichandle2) * 100 / gMusic1.getLength()));
 		ImGui::Text("Active voices    : %d", gSoloud.getActiveVoiceCount());
 		ImGui::End();
 

+ 4 - 3
soloud.mod/soloud/demos/megademo/pewpew.cpp

@@ -73,6 +73,7 @@ namespace pewpew
 		int tick = DemoTick();
 		x = (gMouseX - 400.0f) / 200.0f;
 
+
 		if (lasttick >= tick)
 		{
 			DemoYield();
@@ -86,7 +87,7 @@ namespace pewpew
 				gSfx.loadPreset(SoLoud::Sfxr::LASER, 3);
 				if (fire1)
 				{
-					gSoloud.playClocked(lasttick / 1000.0f, gSfx, 1, x);
+					gSoloud.playClocked(DemoTick() / 1000.0f, gSfx, 1, x);
 					bulletc[bulletidx] = 1;
 				}
 
@@ -98,7 +99,7 @@ namespace pewpew
 
 				if (fire3)
 				{
-					gSoloud.playClocked(lasttick / 1000.0f, gSfx, 1, x);
+					gSoloud.playClocked(DemoTick() / 1000.0f, gSfx, 1, x);
 					bulletc[bulletidx] = 1;
 				}
 
@@ -131,7 +132,7 @@ namespace pewpew
 					}
 				}
 
-				lasttick += 40;
+				lasttick += 10;
 			}
 
 			DemoUpdateStart();

+ 2 - 2
soloud.mod/soloud/demos/megademo/space.cpp

@@ -75,8 +75,8 @@ namespace space
 		gSpeech.setFilter(2, &gReso);
 		gLofi.setParams(8000, 4);
 		gFlanger.setParams(0.002f, 100);
-		//	gReso.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 8000, 500, 5);
-		gReso.setParams(SoLoud::BiquadResonantFilter::BANDPASS, 8000, 1000, 0.5);
+		//	gReso.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 500, 5);
+		gReso.setParams(SoLoud::BiquadResonantFilter::BANDPASS, 1000, 0.5);
 
 		gSpeech.setText("What the alien has to say might\n"
 			"appear around here if this\n"

+ 1 - 1
soloud.mod/soloud/demos/megademo/speechfilter.cpp

@@ -224,7 +224,7 @@ namespace speechfilter
 	int DemoEntry(int argc, char *argv[])
 	{
 		gEcho.setParams(0.2f, 0.5f, 0.05f);
-		gBiquad.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 44100, 4000, 2);
+		gBiquad.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 4000, 2);
 
 		gSpeech.setLooping(1);
 		gVizsn.setLooping(1);

+ 1 - 1
soloud.mod/soloud/demos/megademo/tedsid.cpp

@@ -54,7 +54,7 @@ namespace tedsid
 		gMusic2.load("audio/ted_storm.prg.dump");
 
 		gEcho.setParams(0.2f, 0.5f, 0.05f);
-		gBiquad.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 44100, 4000, 2);
+		gBiquad.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 4000, 2);
 
 		gMusic1.setLooping(1);
 		gMusic2.setLooping(1);

+ 1 - 0
soloud.mod/soloud/demos/megademo/thebutton.cpp

@@ -52,6 +52,7 @@ namespace SoLoud
 			mSourceCountMax = 0;
 			mAck = 0;
 			mBus = 0;
+			mAckLength = 0;
 		}
 
 		result init(Soloud &aSoloud, Bus *aBus)

+ 3 - 3
soloud.mod/soloud/demos/piano/main.cpp

@@ -342,21 +342,21 @@ void DemoMainloop()
 		if (ImGui::RadioButton("Lowpass", gFilterSelect == 1))
 		{
 			gFilterSelect = 1;
-			gBQRFilter.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 44100, 1000, 2);
+			gBQRFilter.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 1000, 2);
 			gBus.setFilter(2, &gBQRFilter);
 			say("Low pass filter");
 		}
 		if (ImGui::RadioButton("Highpass", gFilterSelect == 2))
 		{
 			gFilterSelect = 2;
-			gBQRFilter.setParams(SoLoud::BiquadResonantFilter::HIGHPASS, 44100, 1000, 2);
+			gBQRFilter.setParams(SoLoud::BiquadResonantFilter::HIGHPASS, 1000, 2);
 			gBus.setFilter(2, &gBQRFilter);
 			say("High pass filter");
 		}
 		if (ImGui::RadioButton("Bandpass", gFilterSelect == 3))
 		{
 			gFilterSelect = 3;
-			gBQRFilter.setParams(SoLoud::BiquadResonantFilter::BANDPASS, 44100, 1000, 2);
+			gBQRFilter.setParams(SoLoud::BiquadResonantFilter::BANDPASS, 1000, 2);
 			gBus.setFilter(2, &gBQRFilter);
 			say("Band pass filter");
 		}

+ 2 - 0
soloud.mod/soloud/demos/piano/soloud_padsynth.cpp

@@ -74,6 +74,8 @@ class PADsynth {
 	virtual float RND();
 
     private:
+	PADsynth(const PADsynth&); // disable copy
+	PADsynth& operator=(PADsynth const&);
 	float *mHarmonics;		//Amplitude of the harmonics
 	float *mFreqAmp;	//Amplitude spectrum
 	float mSamplerate;

+ 4 - 1
soloud.mod/soloud/docsrc/SoLoud.tex

@@ -67,7 +67,7 @@ These pages were intentionally left blank.
 
 \newpage
 
-© 2018 Komppa, Jari\\
+© 2020 Komppa, Jari\\
 %Kustantaja: BoD - Books on Demand, Helsinki, Suomi\\
 %Valmistaja: BoD - Books on Demand, Norderstedt, Saksa\\
 %ISBN: 978-952-80-0359-5
@@ -125,6 +125,7 @@ These pages were intentionally left blank.
 \include{temp/tedsid}
 \include{temp/vizsn}
 \include{temp/vic}
+\include{temp/noise}
 
 \include{temp/filters}
 \include{temp/biquadfilter}
@@ -135,6 +136,8 @@ These pages were intentionally left blank.
 \include{temp/fftfilter}
 \include{temp/bassboostfilter}
 \include{temp/waveshaperfilter}
+\include{temp/robotizefilter}
+\include{temp/freeverbfilter}
 
 \include{temp/mixbus}
 \include{temp/queue}

+ 21 - 2
soloud.mod/soloud/docsrc/attributes.mmd

@@ -43,13 +43,21 @@ If an invalid handle is given to getPan, it will return 0.
 
 ### Soloud.setPanAbsolute()
 
-These function can be used to set the left/right volumes directly.
+This function can be used to set the left/right volumes directly.
 
     soloud.setPanAbsolute(h, 1, 1); // full blast
 
 Note that this does not affect the value returned by getPan.
 
-If an invalid handle is given to getPan, it will return 0.
+If the audio source has more than two channels, volume is adjusted for all channels.
+
+### Soloud.setChannelVolume()
+
+This function can be used to adjust specific channel (speaker) volume for a handle.
+
+    soloud.setChannelVolume(h, 1, 1.1f); // set right channel to 110%
+    
+If an invalid channel number is given, nothing happens.
 
 ### Soloud.getSamplerate(), Soloud.setSamplerate()
 
@@ -176,3 +184,14 @@ inaudible.
 
     // The dictator's speech must go on even if not heard
     soloud.setInaudibleBehavior(h, true, false);
+
+
+### Soloud.getMainResampler(), Soloud.setMainResampler()
+
+Set or get the main resampler. The default is linear interpolator.
+
+This is the resampler for the main mixer. Setting the main resampler does not change the resamplers busses use.
+
+    // Use point-sample resampler
+    soloud.setMainResampler(SoLoud::Soloud::RESAMPLER_POINT);
+    

+ 3 - 0
soloud.mod/soloud/docsrc/audiosource.mmd

@@ -39,6 +39,9 @@ This function can be used to tell SoLoud that only one instance of this
 sound may be played at the same time.
 
     menuselect.setSingleInstance(1); // Only play it once, Sam
+    
+This may be useful if, for example, you play a sound effect every time user
+interacts with a menu, and don't want the effect to overlap.
 
 ### AudioSource.set3dMinMaxDistance()
 

+ 8 - 5
soloud.mod/soloud/docsrc/backends.mmd

@@ -10,14 +10,14 @@ addition to the optional mutex function pointers.
 Studying the existing back-end implementations' source code, in addition
 to this page, will help creating new ones.
 
-### Soloud.postinit()
+### Soloud.postinit_internal()
 
 
-The back-end should call Soloud.postinit() once it knows what it can do.
+The back-end should call Soloud.postinit_internal() once it knows what it can do.
 
-    void postinit(int aSamplerate, // Sample rate, in Hz
-                  int aBufferSize, // Buffer size, in samples
-                  int aFlags);     // Flags
+    void postinit_internal(int aSamplerate, // Sample rate, in Hz
+                           int aBufferSize, // Buffer size, in samples
+                           int aFlags);     // Flags
 
 The channels and flags most likely come directly from the application,
 while sample rate and buffer size may depend on how the back-end does
@@ -93,12 +93,15 @@ SDL/SDL2 DLL   Yes  Most tested, primary development platform. Cross-platform. L
 SDL Static     ?    Mostly meant for emscripten use.
 SDL2 Static    Yes  Can be used to statically link to SDL2.
 PortAudio      ?    Cross-platform. Very low latency. Dynamic linking.
+MiniAudio      Yes  Cross-platform, very low latency. Included with SoLoud.
 WinMM          Yes  Simplest back-end for Windows-only programs.
 ALSA           Yes  Default audio interface for Linux
+JACK           ?    Alternative audio interface for Linux
 oss (/dev/dsp) Yes  Simplest back-end for Linux-only programs. Experimental.
 OpenAL         ?    Very experimental. Very high latency; if this is your only option, you're probably better off using OpenAL directly.
 WASAPI         Yes  Experimental
 XAudio2        Yes  Experimental
+Nosound        Yes  Plays audio, throws it away.
 Null driver    Yes  Can be used to use SoLoud without audio device.
 
 Some of the backends have not been tested in x64 builds, but as long as everything is x64, there's no real reason why they don't work.

+ 12 - 5
soloud.mod/soloud/docsrc/basics.mmd

@@ -46,11 +46,12 @@ it prefers, and its default parameters.
 
 Currently, you can select from these flags:
 
-Flag                 | Description
-----                 | ------------
-CLIP_ROUNDOFF        | Use roundoff clipper. Without this flag the clipper defaults to "hard" clipping to -1/+1
-ENABLE_VISUALIZATION | Enable gathering of visualization data. Can be changed at runtime with setVisualizationEnable()
-LEFT_HANDED_3D       | Use left-handed (Direct3D) 3d coordinates. Default is right-handed (OpenGL) coordinates.
+Flag                   | Description
+----                   | ------------
+CLIP_ROUNDOFF          | Use roundoff clipper. Without this flag the clipper defaults to "hard" clipping to -1/+1
+ENABLE_VISUALIZATION   | Enable gathering of visualization data. Can be changed at runtime with setVisualizationEnable()
+LEFT_HANDED_3D         | Use left-handed (Direct3D) 3d coordinates. Default is right-handed (OpenGL) coordinates.
+NO_FPU_REGISTER_CHANGE | Do not alter the FPU state in audio threads. By default, SoLoud uses "fast" fpu options.
 
 Current set of back-ends is:
 
@@ -60,15 +61,18 @@ AUTO          | Select backend automatically
 SDL1          | SDL1 dynamic or static linking
 SDL2          | SDL2 dynamic or static linking
 PORTAUDIO     | PortAudio
+MINIAUDIO     | MiniAudio
 WINMM         | Windows MultiMedia
 XAUDIO2       | XAudio2
 WASAPI        | Windows Audio Session API
 ALSA          | Advanced Linux Sound Architecture
+JACK          | JACK Audio Connection Kit
 OSS           | Open Sound System
 OPENAL        | OpenAL (high latency)
 COREAUDIO     | OSX CoreAudio
 OPENSLES      | OpenSL ES
 VITA_HOMEBREW | Vita console homebrew SDK
+NOSOUND       | No-sound driver
 NULLDRIVER    | Null driver
 
 \pagebreak
@@ -157,6 +161,9 @@ used) to calculate the delay between two sound effects. If a output
 sound buffer threshold is passed between the two sounds, SoLoud will
 adjust the delay accordingly.
 
+Note that if your "physics time" granularity is low, playClocked is
+not really useful. Audio buffers tend to be 40ms long at most.
+
 \pagebreak
 
 ### Soloud.playBackground()

+ 12 - 0
soloud.mod/soloud/docsrc/bassboostfilter.mmd

@@ -26,3 +26,15 @@ can be set, faded or oscillated:
       SoLoud::BassboostFilter::BOOST, // What to adjust
       0,            // Target value
       3);           // Time in seconds
+
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- BassboostFilter.getParamCount()
+- BassboostFilter.getParamName()
+- BassboostFilter.getParamType()
+- BassboostFilter.getParamMax()
+- BassboostFilter.getParamMin()
+

+ 12 - 2
soloud.mod/soloud/docsrc/biquadfilter.mmd

@@ -15,7 +15,7 @@ The resonance parameter adjusts the sharpness (or bandwidth) of the
 cutoff.
 
     // Set up low-pass filter
-    gBQRFilter.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 44100, 500, 2);  
+    gBQRFilter.setParams(SoLoud::BiquadResonantFilter::LOWPASS, 500, 2);  
     // Set the filter as the second filter of the bus
     gBus.setFilter(1, &gBQRFilter); 
 
@@ -33,7 +33,6 @@ Currently, four parameters can be adjusted:
 Parameter   Description
 ----        ------------
 WET         Filter's wet signal; 1.0f for fully filtered, 0.0f for original, 0.5f for half and half.
-SAMPLERATE  Filter's samplerate parameter
 FREQUENCY   Filter's cutoff frequency
 RESONANCE   Filter's resonance - higher means sharper cutoff
 
@@ -47,3 +46,14 @@ Set the parameters of the filter.
     
 Changing the parameters does not affect "live" sounds. If invalid parameters are
 given, the function will return error.
+
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- BiquadResonantFilter.getParamCount()
+- BiquadResonantFilter.getParamName()
+- BiquadResonantFilter.getParamType()
+- BiquadResonantFilter.getParamMax()
+- BiquadResonantFilter.getParamMin()

+ 16 - 13
soloud.mod/soloud/docsrc/concepts.mmd

@@ -44,8 +44,8 @@ channels), but surround sound audio sources may practically have any
 number of channels.
 
 In module music (such as mod, s3m, xm, it), "channel" means one of the
-concurrent sounds played, regardless of speaker configuration. Confusing,
-yes.
+concurrent sounds played, regardless of speaker configuration. Confusing?
+Yes.
 
 ### Voice
 
@@ -196,15 +196,17 @@ resampling is needed, but this is often not true.
 
 ![Different resamplers (Point / linear / catmull-rom). Red is the ideal signal.](images/resampler)\ 
 
-Currently, SoLoud supports "linear interpolation", which calculates linear 
-interpolation of samples, as well as "point sample" resampling, which 
-means it simply skips or repeats samples as needed.
-
-Picking the resampler is done by editing the soloud.h file.
+Currently, SoLoud supports "point sample" resampling, which means it simply skips 
+or repeats samples as needed, "linear interpolation", which calculates linear 
+interpolation of samples, as well as "catmull-rom" which, instead of doing
+linear interpolation, uses a catmull-rom spline to interpolate the samples.
 
 The linear interpolation resampler is used by default.
 
-Higher quality resamplers are planned.
+The resampler can be set on a per-bus basis, so if you want to use a higher (or lower) quality
+resampler for a certain bus, you can do so. Note that if all sample data has the same
+sample rate, the point sample resampler will actually produce the best results, as it
+will not affect the signal (in that, and only in that case).
 
 ### Pan
 
@@ -219,12 +221,12 @@ directly, if needed.
 
 
 SoLoud uses throwaway handles to control sounds. The handle is an
-integer, and internally tracks the channel and sound id, as well as an
+integer, and internally tracks the voice and sound id, as well as an
 "uniqueness" value.
 
 If you try to use a handle after the sound it represents has stopped,
 the operation is quietly discarded (or if you're requesting information,
-some kind of generic value is returned). You can also query the validity
+some kind of generic value is returned, usually 0). You can also query the validity
 of a handle.
 
 ### Latency
@@ -244,8 +246,9 @@ there's no data ready to be played) and the sound breaks down horribly.
 Assuming there's no other sources of latency (and there quite likely
 is), with 2048 sample buffer and 44100Hz playback, the latency is around
 46 milliseconds, which is tolerable in most computer game use cases. A 
-100ms latency is already easily noticeable. For playing drums, 40ms 
-is too much.
+100ms latency is already easily noticeable. In music terms, when playing
+drums, 40ms is too much, but when playing slowly evolving atmospheric pads,
+200ms is fine.
 
 ### Filter
 
@@ -254,7 +257,7 @@ Audio streams can also be modified on the fly for various effects.
 Typical uses are different environmental effects such as echoes or
 reverb, or low pass (bassy sound) / high pass (tinny sound) filters, but
 basically any kind of modification can be done; the primary limitations
-are processor power, imagination, and developer's skill in digital
+are processor power, imagination, and the developer's skill in digital
 signal processing.
 
 SoLoud lets you hook several filters to a single audio stream, as well

+ 1 - 1
soloud.mod/soloud/docsrc/concepts3d.mmd

@@ -6,7 +6,7 @@ In practise, all the "3d audio" does is adjust panning and play speed of your au
 
 Any audio source can be 3d, including mixing busses. However, true 3d positioning only really makes sense for mono audio sources.
 
-The doppler and attenuation calculations follow the OpenAL functions.
+The doppler and attenuation calculations follow the OpenAL equations.
 
 In order to use the 3d audio, use the 3d versions of the play commands, adjust the positions and velocities of your audio sources and listener with the set3dSource...() and set3dListener...() calls, and call update3dAudio() to ask SoLoud to recalculate the proper panning (and play speed, for doppler).
 

+ 11 - 0
soloud.mod/soloud/docsrc/dcremovalfilter.mmd

@@ -26,3 +26,14 @@ Set the parameters of the filter.
     
 Changing the parameters does not affect "live" sounds. If invalid parameters are
 given, the function will return error.
+
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- DCRemovalFilter.getParamCount()
+- DCRemovalFilter.getParamName()
+- DCRemovalFilter.getParamType()
+- DCRemovalFilter.getParamMax()
+- DCRemovalFilter.getParamMin()

+ 3 - 2
soloud.mod/soloud/docsrc/dirstruct.mmd

@@ -17,6 +17,7 @@ glue      All the glue libraries for various environments, like rpgmaker, c#, py
 build     The GENie / premake script that can be used to generate build scripts for various IDEs or a gnu makefile.
 demos     SoLoud's demos showing how to use SoLoud's various features.
 src       Source code for SoLoud itself
+contrib   Additional files that are not maintained by SoLoud project itself, such as cmakefiles, but may be useful to some people.
 
 
 ### src
@@ -32,8 +33,8 @@ src/tools       Some command-line tools under the src/tools directory. Most of t
 
 ### demos
 
-Most of the demos use some common code based on Ocornut's Dear ImGui library. This is to make the source for the demo itself mostly about SoLoud and not about putting pixels on the screen, while having an easy to use UI
-for the demos.
+Most of the demos are based on SDL2 and use some common code based on Ocornut's Dear ImGui library. This is to make the source for the demo itself mostly about SoLoud 
+and not about putting pixels on the screen, while having an easy to use UI for the demos.
 
 Directory        Description
 ----             ------------

+ 42 - 3
soloud.mod/soloud/docsrc/downloads.mmd

@@ -5,11 +5,14 @@ This page lists SoLoud downloads, as well as other relevant information.
 
 Latest stable release
 ---------------------
-[soloud_20181119.zip](soloud_20181119.zip) <<- Download here (~47 MB)
+[soloud_20200207.zip](soloud_20200207.zip) <<- Download here (~47 MB)
 
-[soloud_20181119_lite.zip](soloud_20181119_lite.zip)  (~3 MB)
+[soloud_20200207_lite.zip](soloud_20200207_lite.zip)  (~3 MB)
 
-Documentation: [PDF](soloud_20181119.pdf) | [EPUB](soloud_20181119.epub) | [MOBI](soloud_20181119.mobi) | [HTML](soloud_20181119.html) 
+Documentation: [PDF](soloud_20200207.pdf) | [EPUB](soloud_20200207.epub) | [MOBI](soloud_20200207.mobi) | [HTML](soloud_20200207.html) 
+
+Book
+----
 
 You can also buy the documentation as a physical book (version 20181119): 
 
@@ -18,6 +21,8 @@ You can also buy the documentation as a physical book (version 20181119):
 - [bookdepository](https://www.bookdepository.com/SoLoud-Audio-Engine-Jari-Komppa/9789528003595)
 - [blackwell's](https://blackwells.co.uk/bookshop/product/9789528003595)
 
+There won't be new versions of the physical book every time SoLoud releases because those things cost money and unless they suddely start selling hundreds of copies, it's not financially viable.
+
 Development
 -----------
 You can find the latest, bleeding-edge version on GitHub at: <https://github.com/jarikomppa/soloud>. Note that the latest development version may be unstable.
@@ -42,6 +47,40 @@ Additional files
 
 Release history
 ---------------
+[soloud_20200207.zip](soloud_20200207.zip) <<- Download here (~47 MB)
+
+[soloud_20200207_lite.zip](soloud_20200207_lite.zip)  (~3 MB)
+
+Documentation: [PDF](soloud_20200207.pdf) | [EPUB](soloud_20200207.epub) | [MOBI](soloud_20200207.mobi) | [HTML](soloud_20200207.html) 
+
+- Oops, it's over a year already, let's do a refresh
+- Hilights:
+    - Python 3 migration
+    - Updated dr_ and stb_ libraries
+    - Changing volume while paused should now work
+    - Filters can now be queried for live parameters and ranges
+    - Set FPU flags in audio threads to ignore denorms, performance gain (can be disabled at runtime)
+    - New feature: ability to move live sounds from one bus to another (annexSound)
+    - New backend: JACK
+    - New backend: Nosound
+    - New backend: MiniAudio
+    - New demo: annex
+    - New demo: Filter Folio for playing with filters
+    - New audio source: Noise
+    - New filter: FreeVerb
+    - New namespace: Misc, including pseudorandom generator and waveform generator
+    - Monotone now has new waveforms
+    - Rewritten robotize filter
+    - Internal calls in Soloud class renamed to _internal to avoid confusion
+    - sdl headers now loaded as "sdl.h" instead of "sdl/sdl.h"
+    - Removed portmidi, using rtmidi instead (piano example)
+    - Added const in several places due to peer pressure
+    - WinMM backend no longer leaks resources if init fails
+    - Several queue fixes
+    - WASAPI backend fixes
+    - deprecated usleep -> nanosleep
+    - A lot of cppcheck, lgtm, pvs-studio and other static code analysis fixes
+    - A pile of smaller bug fixes and inevitably new bugs.
 
 [soloud_20181119.zip](soloud_20181119.zip) <<- Download here (~47 MB)
 

+ 11 - 0
soloud.mod/soloud/docsrc/echofilter.mmd

@@ -24,3 +24,14 @@ Set the parameters of the filter.
     
 Changing the parameters does not affect "live" sounds. If invalid parameters are
 given, the function will return error.
+
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- EchoFilter.getParamCount()
+- EchoFilter.getParamName()
+- EchoFilter.getParamType()
+- EchoFilter.getParamMax()
+- EchoFilter.getParamMin()

+ 3 - 0
soloud.mod/soloud/docsrc/faq.mmd

@@ -96,6 +96,9 @@ for the future.
 
 Yes. SoLoud supports 1, 2, 4, 5.1 and 7.1 configurations.
 
+The way multi-speaker system is implemented in SoLoud, it would be relatively easy to add any number of speakers,
+but having more output channels also adds overhead. Most people will only ever use stereo output.
+
 ### Are these real questions?
 
 

+ 11 - 0
soloud.mod/soloud/docsrc/fftfilter.mmd

@@ -6,3 +6,14 @@ does a simple tone downshifting.
 
 The filter exists mainly to adjust the speech synthesizer's voice in
 strange ways. It can also be used as basis for other FFT-based filters.
+
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- FFTFilter.getParamCount()
+- FFTFilter.getParamName()
+- FFTFilter.getParamType()
+- FFTFilter.getParamMax()
+- FFTFilter.getParamMin()

+ 2 - 2
soloud.mod/soloud/docsrc/file.mmd

@@ -116,8 +116,8 @@ buffer.
 
 ### soloud_file_hack_on.h, soloud_file_hack_off.h
 
-SoLoud comes with a pair of headers you can use to fool code which uses the FILE*
-interface to use File* instead. 
+SoLoud comes with a pair of headers you can use to fool code which uses the FILE\*
+interface to use File\* instead. 
 
 The files use preprocessor macros to turn FILE* calls into SoLoud's wrapper
 function calls which in turn use the File class interfaces. Since it's a 

+ 19 - 0
soloud.mod/soloud/docsrc/filters.mmd

@@ -156,3 +156,22 @@ parameters. The default implementation uses the mParamFader array.
 
 Unless you do something unexpected, you shouldn't need to touch
 this function.
+
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- getParamCount()
+- getParamName()
+- getParamType()
+- getParamMax()
+- getParamMin()
+
+These functions are mostly useful at runtime, to get information about
+filters without knowing which filter you're talking with, such as
+with an editor. See "Filter Folio" demo as an example.
+
+The max/min values are suggestions; filters may function outside
+the suggested ranges, but in some cases (especially with value zero)
+may lead to very bad audio or possibly even crashes.

+ 11 - 0
soloud.mod/soloud/docsrc/flangerfilter.mmd

@@ -33,3 +33,14 @@ Set the parameters of the filter.
     
 Changing the parameters does not affect "live" sounds. If invalid parameters are
 given, the function will return error.
+
+\pagebreak
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- FlangerFilter.getParamCount()
+- FlangerFilter.getParamName()
+- FlangerFilter.getParamType()
+- FlangerFilter.getParamMax()
+- FlangerFilter.getParamMin()

+ 27 - 0
soloud.mod/soloud/docsrc/freeverbfilter.mmd

@@ -0,0 +1,27 @@
+## SoLoud::FreeverbFilter
+
+Freeverb is a reverb filter based on the code written by Jezar at Dreampoint, 
+June 2000 http://www.dreampoint.co.uk, and placed under public domain. There
+are other versions of Freeverb out there with different licenses. 
+
+While it sounds great, the filter is relatively heavy, and should be used sparingly.
+
+### FreeverbFilter.setParams()
+
+Set parameters of the filter. Does not affect "live" filters.
+
+    verb.setParams(0, 0.5f, 0.5f, 1);
+    
+The mode parameter freezes the audio currently flowing through the
+filter; setting it to 1 before playing audio will cause the filter
+to just replicate silence.
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- FreeverbFilter.getParamCount()
+- FreeverbFilter.getParamName()
+- FreeverbFilter.getParamType()
+- FreeverbFilter.getParamMax()
+- FreeverbFilter.getParamMin()

+ 1 - 1
soloud.mod/soloud/docsrc/htmlpost.txt

@@ -1,4 +1,4 @@
-<p>Copyright&copy;2013-2018 <a href="http://iki.fi/sol/">Jari Komppa</a></p>
+<p>Copyright&copy;2013-2020 <a href="http://iki.fi/sol/">Jari Komppa</a></p>
 
 <div class="advert">
 <script type="text/javascript"><!--

+ 3 - 0
soloud.mod/soloud/docsrc/htmlpre.txt

@@ -73,6 +73,7 @@ ga('send', 'pageview');
 <a href="tedsid.html">SoLoud::TedSid</a><br>
 <a href="vizsn.html">SoLoud::Vizsn</a><br>
 <a href="vic.html">SoLoud::Vic</a><br>
+<a href="noise.html">SoLoud::Noise</a><br>
 <br>
 <a href="filters.html">SoLoud::Filter</a><br>
 <a href="biquadfilter.html">SoLoud::BiquadReso..</a><br>
@@ -83,6 +84,8 @@ ga('send', 'pageview');
 <a href="fftfilter.html">SoLoud::FFTFilter</a><br>
 <a href="bassboostfilter.html">SoLoud::BassBoost..</a><br>
 <a href="waveshaperfilter.html">SoLoud::WaveShaper..</a><br>
+<a href="robotizefilter.html">SoLoud::Robotize..</a><br>
+<a href="freeverbfilter.html">SoLoud::Freeeverb..</a><br>
 <br>
 <a href="mixbus.html">SoLoud::Bus</a><br>
 <a href="queue.html">SoLoud::Queue</a><br>

+ 9 - 2
soloud.mod/soloud/docsrc/legal.mmd

@@ -16,7 +16,7 @@ SoLoud proper is licensed under the ZLib/LibPNG license. The code is a
 clean-room implementation with no outside sources used.
 
     SoLoud audio engine
-    Copyright (c) 2013-2018 Jari Komppa
+    Copyright (c) 2013-2020 Jari Komppa
 
     This software is provided 'as-is', without any express or implied
     warranty. In no event will the authors be held liable for any damages
@@ -257,4 +257,11 @@ SoLoud does not include Openmpt in itself, but can use it through a DLL.
 If you don't need it, you don't need to include the DLL either. If you DO
 need to use it, please look up its license.
 
-    
+### FreeVerb
+
+Based on code by Jezar at Dreampoint, June 2000 
+http://www.dreampoint.co.uk, which was placed under public domain.
+
+Note that the version of FreeVerb included in SoLoud is based on the original, public domain
+release, and not the GPL-licensed FreeVerb3. 
+

+ 13 - 0
soloud.mod/soloud/docsrc/lofifilter.mmd

@@ -26,6 +26,8 @@ WET         Filter's wet signal; 1.0f for fully filtered, 0.0f for original, 0.5
 SAMPLERATE  Filter's samplerate parameter
 BITDEPTH    Filter's bit-depth parameter
 
+Note that the bit depth does not need to be an integer value.
+
 ### LofiFilter.setParams()
 
 Set the parameters of the filter.
@@ -34,3 +36,14 @@ Set the parameters of the filter.
     
 Changing the parameters does not affect "live" sounds. If invalid parameters are
 given, the function will return error.
+
+\pagebreak
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- LofiFilter.getParamCount()
+- LofiFilter.getParamName()
+- LofiFilter.getParamType()
+- LofiFilter.getParamMax()
+- LofiFilter.getParamMin()

+ 15 - 6
soloud.mod/soloud/docsrc/makedoc.py

@@ -49,6 +49,7 @@ src = [
     "tedsid.mmd",
     "vizsn.mmd",
     "vic.mmd",
+    "noise.mmd",
     "filters.mmd",
     "biquadfilter.mmd",
     "echofilter.mmd",
@@ -58,6 +59,8 @@ src = [
     "fftfilter.mmd",
     "bassboostfilter.mmd",
     "waveshaperfilter.mmd",
+    "robotizefilter.mmd",
+    "freeverbfilter.mmd",
     "mixbus.mmd",
     "queue.mmd",
     "collider.mmd",
@@ -96,9 +99,9 @@ subprocess.call(callp)
 
 print("- -- --- -- - Generating web site")
 for x in src:
-    subprocess.call(["pandoc", "--template=html.pandoc", "-f", "markdown-smart", "--metadata", 'title="SoLoud ' + datestring + ' ' + x[:len(x)-4] + '"', "-B", "htmlpre.txt", "-A", "htmlpost.txt", "--default-image-extension=png", x, "-o", datestring + "/web/" + x[:len(x)-3]+"html.bak"])
+    subprocess.call(["pandoc", "--template=html.pandoc", "-f", "markdown-smart", "-t", "html5", "--metadata", 'title="SoLoud ' + datestring + ' ' + x[:len(x)-4] + '"', "-B", "htmlpre.txt", "-A", "htmlpost.txt", "--default-image-extension=png", x, "-o", "temp/" + x[:len(x)-3]+"orig.html"])
     with open(datestring + "/web/" + x[:len(x)-3]+"html", "w") as file_out:
-        with open(datestring + "/web/" + x[:len(x)-3]+"html.bak", "r") as file_in:
+        with open("temp/" + x[:len(x)-3]+"orig.html", "r") as file_in:
             for line in file_in:
                 file_out.write(line.replace('code>', 'code>\n').replace('::','::<wbr>').replace('\xc2','').replace('\xa0',''))
     if x == "intro.mmd":
@@ -115,22 +118,22 @@ for x in src:
 subprocess.call(callp)
 
 print("- -- --- -- - Converting epub -> mobi (kindlegen_output.txt)")
-with open('kindlegen_output.txt', 'w') as outfile:
+with open('temp/kindlegen_output.txt', 'w') as outfile:
     subprocess.call(["kindlegen", datestring + "/soloud_" + datestring + ".epub", "-c2"], stdout=outfile)
 
 print("- -- --- -- - Generating LaTex")
 
 for x in src:
     if x not in website_only:
-        subprocess.call(["pandoc", "-t", "latex", "--listings", "--default-image-extension=pdf", "--top-level-division=chapter", x, "-o", "temp/" + x[:len(x)-3]+"tex.orig"])
+        subprocess.call(["pandoc", "-t", "latex", "-f", "markdown-smart", "--listings", "--default-image-extension=pdf", "--top-level-division=chapter", x, "-o", "temp/" + x[:len(x)-3]+"orig.tex"])
         with open("temp/" + x[:len(x)-3]+"tex", "w") as file_out:
-            with open("temp/" + x[:len(x)-3]+"tex.orig", "r") as file_in:
+            with open("temp/" + x[:len(x)-3]+"orig.tex", "r") as file_in:
                 for line in file_in:
                     file_out.write(line.replace('\\begin{longtable}[]{@{}ll@{}}', '\\begin{tabulary}{\\textwidth}{lJ}').replace('\\begin{longtable}[]{@{}lll@{}}', '\\begin{tabulary}{\\textwidth}{lJJ}').replace('\\begin{longtable}[]{@{}llll@{}}', '\\begin{tabulary}{\\textwidth}{lJJJ}').replace('\\endhead','').replace('\\end{longtable}','\\end{tabulary}'))
 
 print("- -- --- -- - Generating pdf (xelatex_output.txt)")
 
-with open('xelatex_output.txt', 'w') as outfile:
+with open('temp/xelatex_output.txt', 'w') as outfile:
     subprocess.call(["xelatex", "SoLoud.tex"], stdout=outfile)
     print("- -- --- -- - Generating pdf pass 2..")
     subprocess.call(["xelatex", "SoLoud.tex"], stdout=outfile)
@@ -148,4 +151,10 @@ for file in glob.glob("temp/*"):
    os.remove(file)
 os.rmdir("temp")
 
+print("- -- --- -- - Copying release docs to /doc")
+shutil.copy(datestring + "/soloud_" + datestring + ".epub", "../doc/soloud.epub")
+shutil.copy(datestring + "/soloud_" + datestring + ".mobi", "../doc/soloud.mobi")
+shutil.copy(datestring + "/soloud_" + datestring + ".html", "../doc/soloud.html")
+shutil.copy(datestring + "/soloud_" + datestring + ".pdf", "../doc/soloud.pdf")
+
 print("- -- --- -- - Done - " + datestring)

+ 31 - 0
soloud.mod/soloud/docsrc/mixbus.mmd

@@ -28,6 +28,10 @@ To play a stream through the mixing bus, use the bus play() command.
     int fxhandle = gBus.play(gSoundEffect); // Play sound effect through bus
     gSoloud.setVolume(fxhandle, 0.5f); // set sound effect volume
 
+When chaining busses care should be taken, as resampling will offset the output
+by a number of samples. Point sampling by 0, linear by 1, and higher resamplers
+with higher number of samples.
+
 ### Bus.setChannels()
 
 Set the number of channels this bus should handle. Defaults to 2 (stereo).
@@ -152,6 +156,33 @@ inaudible.
 Set the default volume of the bus.
 
     gMusicBus.setVolume(11);
+
+### Bus.annexSound()
+
+Move live audio stream under this bus. This can be useful if you have
+some heavy filtering under one bus and want to move playing sounds in
+and out of the bus.
+
+    gTunnelBus.annexSound(sfxBus);
+    
+
+### Bus.getActiveVoiceCount()
+
+Returns the number of concurrent sounds that are playing through this bus
+at the moment.
+
+    if (sfxbus.getActiveVoiceCount() == 0) enjoy_the_silence();
+
+
+### Bus.getResampler(), Bus.setResampler()
+
+Set or get the resampler for this bus. The default is linear interpolator.
+
+Setting the resampler does not change the resampler other busses or the main mixer uses.
+
+    // Use point-sample resampler for the music
+    gMusicBus.setResampler(SoLoud::Soloud::RESAMPLER_POINT);
+
     
 ### Inherited 3d audio interfaces
 

+ 16 - 4
soloud.mod/soloud/docsrc/monotone.mmd

@@ -11,8 +11,8 @@ available at the time of this writing). You can pick the number of
 "hardware" voices used - typically the songs are composed for a single
 voice (PC beeper).
 
-The waveform used is square wave. Other waveforms can be used by 
-modifying the soloud_monotone.cpp.
+The default waveform used is square wave, but other waveforms
+are also supported.
 
 ### Monotone.clear()
 
@@ -67,8 +67,20 @@ MONOTONE file.
 Most songs are composed for a single hardware channel. SoLoud supports
 up to 12 hardware channels (more can be easily added by editing soloud_monotone.cpp)
 
-For waveform, along with the default SQUARE, the SAW, SIN and SAWSIN waveforms are 
-supported. The SAWSIN is simply saw(t)*sin(t).
+The supported waveforms include:
+
+| Waveform | Description |
+|:---------|:-----------------------|
+|WAVE_SQUARE|Raw, harsh square wave|
+|WAVE_SAW|Raw, harsh saw wave|
+|WAVE_SIN|Sine wave|
+|WAVE_TRIANGLE|Triangle wave|
+|WAVE_BOUNCE|Bounce, i.e, abs(sin())|
+|WAVE_JAWS|Quater sine wave, rest of period quiet|
+|WAVE_HUMPS|Half sine wave, rest of period quiet|
+|WAVE_FSQUARE|"Fourier" square wave; less noisy|
+|WAVE_FSAW|"Fourier" saw wave; less noisy|
+
 
 
 ### Monotone.setLooping()

+ 1 - 1
soloud.mod/soloud/docsrc/newsoundsources.mmd

@@ -99,7 +99,7 @@ function.
 
 Optionally, you can implement a seek function. The base implementation
 will simply request (and discard) samples from the sound source until
-the desired position has been reached; for many sound sources, a smarter
+the desired position has been reached; for many sound sources, some smarter
 way exists.
 
 ### AudioSourceInstance.rewind()

+ 88 - 0
soloud.mod/soloud/docsrc/noise.mmd

@@ -0,0 +1,88 @@
+## SoLoud::Noise
+
+
+The SoLoud::Noise audio source generates... noise. This can be useful in some situations, such as when you want to drown out everything into white noise,
+or when you want to have some other kind of noise in the background. Noise can also be filtered to produce different kinds of sounds, such as wind hissing
+or water pouring.
+
+### Noise.setType()
+
+
+The type of the desired noise can be set before playing.
+
+|Parameter|Effect|
+|:--------|:---------------------|
+|WHITE|White noise. 100% weight on the first octave.|
+|PINK|Pink noise. Equal weight on all octaves.|
+|BROWNISH|Brown-ish noise, increasing weight on deeper octaves.|
+|BLUEISH|Blue-ish noise, decreasing weight on deeper octaves.|
+
+White noise is harsh, new random value on every sample kind of noise. This is the most useful one as base for filtering. The other kinds of noises may be useful
+as they are for background noise at low volume.
+    
+    gNoise.setType(SoLoud::Noise::PINK); // Some pink noise, please
+
+### Noise.setOctaveScale()
+
+
+Instead of selecting the noise type, you can also define the octave weights manually. The noise genrator has 10 octaves; the first one generates new value for
+every sample, the second for every second sample, the third for every 4 samples, 8, 16, 32, and so on. 
+
+    gNoise.setOctaveScale(0,0,0,0,0,1,0,0,0,0); // Very particular noise
+
+The weight values do not need to sum up to 1; the total will be used as a divisor. As such, the total must not be zero.
+
+### Noise.setLooping(), Noise.setLoopPoint(), Noise.getLoopPoint()
+
+
+Adjusting the looping of a noise sound does not have any effect.
+
+\pagebreak
+### Noise.setFilter()
+
+
+As with any other audio source, you can attach filters to 
+monotone audio sources.
+
+    gMusic.setFilter(0, &gLofi);
+
+
+### Noise.stop()
+
+
+You can stop all instances of a noise sound source with
+stop(). This is equivalent of calling soloud.stopAudioSource()
+with the sound source.
+
+    gMusic.stop();
+
+### Noise.setInaudibleBehavior()
+
+Set the inaudible behavior of the sound. By default, if a sound is
+inaudible, it's paused, and will resume when it becomes audible again.
+With this function you can tell SoLoud to either kill the sound if
+it becomes inaudible, or to keep ticking the sound even if it's 
+inaudible.
+
+	// Keep on talking even if I'm not around
+	gSpeech.setInaudibleBehavior(true, false);
+
+### Noise.setVolume()
+
+Set the default volume of the instances created from this audio source.
+
+    gTinyVoice.setVolume(0.1);
+       
+
+### Inherited 3d audio interfaces
+
+Like all other audio sources, monotone inherits the 3d audio interfaces. Please refer to the 3d audio chapter for details on:
+
+- Noise.set3dMinMaxDistance()
+- Noise.set3dAttenuation()
+- Noise.set3dDopplerFactor()
+- Noise.set3dProcessing()
+- Noise.set3dListenerRelative()
+- Noise.set3dDistanceDelay()
+- Noise.set3dCollider()
+- Noise.set3dAttenuator()

+ 5 - 1
soloud.mod/soloud/docsrc/premake.mmd

@@ -29,10 +29,14 @@ Option                  Description
 soloud-devel            Shorthand for options used while developing SoLoud
 with-common-backends    Includes common backends in build
 with-coreaudio          Include OS X CoreAudio backend in build
+with-jack               Include JACK backend in build
+with-jack-only          Only include JACK backend in build
+with-miniaudio          Include MiniAudio in build
+with-miniaudio-only     Only include MiniAudio in build
 with-native-only        Only native backends (winmm/oss) in build (default)
+with-nosound            Include nosound backend in build
 with-openal             Include OpenAL backend in build
 with-portaudio          Include PortAudio backend in build
-with-portmidi           Use PortMidi to drive midi keyboard in the piano demo
 with-sdl                Include SDL backend in build
 with-sdl-only           Only include sdl in build
 with-sdl2               Include SDL2 backend in build

+ 17 - 13
soloud.mod/soloud/docsrc/quickstart.mmd

@@ -13,26 +13,28 @@ on the <http://soloud-audio.com/downloads.html> page.
 #### Add SoLoud to your project
 
 
-There's a few ways to include SoLoud to your project. Probably the
-easiest is to use GENie / premake4 to create the build files, and build a 
-static library for your compiler / environment.
+There's a few ways to include SoLoud to your project. 
 
-Note that the Windows DLL only exports the  "C" API, which may not 
-be what you want.
+You can, for example, include all the SoLoud source files to your project,
+define one or more of the backend defines (see table below), and you're good
+to go.
+
+A bit more structured way is to use GENie / premake4 to create the build
+files, and build a static library for your compiler / environment.
 
-You can go the lazy way and just add all of the sources to your project,
-or you can copy the things you need to a single directory and include
-those. 
+Note that the Windows DLL only exports the  "C" API, which may not 
+be what you want - it's primarily meant for foreign interface use.
 
-You'll need the core files, at least one backend, and at least one 
-audio source. For example, for wav file playing, you'll need the files from
+If you're including the sources directly to your project, You'll need the 
+core files, at least one backend, and at least one audio source. For 
+example, for wav file playing, you'll need the files from
 audiosource/wav. 
 
-If you go this route, you'll need to enable one or more of the back-ends 
-via preprocessor defines. The current list is:
+The current list of back-ends is:
 
 Preprocessor macro  Description
 ----                ------------
+WITH_MINIAUDIO      MiniAudio cross-platform audio backend
 WITH_SDL            SDL or SDL2 via runtime dyndll linking
 WITH_SDL1           SDL1 via runtime dyndll linking
 WITH_SDL2           SDL2 via runtime dyndll linking
@@ -49,7 +51,9 @@ WITH_ALSA           Linux ALSA
 WITH_OPENSLES       OpenSL ES
 WITH_COREAUDIO		OSX CoreAudio
 WITH_VITA_HOMEBREW	Sony Vita homebrew backend
-WITH_NULL           No audio device
+WITH_JACK           Linux JACK
+WITH_NOSOUND        Nosound audio device
+WITH_NULL           Special use "no backend"
 
 The backend with no audio device may seem odd, but that can be used to
 call SoLoud's mix function manually, which can be useful in some cases

+ 35 - 0
soloud.mod/soloud/docsrc/robotizefilter.mmd

@@ -0,0 +1,35 @@
+## SoLoud::RobotizeFilter
+
+The robotize filter modulates the signal with a waveform. By default this is a square wave
+adjusted to have half of its period at zero, resulting at a choppy sound. Various waveforms
+can be selected for different effects.
+
+### RobotizeFilter.setParams()
+
+Set the parameters for the filter. Does not affect "live" sounds.
+
+    robo.setParams(30, 0);
+    
+Supported waveforms include:
+
+| Waveform | Description |
+|:---------|:-----------------------|
+|WAVE_SQUARE|Raw, harsh square wave|
+|WAVE_SAW|Raw, harsh saw wave|
+|WAVE_SIN|Sine wave|
+|WAVE_TRIANGLE|Triangle wave|
+|WAVE_BOUNCE|Bounce, i.e, abs(sin())|
+|WAVE_JAWS|Quater sine wave, rest of period quiet|
+|WAVE_HUMPS|Half sine wave, rest of period quiet|
+|WAVE_FSQUARE|"Fourier" square wave; less noisy|
+|WAVE_FSAW|"Fourier" saw wave; less noisy|
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- RobotizeFilter.getParamCount()
+- RobotizeFilter.getParamName()
+- RobotizeFilter.getParamType()
+- RobotizeFilter.getParamMax()
+- RobotizeFilter.getParamMin()

+ 0 - 17
soloud.mod/soloud/docsrc/sfxr.mmd

@@ -119,23 +119,6 @@ queried with these functions.
 	...
 	snd.setLoopPoint(0); // loop from start
 
-### Prg.srand()
-
-
-Initializes the pseudo-random number generator to a seed number.
-
-   rnd.srand(7);
-   
-### Prg.rand()
-
-
-Returns the next 32bit pseudo-random number.
-
-   if (rnd.rand() & 1)
-      printf("Heads");
-   else
-      printf("Tails");
-      
 ### Inherited 3d audio interfaces
 
 Like all other audio sources, Sfxr inherits the 3d audio interfaces. Please refer to the 3d audio chapter for details on:

+ 1 - 1
soloud.mod/soloud/docsrc/wav.mmd

@@ -1,7 +1,7 @@
 ## SoLoud::Wav
 
 The SoLoud::Wav class represents a wave sound effect. The source files
-may be in various RIFF WAV file formats FLAC, MP3 or Ogg Vorbis
+may be in various RIFF WAV file formats, FLAC, MP3 or Ogg Vorbis
 files.
 
 The sounds are loaded and converted to float samples, which means that

+ 10 - 0
soloud.mod/soloud/docsrc/waveshaperfilter.mmd

@@ -26,3 +26,13 @@ can be set, faded or oscillated:
       1,            // What to adjust
       0,            // Target value
       3);           // Time in seconds
+
+### Live Parameter Access
+
+All filters inherit the live parameter access functions.
+
+- WaveShaperFilter.getParamCount()
+- WaveShaperFilter.getParamName()
+- WaveShaperFilter.getParamType()
+- WaveShaperFilter.getParamMax()
+- WaveShaperFilter.getParamMin()

+ 91 - 50
soloud.mod/soloud/include/soloud.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2018 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -33,8 +33,12 @@ freely, subject to the following restrictions:
 #else
 #ifdef _MSC_VER
 #include <stdio.h> // for sprintf in asserts
+#ifndef VC_EXTRALEAN
 #define VC_EXTRALEAN
+#endif
+#ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
+#endif
 #include <windows.h> // only needed for OutputDebugStringA, should be solved somehow.
 #define SOLOUD_ASSERT(x) if (!(x)) { char temp[200]; sprintf(temp, "%s(%d): assert(%s) failed.\n", __FILE__, __LINE__, #x); OutputDebugStringA(temp); __debugbreak(); }
 #else
@@ -69,7 +73,7 @@ freely, subject to the following restrictions:
 #endif
 #endif
 
-#define SOLOUD_VERSION 201811
+#define SOLOUD_VERSION 202002
 
 /////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////
@@ -84,12 +88,12 @@ freely, subject to the following restrictions:
 // Maximum number of concurrent voices (hard limit is 4095)
 #define VOICE_COUNT 1024
 
-// Use linear resampler
-#define RESAMPLER_LINEAR
-
 // 1)mono, 2)stereo 4)quad 6)5.1 8)7.1
 #define MAX_CHANNELS 8
 
+// Default resampler for both main and bus mixers
+#define SOLOUD_DEFAULT_RESAMPLER SoLoud::Soloud::RESAMPLER_LINEAR
+
 //
 /////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////
@@ -176,11 +180,14 @@ namespace SoLoud
 			XAUDIO2,
 			WASAPI,
 			ALSA,
+			JACK,
 			OSS,
 			OPENAL,
 			COREAUDIO,
 			OPENSLES,
 			VITA_HOMEBREW,
+			MINIAUDIO,
+			NOSOUND,
 			NULLDRIVER,
 			BACKEND_MAX,
 		};
@@ -190,7 +197,28 @@ namespace SoLoud
 			// Use round-off clipper
 			CLIP_ROUNDOFF = 1,
 			ENABLE_VISUALIZATION = 2,
-			LEFT_HANDED_3D = 4
+			LEFT_HANDED_3D = 4,
+			NO_FPU_REGISTER_CHANGE = 8
+		};
+
+		enum WAVEFORM
+		{
+			WAVE_SQUARE = 0,
+			WAVE_SAW,
+			WAVE_SIN,
+			WAVE_TRIANGLE,
+			WAVE_BOUNCE,
+			WAVE_JAWS,
+			WAVE_HUMPS,
+			WAVE_FSQUARE,
+			WAVE_FSAW
+		};
+
+		enum RESAMPLER
+		{
+			RESAMPLER_POINT,
+			RESAMPLER_LINEAR,
+			RESAMPLER_CATMULLROM
 		};
 
 		// Initialize SoLoud. Must be called before SoLoud can be used.
@@ -278,12 +306,16 @@ namespace SoLoud
 		float getRelativePlaySpeed(handle aVoiceHandle);
 		// Get current post-clip scaler value.
 		float getPostClipScaler() const;
+		// Get the current main resampler
+		unsigned int getMainResampler() const;
 		// Get current global volume
 		float getGlobalVolume() const;
 		// Get current maximum active voice setting
 		unsigned int getMaxActiveVoiceCount() const;
 		// Query whether a voice is set to loop.
 		bool getLooping(handle aVoiceHandle);
+		// Query whether a voice is set to auto-stop when it ends.
+		bool getAutoStop(handle aVoiceHandle);
 		// Get voice loop point value
 		time getLoopPoint(handle aVoiceHandle);
 
@@ -291,6 +323,8 @@ namespace SoLoud
 		void setLoopPoint(handle aVoiceHandle, time aLoopPoint);
 		// Set voice's loop state
 		void setLooping(handle aVoiceHandle, bool aLooping);
+		// Set whether sound should auto-stop when it ends
+		void setAutoStop(handle aVoiceHandle, bool aAutoStop);
 		// Set current maximum active voice setting
 		result setMaxActiveVoiceCount(unsigned int aVoiceCount);
 		// Set behavior for inaudible sounds
@@ -299,6 +333,8 @@ namespace SoLoud
 		void setGlobalVolume(float aVolume);
 		// Set the post clip scaler value
 		void setPostClipScaler(float aScaler);
+		// Set the main resampler
+		void setMainResampler(unsigned int aResampler);
 		// Set the pause state
 		void setPause(handle aVoiceHandle, bool aPause);
 		// Pause all voices
@@ -312,7 +348,9 @@ namespace SoLoud
 		// Set panning value; -1 is left, 0 is center, 1 is right
 		void setPan(handle aVoiceHandle, float aPan);
 		// Set absolute left/right volumes
-		void setPanAbsolute(handle aVoiceHandle, float aLVolume, float aRVolume, float aLBVolume = 0, float aRBVolume = 0, float aCVolume = 0, float aSVolume = 0);
+		void setPanAbsolute(handle aVoiceHandle, float aLVolume, float aRVolume);
+		// Set channel volume (volume for a specific speaker)
+		void setChannelVolume(handle aVoiceHandle, unsigned int aChannel, float aVolume);
 		// Set overall volume
 		void setVolume(handle aVoiceHandle, float aVolume);
 		// Set delay, in samples, before starting to play samples. Calling this on a live sound will cause glitches.
@@ -411,17 +449,51 @@ namespace SoLoud
 		void mixSigned16(short *aBuffer, unsigned int aSamples);
 	public:
 		// Mix N samples * M channels. Called by other mix_ functions.
-		void mix_internal(unsigned int aSamples);
+		void mix_internal(unsigned int aSamples, unsigned int aStride);
 
 		// Handle rest of initialization (called from backend)
-		void postinit(unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aFlags, unsigned int aChannels);
+		void postinit_internal(unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aFlags, unsigned int aChannels);
 
 		// Update list of active voices
-		void calcActiveVoices();
+		void calcActiveVoices_internal();
 		// Map resample buffers to active voices
-		void mapResampleBuffers();
+		void mapResampleBuffers_internal();
 		// Perform mixing for a specific bus
-		void mixBus(float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize, float *aScratch, unsigned int aBus, float aSamplerate, unsigned int aChannels);
+		void mixBus_internal(float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize, float *aScratch, unsigned int aBus, float aSamplerate, unsigned int aChannels, unsigned int aResampler);
+		// Find a free voice, stopping the oldest if no free voice is found.
+		int findFreeVoice_internal();
+		// Converts handle to voice, if the handle is valid. Returns -1 if not.
+		int getVoiceFromHandle_internal(handle aVoiceHandle) const;
+		// Converts voice + playindex into handle
+		handle getHandleFromVoice_internal(unsigned int aVoice) const;
+		// Stop voice (not handle).
+		void stopVoice_internal(unsigned int aVoice);
+		// Set voice (not handle) pan.
+		void setVoicePan_internal(unsigned int aVoice, float aPan);
+		// Set voice (not handle) relative play speed.
+		result setVoiceRelativePlaySpeed_internal(unsigned int aVoice, float aSpeed);
+		// Set voice (not handle) volume.
+		void setVoiceVolume_internal(unsigned int aVoice, float aVolume);
+		// Set voice (not handle) pause state.
+		void setVoicePause_internal(unsigned int aVoice, int aPause);
+		// Update overall volume from set and 3d volumes
+		void updateVoiceVolume_internal(unsigned int aVoice);
+		// Update overall relative play speed from set and 3d speeds
+		void updateVoiceRelativePlaySpeed_internal(unsigned int aVoice);
+		// Perform 3d audio calculation for array of voices
+		void update3dVoices_internal(unsigned int *aVoiceList, unsigned int aVoiceCount);
+		// Clip the samples in the buffer
+		void clip_internal(AlignedFloatBuffer &aBuffer, AlignedFloatBuffer &aDestBuffer, unsigned int aSamples, float aVolume0, float aVolume1);
+		// Remove all non-active voices from group
+		void trimVoiceGroup_internal(handle aVoiceGroupHandle);
+		// Get pointer to the zero-terminated array of voice handles in a voice group
+		handle * voiceGroupHandleToArray_internal(handle aVoiceGroupHandle) const;
+
+		// Lock audio thread mutex.
+		void lockAudioMutex_internal();
+		// Unlock audio thread mutex.
+		void unlockAudioMutex_internal();
+
 		// Max. number of active voices. Busses and tickable inaudibles also count against this.
 		unsigned int mMaxActiveVoices;
 		// Highest voice in use so far
@@ -430,16 +502,18 @@ namespace SoLoud
 		AlignedFloatBuffer mScratch;
 		// Current size of the scratch, in samples.
 		unsigned int mScratchSize;
-		// Amount of scratch needed.
-		unsigned int mScratchNeeded;
 		// Output scratch buffer, used in mix_().
 		AlignedFloatBuffer mOutputScratch;
-		// Resampler buffers, two per active voice.
-		AlignedFloatBuffer *mResampleData;
+		// Pointers to resampler buffers, two per active voice.
+		float **mResampleData;
+		// Actual allocated memory for resampler buffers
+		AlignedFloatBuffer mResampleDataBuffer;
 		// Owners of the resample data
 		AudioSourceInstance **mResampleDataOwner;
 		// Audio voices.
 		AudioSourceInstance *mVoice[VOICE_COUNT];
+		// Resampler for the main bus
+		unsigned int mResampler;
 		// Output sample rate (not float)
 		unsigned int mSamplerate;
 		// Output channel count
@@ -470,30 +544,7 @@ namespace SoLoud
 		Filter *mFilter[FILTERS_PER_STREAM];
 		// Global filter instance
 		FilterInstance *mFilterInstance[FILTERS_PER_STREAM];
-		// Find a free voice, stopping the oldest if no free voice is found.
-		int findFreeVoice();
-		// Converts handle to voice, if the handle is valid. Returns -1 if not.
-		int getVoiceFromHandle(handle aVoiceHandle) const;
-		// Converts voice + playindex into handle
-		handle getHandleFromVoice(unsigned int aVoice) const;
-		// Stop voice (not handle).
-		void stopVoice(unsigned int aVoice);
-		// Set voice (not handle) pan.
-		void setVoicePan(unsigned int aVoice, float aPan);
-		// Set voice (not handle) relative play speed.
-		result setVoiceRelativePlaySpeed(unsigned int aVoice, float aSpeed);
-		// Set voice (not handle) volume.
-		void setVoiceVolume(unsigned int aVoice, float aVolume);
-		// Set voice (not handle) pause state.
-		void setVoicePause(unsigned int aVoice, int aPause);
-		// Update overall volume from set and 3d volumes
-		void updateVoiceVolume(unsigned int aVoice);
-		// Update overall relative play speed from set and 3d speeds
-		void updateVoiceRelativePlaySpeed(unsigned int aVoice);
-		// Perform 3d audio calculation for array of voices
-		void update3dVoices(unsigned int *aVoiceList, unsigned int aVoiceCount);
-		// Clip the samples in the buffer
-		void clip(AlignedFloatBuffer &aBuffer, AlignedFloatBuffer &aDestBuffer, unsigned int aSamples, float aVolume0, float aVolume1);
+
 		// Approximate volume for channels.
 		float mVisualizationChannelVolume[MAX_CHANNELS];
 		// Mono-mixed wave data for visualization and for visualization FFT input
@@ -530,16 +581,6 @@ namespace SoLoud
 		unsigned int mActiveVoiceCount;
 		// Active voices list needs to be recalculated
 		bool mActiveVoiceDirty;
-
-		// Remove all non-active voices from group
-		void trimVoiceGroup(handle aVoiceGroupHandle);
-		// Get pointer to the zero-terminated array of voice handles in a voice group
-		handle * voiceGroupHandleToArray(handle aVoiceGroupHandle) const;
-
-		// Lock audio thread mutex.
-		void lockAudioMutex();
-		// Unlock audio thread mutex.
-		void unlockAudioMutex();
 	};
 };
 

+ 10 - 4
soloud.mod/soloud/include/soloud_audiosource.h

@@ -119,7 +119,9 @@ namespace SoLoud
 			// If inaudible, should be killed (default = don't kill kill)
 			INAUDIBLE_KILL = 64,
 			// If inaudible, should still be ticked (default = pause)
-			INAUDIBLE_TICK = 128
+			INAUDIBLE_TICK = 128,
+			// Don't auto-stop sound
+			DISABLE_AUTOSTOP = 256
 		};
 		// Ctor
 		AudioSourceInstance();
@@ -175,8 +177,8 @@ namespace SoLoud
 		FilterInstance *mFilter[FILTERS_PER_STREAM];
 		// Initialize instance. Mostly internal use.
 		void init(AudioSource &aSource, int aPlayIndex);
-		// Buffers for the resampler
-		AlignedFloatBuffer *mResampleData[2];
+		// Pointers to buffers for the resampler
+		float *mResampleData[2];
 		// Sub-sample playhead; 16.16 fixed point
 		unsigned int mSrcOffset;
 		// Samples left over from earlier pass
@@ -221,7 +223,9 @@ namespace SoLoud
 			// If inaudible, should be killed (default)
 			INAUDIBLE_KILL = 64,
 			// If inaudible, should still be ticked (default = pause)
-			INAUDIBLE_TICK = 128
+			INAUDIBLE_TICK = 128,
+			// Disable auto-stop
+			DISABLE_AUTOSTOP = 256
 		};
 		enum ATTENUATION_MODELS
 		{
@@ -276,6 +280,8 @@ namespace SoLoud
 		void setLooping(bool aLoop);
 		// Set whether only one instance of this sound should ever be playing at the same time
 		void setSingleInstance(bool aSingleInstance);
+		// Set whether audio should auto-stop when it ends or not
+		void setAutoStop(bool aAutoStop);
 		
 		// Set the minimum and maximum distances for 3d audio source (closer to min distance = max vol)
 		void set3dMinMaxDistance(float aMinDistance, float aMaxDistance);

+ 5 - 0
soloud.mod/soloud/include/soloud_bassboostfilter.h

@@ -53,6 +53,11 @@ namespace SoLoud
 			WET = 0,
 			BOOST = 1
 		};
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
 		float mBoost;
 		result setParams(float aBoost);
 		virtual FilterInstance *createInstance();

+ 18 - 15
soloud.mod/soloud/include/soloud_biquadresonantfilter.h

@@ -41,16 +41,15 @@ namespace SoLoud
 		enum FILTERATTRIBUTE
 		{
 			WET = 0,
-			SAMPLERATE = 1,
-			FREQUENCY = 2,
-			RESONANCE = 3
+			TYPE,
+			FREQUENCY,
+			RESONANCE
 		};
 
-		int mActive;
-		BQRStateData mState[2];
+		BQRStateData mState[8];
 		float mA0, mA1, mA2, mB1, mB2;
 		int mDirty;
-		int mFilterType;
+		float mSamplerate;
 
 		BiquadResonantFilter *mParent;
 		void calcBQRParams();
@@ -65,25 +64,29 @@ namespace SoLoud
 	public:
 		enum FILTERTYPE
 		{
-			NONE = 0,
-			LOWPASS = 1,
-			HIGHPASS = 2,
-			BANDPASS = 3
+			LOWPASS = 0,
+			HIGHPASS = 1,
+			BANDPASS = 2
 		};
 		enum FILTERATTRIBUTE
 		{
 			WET = 0,
-			SAMPLERATE = 1,
-			FREQUENCY = 2,
-			RESONANCE = 3
+			TYPE,
+			FREQUENCY,
+			RESONANCE
 		};
 		int mFilterType;
-		float mSampleRate;
 		float mFrequency;
 		float mResonance;
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
+
 		virtual BiquadResonantFilterInstance *createInstance();
 		BiquadResonantFilter();
-		result setParams(int aType, float aSampleRate, float aFrequency, float aResonance);
+		result setParams(int aType, float aFrequency, float aResonance);
 		virtual ~BiquadResonantFilter();
 	};
 }

+ 12 - 1
soloud.mod/soloud/include/soloud_bus.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2014 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -67,6 +67,8 @@ namespace SoLoud
 		result setChannels(unsigned int aChannels);
 		// Enable or disable visualization data gathering
 		void setVisualizationEnable(bool aEnable);
+		// Move a live sound to this bus
+		void annexSound(handle aVoiceHandle);
 		
 		// Calculate and get 256 floats of FFT data for visualization. Visualization has to be enabled before use.
 		float *calcFFT();
@@ -76,9 +78,18 @@ namespace SoLoud
 
 		// Get approximate volume for output channel for visualization. Visualization has to be enabled before use.
 		float getApproximateVolume(unsigned int aChannel);
+
+		// Get number of immediate child voices to this bus
+		unsigned int getActiveVoiceCount();
+
+		// Get current the resampler for this bus
+		unsigned int getResampler();
+		// Set the resampler for this bus
+		void setResampler(unsigned int aResampler);
 	public:
 		BusInstance *mInstance;
 		unsigned int mChannelHandle;
+		unsigned int mResampler;
 		// FFT output data
 		float mFFTData[256];
 		// Snapshot of wave data for visualization

+ 149 - 42
soloud.mod/soloud/include/soloud_c.h

@@ -5,7 +5,7 @@
 
 /*
 SoLoud audio engine
-Copyright (c) 2013-2016 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -27,7 +27,7 @@ freely, subject to the following restrictions:
    distribution.
 */
 
-/* SoLoud C-Api Code Generator (c)2013-2018 Jari Komppa http://iki.fi/sol/ */
+/* SoLoud C-Api Code Generator (c)2013-2020 Jari Komppa http://iki.fi/sol/ */
 
 #ifndef SOLOUD_C_H_INCLUDED
 #define SOLOUD_C_H_INCLUDED
@@ -46,37 +46,63 @@ enum SOLOUD_ENUMS
 	SOLOUD_XAUDIO2 = 5,
 	SOLOUD_WASAPI = 6,
 	SOLOUD_ALSA = 7,
-	SOLOUD_OSS = 8,
-	SOLOUD_OPENAL = 9,
-	SOLOUD_COREAUDIO = 10,
-	SOLOUD_OPENSLES = 11,
-	SOLOUD_VITA_HOMEBREW = 12,
-	SOLOUD_NULLDRIVER = 13,
-	SOLOUD_BACKEND_MAX = 14,
+	SOLOUD_JACK = 8,
+	SOLOUD_OSS = 9,
+	SOLOUD_OPENAL = 10,
+	SOLOUD_COREAUDIO = 11,
+	SOLOUD_OPENSLES = 12,
+	SOLOUD_VITA_HOMEBREW = 13,
+	SOLOUD_MINIAUDIO = 14,
+	SOLOUD_NOSOUND = 15,
+	SOLOUD_NULLDRIVER = 16,
+	SOLOUD_BACKEND_MAX = 17,
 	SOLOUD_CLIP_ROUNDOFF = 1,
 	SOLOUD_ENABLE_VISUALIZATION = 2,
 	SOLOUD_LEFT_HANDED_3D = 4,
+	SOLOUD_NO_FPU_REGISTER_CHANGE = 8,
+	SOLOUD_WAVE_SQUARE = 0,
+	SOLOUD_WAVE_SAW = 1,
+	SOLOUD_WAVE_SIN = 2,
+	SOLOUD_WAVE_TRIANGLE = 3,
+	SOLOUD_WAVE_BOUNCE = 4,
+	SOLOUD_WAVE_JAWS = 5,
+	SOLOUD_WAVE_HUMPS = 6,
+	SOLOUD_WAVE_FSQUARE = 7,
+	SOLOUD_WAVE_FSAW = 8,
+	SOLOUD_RESAMPLER_POINT = 0,
+	SOLOUD_RESAMPLER_LINEAR = 1,
+	SOLOUD_RESAMPLER_CATMULLROM = 2,
 	BASSBOOSTFILTER_WET = 0,
 	BASSBOOSTFILTER_BOOST = 1,
-	BIQUADRESONANTFILTER_NONE = 0,
-	BIQUADRESONANTFILTER_LOWPASS = 1,
-	BIQUADRESONANTFILTER_HIGHPASS = 2,
-	BIQUADRESONANTFILTER_BANDPASS = 3,
+	BIQUADRESONANTFILTER_LOWPASS = 0,
+	BIQUADRESONANTFILTER_HIGHPASS = 1,
+	BIQUADRESONANTFILTER_BANDPASS = 2,
 	BIQUADRESONANTFILTER_WET = 0,
-	BIQUADRESONANTFILTER_SAMPLERATE = 1,
+	BIQUADRESONANTFILTER_TYPE = 1,
 	BIQUADRESONANTFILTER_FREQUENCY = 2,
 	BIQUADRESONANTFILTER_RESONANCE = 3,
+	ECHOFILTER_WET = 0,
+	ECHOFILTER_DELAY = 1,
+	ECHOFILTER_DECAY = 2,
+	ECHOFILTER_FILTER = 3,
 	FLANGERFILTER_WET = 0,
 	FLANGERFILTER_DELAY = 1,
 	FLANGERFILTER_FREQ = 2,
+	FREEVERBFILTER_WET = 0,
+	FREEVERBFILTER_FREEZE = 1,
+	FREEVERBFILTER_ROOMSIZE = 2,
+	FREEVERBFILTER_DAMP = 3,
+	FREEVERBFILTER_WIDTH = 4,
 	LOFIFILTER_WET = 0,
 	LOFIFILTER_SAMPLERATE = 1,
 	LOFIFILTER_BITDEPTH = 2,
-	MONOTONE_SQUARE = 0,
-	MONOTONE_SAW = 1,
-	MONOTONE_SIN = 2,
-	MONOTONE_SAWSIN = 3,
+	NOISE_WHITE = 0,
+	NOISE_PINK = 1,
+	NOISE_BROWNISH = 2,
+	NOISE_BLUEISH = 3,
 	ROBOTIZEFILTER_WET = 0,
+	ROBOTIZEFILTER_FREQ = 1,
+	ROBOTIZEFILTER_WAVE = 2,
 	SFXR_COIN = 0,
 	SFXR_LASER = 1,
 	SFXR_EXPLOSION = 2,
@@ -97,7 +123,9 @@ enum SOLOUD_ENUMS
 	VIC_ALTO = 1,
 	VIC_SOPRANO = 2,
 	VIC_NOISE = 3,
-	VIC_MAX_REGS = 4
+	VIC_MAX_REGS = 4,
+	WAVESHAPERFILTER_WET = 0,
+	WAVESHAPERFILTER_AMOUNT = 1
 };
 
 // Object handle typedefs
@@ -116,12 +144,13 @@ typedef void * Fader;
 typedef void * FFTFilter;
 typedef void * Filter;
 typedef void * FlangerFilter;
+typedef void * FreeverbFilter;
 typedef void * LofiFilter;
 typedef void * Monotone;
+typedef void * Noise;
 typedef void * Openmpt;
 typedef void * Queue;
 typedef void * RobotizeFilter;
-typedef void * Prg;
 typedef void * Sfxr;
 typedef void * Speech;
 typedef void * TedSid;
@@ -181,6 +210,7 @@ unsigned int Soloud_getVoiceCount(Soloud * aSoloud);
 int Soloud_isValidVoiceHandle(Soloud * aSoloud, unsigned int aVoiceHandle);
 float Soloud_getRelativePlaySpeed(Soloud * aSoloud, unsigned int aVoiceHandle);
 float Soloud_getPostClipScaler(Soloud * aSoloud);
+unsigned int Soloud_getMainResampler(Soloud * aSoloud);
 float Soloud_getGlobalVolume(Soloud * aSoloud);
 unsigned int Soloud_getMaxActiveVoiceCount(Soloud * aSoloud);
 int Soloud_getLooping(Soloud * aSoloud, unsigned int aVoiceHandle);
@@ -191,6 +221,7 @@ int Soloud_setMaxActiveVoiceCount(Soloud * aSoloud, unsigned int aVoiceCount);
 void Soloud_setInaudibleBehavior(Soloud * aSoloud, unsigned int aVoiceHandle, int aMustTick, int aKill);
 void Soloud_setGlobalVolume(Soloud * aSoloud, float aVolume);
 void Soloud_setPostClipScaler(Soloud * aSoloud, float aScaler);
+void Soloud_setMainResampler(Soloud * aSoloud, unsigned int aResampler);
 void Soloud_setPause(Soloud * aSoloud, unsigned int aVoiceHandle, int aPause);
 void Soloud_setPauseAll(Soloud * aSoloud, int aPause);
 int Soloud_setRelativePlaySpeed(Soloud * aSoloud, unsigned int aVoiceHandle, float aSpeed);
@@ -198,7 +229,7 @@ void Soloud_setProtectVoice(Soloud * aSoloud, unsigned int aVoiceHandle, int aPr
 void Soloud_setSamplerate(Soloud * aSoloud, unsigned int aVoiceHandle, float aSamplerate);
 void Soloud_setPan(Soloud * aSoloud, unsigned int aVoiceHandle, float aPan);
 void Soloud_setPanAbsolute(Soloud * aSoloud, unsigned int aVoiceHandle, float aLVolume, float aRVolume);
-void Soloud_setPanAbsoluteEx(Soloud * aSoloud, unsigned int aVoiceHandle, float aLVolume, float aRVolume, float aLBVolume /* = 0 */, float aRBVolume /* = 0 */, float aCVolume /* = 0 */, float aSVolume /* = 0 */);
+void Soloud_setChannelVolume(Soloud * aSoloud, unsigned int aVoiceHandle, unsigned int aChannel, float aVolume);
 void Soloud_setVolume(Soloud * aSoloud, unsigned int aVoiceHandle, float aVolume);
 void Soloud_setDelaySamples(Soloud * aSoloud, unsigned int aVoiceHandle, unsigned int aSamples);
 void Soloud_fadeVolume(Soloud * aSoloud, unsigned int aVoiceHandle, float aTo, double aTime);
@@ -246,6 +277,11 @@ void Soloud_mixSigned16(Soloud * aSoloud, short * aBuffer, unsigned int aSamples
  * BassboostFilter
  */
 void BassboostFilter_destroy(BassboostFilter * aBassboostFilter);
+int BassboostFilter_getParamCount(BassboostFilter * aBassboostFilter);
+const char * BassboostFilter_getParamName(BassboostFilter * aBassboostFilter, unsigned int aParamIndex);
+unsigned int BassboostFilter_getParamType(BassboostFilter * aBassboostFilter, unsigned int aParamIndex);
+float BassboostFilter_getParamMax(BassboostFilter * aBassboostFilter, unsigned int aParamIndex);
+float BassboostFilter_getParamMin(BassboostFilter * aBassboostFilter, unsigned int aParamIndex);
 int BassboostFilter_setParams(BassboostFilter * aBassboostFilter, float aBoost);
 BassboostFilter * BassboostFilter_create();
 
@@ -253,8 +289,13 @@ BassboostFilter * BassboostFilter_create();
  * BiquadResonantFilter
  */
 void BiquadResonantFilter_destroy(BiquadResonantFilter * aBiquadResonantFilter);
+int BiquadResonantFilter_getParamCount(BiquadResonantFilter * aBiquadResonantFilter);
+const char * BiquadResonantFilter_getParamName(BiquadResonantFilter * aBiquadResonantFilter, unsigned int aParamIndex);
+unsigned int BiquadResonantFilter_getParamType(BiquadResonantFilter * aBiquadResonantFilter, unsigned int aParamIndex);
+float BiquadResonantFilter_getParamMax(BiquadResonantFilter * aBiquadResonantFilter, unsigned int aParamIndex);
+float BiquadResonantFilter_getParamMin(BiquadResonantFilter * aBiquadResonantFilter, unsigned int aParamIndex);
 BiquadResonantFilter * BiquadResonantFilter_create();
-int BiquadResonantFilter_setParams(BiquadResonantFilter * aBiquadResonantFilter, int aType, float aSampleRate, float aFrequency, float aResonance);
+int BiquadResonantFilter_setParams(BiquadResonantFilter * aBiquadResonantFilter, int aType, float aFrequency, float aResonance);
 
 /*
  * Bus
@@ -272,9 +313,13 @@ unsigned int Bus_play3dClocked(Bus * aBus, double aSoundTime, AudioSource * aSou
 unsigned int Bus_play3dClockedEx(Bus * aBus, double aSoundTime, AudioSource * aSound, float aPosX, float aPosY, float aPosZ, float aVelX /* = 0.0f */, float aVelY /* = 0.0f */, float aVelZ /* = 0.0f */, float aVolume /* = 1.0f */);
 int Bus_setChannels(Bus * aBus, unsigned int aChannels);
 void Bus_setVisualizationEnable(Bus * aBus, int aEnable);
+void Bus_annexSound(Bus * aBus, unsigned int aVoiceHandle);
 float * Bus_calcFFT(Bus * aBus);
 float * Bus_getWave(Bus * aBus);
 float Bus_getApproximateVolume(Bus * aBus, unsigned int aChannel);
+unsigned int Bus_getActiveVoiceCount(Bus * aBus);
+unsigned int Bus_getResampler(Bus * aBus);
+void Bus_setResampler(Bus * aBus, unsigned int aResampler);
 void Bus_setVolume(Bus * aBus, float aVolume);
 void Bus_setLooping(Bus * aBus, int aLoop);
 void Bus_set3dMinMaxDistance(Bus * aBus, float aMinDistance, float aMaxDistance);
@@ -297,11 +342,21 @@ void DCRemovalFilter_destroy(DCRemovalFilter * aDCRemovalFilter);
 DCRemovalFilter * DCRemovalFilter_create();
 int DCRemovalFilter_setParams(DCRemovalFilter * aDCRemovalFilter);
 int DCRemovalFilter_setParamsEx(DCRemovalFilter * aDCRemovalFilter, float aLength /* = 0.1f */);
+int DCRemovalFilter_getParamCount(DCRemovalFilter * aDCRemovalFilter);
+const char * DCRemovalFilter_getParamName(DCRemovalFilter * aDCRemovalFilter, unsigned int aParamIndex);
+unsigned int DCRemovalFilter_getParamType(DCRemovalFilter * aDCRemovalFilter, unsigned int aParamIndex);
+float DCRemovalFilter_getParamMax(DCRemovalFilter * aDCRemovalFilter, unsigned int aParamIndex);
+float DCRemovalFilter_getParamMin(DCRemovalFilter * aDCRemovalFilter, unsigned int aParamIndex);
 
 /*
  * EchoFilter
  */
 void EchoFilter_destroy(EchoFilter * aEchoFilter);
+int EchoFilter_getParamCount(EchoFilter * aEchoFilter);
+const char * EchoFilter_getParamName(EchoFilter * aEchoFilter, unsigned int aParamIndex);
+unsigned int EchoFilter_getParamType(EchoFilter * aEchoFilter, unsigned int aParamIndex);
+float EchoFilter_getParamMax(EchoFilter * aEchoFilter, unsigned int aParamIndex);
+float EchoFilter_getParamMin(EchoFilter * aEchoFilter, unsigned int aParamIndex);
 EchoFilter * EchoFilter_create();
 int EchoFilter_setParams(EchoFilter * aEchoFilter, float aDelay);
 int EchoFilter_setParamsEx(EchoFilter * aEchoFilter, float aDelay, float aDecay /* = 0.7f */, float aFilter /* = 0.0f */);
@@ -311,18 +366,45 @@ int EchoFilter_setParamsEx(EchoFilter * aEchoFilter, float aDelay, float aDecay
  */
 void FFTFilter_destroy(FFTFilter * aFFTFilter);
 FFTFilter * FFTFilter_create();
+int FFTFilter_getParamCount(FFTFilter * aFFTFilter);
+const char * FFTFilter_getParamName(FFTFilter * aFFTFilter, unsigned int aParamIndex);
+unsigned int FFTFilter_getParamType(FFTFilter * aFFTFilter, unsigned int aParamIndex);
+float FFTFilter_getParamMax(FFTFilter * aFFTFilter, unsigned int aParamIndex);
+float FFTFilter_getParamMin(FFTFilter * aFFTFilter, unsigned int aParamIndex);
 
 /*
  * FlangerFilter
  */
 void FlangerFilter_destroy(FlangerFilter * aFlangerFilter);
+int FlangerFilter_getParamCount(FlangerFilter * aFlangerFilter);
+const char * FlangerFilter_getParamName(FlangerFilter * aFlangerFilter, unsigned int aParamIndex);
+unsigned int FlangerFilter_getParamType(FlangerFilter * aFlangerFilter, unsigned int aParamIndex);
+float FlangerFilter_getParamMax(FlangerFilter * aFlangerFilter, unsigned int aParamIndex);
+float FlangerFilter_getParamMin(FlangerFilter * aFlangerFilter, unsigned int aParamIndex);
 FlangerFilter * FlangerFilter_create();
 int FlangerFilter_setParams(FlangerFilter * aFlangerFilter, float aDelay, float aFreq);
 
+/*
+ * FreeverbFilter
+ */
+void FreeverbFilter_destroy(FreeverbFilter * aFreeverbFilter);
+int FreeverbFilter_getParamCount(FreeverbFilter * aFreeverbFilter);
+const char * FreeverbFilter_getParamName(FreeverbFilter * aFreeverbFilter, unsigned int aParamIndex);
+unsigned int FreeverbFilter_getParamType(FreeverbFilter * aFreeverbFilter, unsigned int aParamIndex);
+float FreeverbFilter_getParamMax(FreeverbFilter * aFreeverbFilter, unsigned int aParamIndex);
+float FreeverbFilter_getParamMin(FreeverbFilter * aFreeverbFilter, unsigned int aParamIndex);
+FreeverbFilter * FreeverbFilter_create();
+int FreeverbFilter_setParams(FreeverbFilter * aFreeverbFilter, float aMode, float aRoomSize, float aDamp, float aWidth);
+
 /*
  * LofiFilter
  */
 void LofiFilter_destroy(LofiFilter * aLofiFilter);
+int LofiFilter_getParamCount(LofiFilter * aLofiFilter);
+const char * LofiFilter_getParamName(LofiFilter * aLofiFilter, unsigned int aParamIndex);
+unsigned int LofiFilter_getParamType(LofiFilter * aLofiFilter, unsigned int aParamIndex);
+float LofiFilter_getParamMax(LofiFilter * aLofiFilter, unsigned int aParamIndex);
+float LofiFilter_getParamMin(LofiFilter * aLofiFilter, unsigned int aParamIndex);
 LofiFilter * LofiFilter_create();
 int LofiFilter_setParams(LofiFilter * aLofiFilter, float aSampleRate, float aBitdepth);
 
@@ -332,10 +414,10 @@ int LofiFilter_setParams(LofiFilter * aLofiFilter, float aSampleRate, float aBit
 void Monotone_destroy(Monotone * aMonotone);
 Monotone * Monotone_create();
 int Monotone_setParams(Monotone * aMonotone, int aHardwareChannels);
-int Monotone_setParamsEx(Monotone * aMonotone, int aHardwareChannels, int aWaveform /* = SQUARE */);
+int Monotone_setParamsEx(Monotone * aMonotone, int aHardwareChannels, int aWaveform /* = Soloud::WAVE_SQUARE */);
 int Monotone_load(Monotone * aMonotone, const char * aFilename);
-int Monotone_loadMem(Monotone * aMonotone, unsigned char * aMem, unsigned int aLength);
-int Monotone_loadMemEx(Monotone * aMonotone, unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
+int Monotone_loadMem(Monotone * aMonotone, const unsigned char * aMem, unsigned int aLength);
+int Monotone_loadMemEx(Monotone * aMonotone, const unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
 int Monotone_loadFile(Monotone * aMonotone, File * aFile);
 void Monotone_setVolume(Monotone * aMonotone, float aVolume);
 void Monotone_setLooping(Monotone * aMonotone, int aLoop);
@@ -353,14 +435,37 @@ double Monotone_getLoopPoint(Monotone * aMonotone);
 void Monotone_setFilter(Monotone * aMonotone, unsigned int aFilterId, Filter * aFilter);
 void Monotone_stop(Monotone * aMonotone);
 
+/*
+ * Noise
+ */
+void Noise_destroy(Noise * aNoise);
+Noise * Noise_create();
+void Noise_setOctaveScale(Noise * aNoise, float aOct0, float aOct1, float aOct2, float aOct3, float aOct4, float aOct5, float aOct6, float aOct7, float aOct8, float aOct9);
+void Noise_setType(Noise * aNoise, int aType);
+void Noise_setVolume(Noise * aNoise, float aVolume);
+void Noise_setLooping(Noise * aNoise, int aLoop);
+void Noise_set3dMinMaxDistance(Noise * aNoise, float aMinDistance, float aMaxDistance);
+void Noise_set3dAttenuation(Noise * aNoise, unsigned int aAttenuationModel, float aAttenuationRolloffFactor);
+void Noise_set3dDopplerFactor(Noise * aNoise, float aDopplerFactor);
+void Noise_set3dListenerRelative(Noise * aNoise, int aListenerRelative);
+void Noise_set3dDistanceDelay(Noise * aNoise, int aDistanceDelay);
+void Noise_set3dCollider(Noise * aNoise, AudioCollider * aCollider);
+void Noise_set3dColliderEx(Noise * aNoise, AudioCollider * aCollider, int aUserData /* = 0 */);
+void Noise_set3dAttenuator(Noise * aNoise, AudioAttenuator * aAttenuator);
+void Noise_setInaudibleBehavior(Noise * aNoise, int aMustTick, int aKill);
+void Noise_setLoopPoint(Noise * aNoise, double aLoopPoint);
+double Noise_getLoopPoint(Noise * aNoise);
+void Noise_setFilter(Noise * aNoise, unsigned int aFilterId, Filter * aFilter);
+void Noise_stop(Noise * aNoise);
+
 /*
  * Openmpt
  */
 void Openmpt_destroy(Openmpt * aOpenmpt);
 Openmpt * Openmpt_create();
 int Openmpt_load(Openmpt * aOpenmpt, const char * aFilename);
-int Openmpt_loadMem(Openmpt * aOpenmpt, unsigned char * aMem, unsigned int aLength);
-int Openmpt_loadMemEx(Openmpt * aOpenmpt, unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
+int Openmpt_loadMem(Openmpt * aOpenmpt, const unsigned char * aMem, unsigned int aLength);
+int Openmpt_loadMemEx(Openmpt * aOpenmpt, const unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
 int Openmpt_loadFile(Openmpt * aOpenmpt, File * aFile);
 void Openmpt_setVolume(Openmpt * aOpenmpt, float aVolume);
 void Openmpt_setLooping(Openmpt * aOpenmpt, int aLoop);
@@ -409,16 +514,14 @@ void Queue_stop(Queue * aQueue);
  * RobotizeFilter
  */
 void RobotizeFilter_destroy(RobotizeFilter * aRobotizeFilter);
+int RobotizeFilter_getParamCount(RobotizeFilter * aRobotizeFilter);
+const char * RobotizeFilter_getParamName(RobotizeFilter * aRobotizeFilter, unsigned int aParamIndex);
+unsigned int RobotizeFilter_getParamType(RobotizeFilter * aRobotizeFilter, unsigned int aParamIndex);
+float RobotizeFilter_getParamMax(RobotizeFilter * aRobotizeFilter, unsigned int aParamIndex);
+float RobotizeFilter_getParamMin(RobotizeFilter * aRobotizeFilter, unsigned int aParamIndex);
+void RobotizeFilter_setParams(RobotizeFilter * aRobotizeFilter, float aFreq, int aWaveform);
 RobotizeFilter * RobotizeFilter_create();
 
-/*
- * Prg
- */
-void Prg_destroy(Prg * aPrg);
-Prg * Prg_create();
-unsigned int Prg_rand(Prg * aPrg);
-void Prg_srand(Prg * aPrg, int aSeed);
-
 /*
  * Sfxr
  */
@@ -477,8 +580,8 @@ void TedSid_destroy(TedSid * aTedSid);
 TedSid * TedSid_create();
 int TedSid_load(TedSid * aTedSid, const char * aFilename);
 int TedSid_loadToMem(TedSid * aTedSid, const char * aFilename);
-int TedSid_loadMem(TedSid * aTedSid, unsigned char * aMem, unsigned int aLength);
-int TedSid_loadMemEx(TedSid * aTedSid, unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
+int TedSid_loadMem(TedSid * aTedSid, const unsigned char * aMem, unsigned int aLength);
+int TedSid_loadMemEx(TedSid * aTedSid, const unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
 int TedSid_loadFileToMem(TedSid * aTedSid, File * aFile);
 int TedSid_loadFile(TedSid * aTedSid, File * aFile);
 void TedSid_setVolume(TedSid * aTedSid, float aVolume);
@@ -550,8 +653,8 @@ void Vizsn_stop(Vizsn * aVizsn);
 void Wav_destroy(Wav * aWav);
 Wav * Wav_create();
 int Wav_load(Wav * aWav, const char * aFilename);
-int Wav_loadMem(Wav * aWav, unsigned char * aMem, unsigned int aLength);
-int Wav_loadMemEx(Wav * aWav, unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
+int Wav_loadMem(Wav * aWav, const unsigned char * aMem, unsigned int aLength);
+int Wav_loadMemEx(Wav * aWav, const unsigned char * aMem, unsigned int aLength, int aCopy /* = false */, int aTakeOwnership /* = true */);
 int Wav_loadFile(Wav * aWav, File * aFile);
 int Wav_loadRawWave8(Wav * aWav, unsigned char * aMem, unsigned int aLength);
 int Wav_loadRawWave8Ex(Wav * aWav, unsigned char * aMem, unsigned int aLength, float aSamplerate /* = 44100.0f */, unsigned int aChannels /* = 1 */);
@@ -581,8 +684,12 @@ void Wav_stop(Wav * aWav);
  */
 void WaveShaperFilter_destroy(WaveShaperFilter * aWaveShaperFilter);
 int WaveShaperFilter_setParams(WaveShaperFilter * aWaveShaperFilter, float aAmount);
-int WaveShaperFilter_setParamsEx(WaveShaperFilter * aWaveShaperFilter, float aAmount, float aWet /* = 1.0f */);
 WaveShaperFilter * WaveShaperFilter_create();
+int WaveShaperFilter_getParamCount(WaveShaperFilter * aWaveShaperFilter);
+const char * WaveShaperFilter_getParamName(WaveShaperFilter * aWaveShaperFilter, unsigned int aParamIndex);
+unsigned int WaveShaperFilter_getParamType(WaveShaperFilter * aWaveShaperFilter, unsigned int aParamIndex);
+float WaveShaperFilter_getParamMax(WaveShaperFilter * aWaveShaperFilter, unsigned int aParamIndex);
+float WaveShaperFilter_getParamMin(WaveShaperFilter * aWaveShaperFilter, unsigned int aParamIndex);
 
 /*
  * WavStream
@@ -590,8 +697,8 @@ WaveShaperFilter * WaveShaperFilter_create();
 void WavStream_destroy(WavStream * aWavStream);
 WavStream * WavStream_create();
 int WavStream_load(WavStream * aWavStream, const char * aFilename);
-int WavStream_loadMem(WavStream * aWavStream, unsigned char * aData, unsigned int aDataLen);
-int WavStream_loadMemEx(WavStream * aWavStream, unsigned char * aData, unsigned int aDataLen, int aCopy /* = false */, int aTakeOwnership /* = true */);
+int WavStream_loadMem(WavStream * aWavStream, const unsigned char * aData, unsigned int aDataLen);
+int WavStream_loadMemEx(WavStream * aWavStream, const unsigned char * aData, unsigned int aDataLen, int aCopy /* = false */, int aTakeOwnership /* = true */);
 int WavStream_loadToMem(WavStream * aWavStream, const char * aFilename);
 int WavStream_loadFile(WavStream * aWavStream, File * aFile);
 int WavStream_loadFileToMem(WavStream * aWavStream, File * aFile);

+ 1 - 1
soloud.mod/soloud/include/soloud_dcremovalfilter.h

@@ -40,7 +40,7 @@ namespace SoLoud
 		int mOffset;
 
 	public:
-		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aChannels, float aSamplerate, time aTime);
+		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aBufferSize, unsigned int aChannels, float aSamplerate, time aTime);
 		virtual ~DCRemovalFilterInstance();
 		DCRemovalFilterInstance(DCRemovalFilter *aParent);
 	};

+ 15 - 3
soloud.mod/soloud/include/soloud_echofilter.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2014 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -35,11 +35,11 @@ namespace SoLoud
 	{
 		float *mBuffer;
 		int mBufferLength;
-		EchoFilter *mParent;
+		int mBufferMaxLength;
 		int mOffset;
 
 	public:
-		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aChannels, float aSamplerate, time aTime);
+		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aBufferSize, unsigned int aChannels, float aSamplerate, time aTime);
 		virtual ~EchoFilterInstance();
 		EchoFilterInstance(EchoFilter *aParent);
 	};
@@ -47,9 +47,21 @@ namespace SoLoud
 	class EchoFilter : public Filter
 	{
 	public:
+		enum FILTERATTRIBUTE
+		{
+			WET = 0,
+			DELAY,
+			DECAY,
+			FILTER
+		};
 		float mDelay;
 		float mDecay;
 		float mFilter;
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
 		virtual FilterInstance *createInstance();
 		EchoFilter();
 		result setParams(float aDelay, float aDecay = 0.7f, float aFilter = 0.0f);

+ 4 - 4
soloud.mod/soloud/include/soloud_file.h

@@ -45,7 +45,7 @@ namespace SoLoud
 		virtual void seek(int aOffset) = 0;
 		virtual unsigned int pos() = 0;
 		virtual FILE * getFilePtr() { return 0; }
-		virtual unsigned char * getMemPtr() { return 0; }
+		virtual const unsigned char * getMemPtr() { return 0; }
 	};
 
 	class DiskFile : public File
@@ -68,7 +68,7 @@ namespace SoLoud
 	class MemoryFile : public File
 	{
 	public:
-		unsigned char *mDataPtr;
+		const unsigned char *mDataPtr;
 		unsigned int mDataLength;
 		unsigned int mOffset;
 		bool mDataOwned;
@@ -78,10 +78,10 @@ namespace SoLoud
 		virtual unsigned int length();
 		virtual void seek(int aOffset);
 		virtual unsigned int pos();
-		virtual unsigned char * getMemPtr();
+		virtual const unsigned char * getMemPtr();
 		virtual ~MemoryFile();
 		MemoryFile();
-		result openMem(unsigned char *aData, unsigned int aDataLength, bool aCopy=false, bool aTakeOwnership=true);
+		result openMem(const unsigned char *aData, unsigned int aDataLength, bool aCopy=false, bool aTakeOwnership=true);
 		result openToMem(const char *aFilename);
 		result openFileToMem(File *aFile);
 	};

+ 2 - 1
soloud.mod/soloud/include/soloud_file_hack_off.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2015 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -33,3 +33,4 @@ See soloud_file_hack_on.h
 #undef ftell 
 #undef fclose
 #undef fopen 
+#undef fopen_s

+ 3 - 1
soloud.mod/soloud/include/soloud_file_hack_on.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2015 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -44,6 +44,7 @@ extern int Soloud_Filehack_fseek(Soloud_Filehack *f, int idx, int base);
 extern int Soloud_Filehack_ftell(Soloud_Filehack *f);
 extern int Soloud_Filehack_fclose(Soloud_Filehack *f);
 extern Soloud_Filehack * Soloud_Filehack_fopen(const char *aFilename, char *aMode);
+extern int Soloud_Filehack_fopen_s(Soloud_Filehack **f, const char* aFilename, char* aMode);
 
 #ifdef __cplusplus
 }
@@ -56,3 +57,4 @@ extern Soloud_Filehack * Soloud_Filehack_fopen(const char *aFilename, char *aMod
 #define ftell Soloud_Filehack_ftell
 #define fclose Soloud_Filehack_fclose
 #define fopen Soloud_Filehack_fopen
+#define fopen_s Soloud_Filehack_fopen_s

+ 13 - 1
soloud.mod/soloud/include/soloud_filter.h

@@ -43,7 +43,7 @@ namespace SoLoud
 		FilterInstance();
 		virtual result initParams(int aNumParams);
 		virtual void updateParams(time aTime);
-		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aChannels, float aSamplerate, time aTime);
+		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aBufferSize, unsigned int aChannels, float aSamplerate, time aTime);
 		virtual void filterChannel(float *aBuffer, unsigned int aSamples, float aSamplerate, time aTime, unsigned int aChannel, unsigned int aChannels);
 		virtual float getFilterParameter(unsigned int aAttributeId);
 		virtual void setFilterParameter(unsigned int aAttributeId, float aValue);
@@ -55,7 +55,19 @@ namespace SoLoud
 	class Filter
 	{
 	public:
+		enum PARAMTYPE
+		{
+			FLOAT_PARAM = 0,
+			INT_PARAM,
+			BOOL_PARAM
+		};
 		Filter();
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
+
 		virtual FilterInstance *createInstance() = 0;
 		virtual ~Filter();
 	};

+ 7 - 2
soloud.mod/soloud/include/soloud_flangerfilter.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2014 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -40,7 +40,7 @@ namespace SoLoud
 		double mIndex;
 
 	public:
-		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aChannels, float aSamplerate, time aTime);
+		virtual void filter(float *aBuffer, unsigned int aSamples, unsigned int aBufferSize, unsigned int aChannels, float aSamplerate, time aTime);
 		virtual ~FlangerFilterInstance();
 		FlangerFilterInstance(FlangerFilter *aParent);
 	};
@@ -56,6 +56,11 @@ namespace SoLoud
 		};
 		float mDelay;
 		float mFreq;
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
 		virtual FilterInstance *createInstance();
 		FlangerFilter();
 		result setParams(float aDelay, float aFreq);

+ 83 - 0
soloud.mod/soloud/include/soloud_freeverbfilter.h

@@ -0,0 +1,83 @@
+/*
+SoLoud audio engine
+Copyright (c) 2013-2020 Jari Komppa
+
+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.
+*/
+
+#ifndef SOLOUD_FREEVERBFILTER_H
+#define SOLOUD_FREEVERBFILTER_H
+
+#include "soloud.h"
+
+namespace SoLoud
+{
+	class FreeverbFilter;
+	namespace FreeverbImpl
+	{
+		class Revmodel;
+	}
+
+	class FreeverbFilterInstance : public FilterInstance
+	{
+		enum FILTERPARAM {
+			WET = 0,
+			FREEZE,
+			ROOMSIZE,
+			DAMP,
+			WIDTH
+		};		
+
+		FreeverbFilter *mParent;
+		FreeverbImpl::Revmodel *mModel;
+	public:
+		virtual void filter(float* aBuffer, unsigned int aSamples, unsigned int aBufferSize, unsigned int aChannels, float aSamplerate, time aTime);
+		virtual ~FreeverbFilterInstance();
+		FreeverbFilterInstance(FreeverbFilter *aParent);
+	};
+
+	class FreeverbFilter : public Filter
+	{
+	public:
+		enum FILTERPARAM {
+			WET = 0,
+			FREEZE,
+			ROOMSIZE,
+			DAMP,
+			WIDTH
+		};
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
+
+		float mMode;
+		float mRoomSize;
+		float mDamp;
+		float mWidth;
+		virtual FreeverbFilterInstance *createInstance();
+		FreeverbFilter();
+		result setParams(float aMode, float aRoomSize, float aDamp, float aWidth);
+		virtual ~FreeverbFilter();
+	};
+}
+
+#endif

+ 51 - 11
soloud.mod/soloud/include/soloud_internal.h

@@ -71,28 +71,34 @@ namespace SoLoud
 	// ALSA back-end initialization call
 	result alsa_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2);
 
+	// JACK back-end initialization call
+	result jack_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2);
+
+	// MiniAudio back-end initialization call
+	result miniaudio_init(SoLoud::Soloud* aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2);
+
+	// nosound back-end initialization call
+	result nosound_init(SoLoud::Soloud* aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2);
+
 	// null driver back-end initialization call
 	result null_init(SoLoud::Soloud *aSoloud, unsigned int aFlags = Soloud::CLIP_ROUNDOFF, unsigned int aSamplerate = 44100, unsigned int aBuffer = 2048, unsigned int aChannels = 2);
 
-	// Deinterlace samples in a buffer. From 12121212 to 11112222
-	void deinterlace_samples_float(const float *aSourceBuffer, float *aDestBuffer, unsigned int aSamples, unsigned int aChannels);
-
 	// Interlace samples in a buffer. From 11112222 to 12121212
-	void interlace_samples_float(const float *aSourceBuffer, float *aDestBuffer, unsigned int aSamples, unsigned int aChannels);
+	void interlace_samples_float(const float *aSourceBuffer, float *aDestBuffer, unsigned int aSamples, unsigned int aChannels, unsigned int aStride);
 
 	// Convert to 16-bit and interlace samples in a buffer. From 11112222 to 12121212
-	void interlace_samples_s16(const float *aSourceBuffer, short *aDestBuffer, unsigned int aSamples, unsigned int aChannels);
+	void interlace_samples_s16(const float *aSourceBuffer, short *aDestBuffer, unsigned int aSamples, unsigned int aChannels, unsigned int aStride);
 };
 
 #define FOR_ALL_VOICES_PRE \
 		handle *h_ = NULL; \
 		handle th_[2] = { aVoiceHandle, 0 }; \
-		lockAudioMutex(); \
-		h_ = voiceGroupHandleToArray(aVoiceHandle); \
+		lockAudioMutex_internal(); \
+		h_ = voiceGroupHandleToArray_internal(aVoiceHandle); \
 		if (h_ == NULL) h_ = th_; \
 		while (*h_) \
 		{ \
-			int ch = getVoiceFromHandle(*h_); \
+			int ch = getVoiceFromHandle_internal(*h_); \
 			if (ch != -1)  \
 			{
 
@@ -100,12 +106,12 @@ namespace SoLoud
 			} \
 			h_++; \
 		} \
-		unlockAudioMutex();
+		unlockAudioMutex_internal();
 
 #define FOR_ALL_VOICES_PRE_3D \
 		handle *h_ = NULL; \
 		handle th_[2] = { aVoiceHandle, 0 }; \
-		h_ = voiceGroupHandleToArray(aVoiceHandle); \
+		h_ = voiceGroupHandleToArray_internal(aVoiceHandle); \
 		if (h_ == NULL) h_ = th_; \
 				while (*h_) \
 						{ \
@@ -118,4 +124,38 @@ namespace SoLoud
 			h_++; \
 						} 
 
-#endif
+#define FOR_ALL_VOICES_PRE_EXT \
+		handle *h_ = NULL; \
+		handle th_[2] = { aVoiceHandle, 0 }; \
+		mSoloud->lockAudioMutex_internal(); \
+		h_ = mSoloud->voiceGroupHandleToArray_internal(aVoiceHandle); \
+		if (h_ == NULL) h_ = th_; \
+		while (*h_) \
+		{ \
+			int ch = mSoloud->getVoiceFromHandle_internal(*h_); \
+			if (ch != -1)  \
+			{
+
+#define FOR_ALL_VOICES_POST_EXT \
+			} \
+			h_++; \
+		} \
+		mSoloud->unlockAudioMutex_internal();
+
+#define FOR_ALL_VOICES_PRE_3D_EXT \
+		handle *h_ = NULL; \
+		handle th_[2] = { aVoiceHandle, 0 }; \
+		h_ = mSoloud->voiceGroupHandleToArray(aVoiceHandle); \
+		if (h_ == NULL) h_ = th_; \
+				while (*h_) \
+						{ \
+			int ch = (*h_ & 0xfff) - 1; \
+			if (ch != -1 && mSoloud->m3dData[ch].mHandle == *h_)  \
+						{
+
+#define FOR_ALL_VOICES_POST_3D_EXT \
+						} \
+			h_++; \
+						} 
+
+#endif

+ 6 - 1
soloud.mod/soloud/include/soloud_lofifilter.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2014 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -66,6 +66,11 @@ namespace SoLoud
 		float mSampleRate;
 		float mBitdepth;
 		virtual LofiFilterInstance *createInstance();
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
 		LofiFilter();
 		result setParams(float aSampleRate, float aBitdepth);
 		virtual ~LofiFilter();

+ 53 - 0
soloud.mod/soloud/include/soloud_misc.h

@@ -0,0 +1,53 @@
+/*
+SoLoud audio engine
+Copyright (c) 2020 Jari Komppa
+
+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.
+*/
+
+#ifndef SOLOUD_MISC_H
+#define SOLOUD_MISC_H
+
+#include "soloud.h"
+
+namespace SoLoud
+{
+	namespace Misc
+	{
+		// Generate a waveform.
+		float generateWaveform(int aWaveform, float p);
+
+		// WELL512 random
+		class Prg
+		{
+		public:
+			// random generator
+			Prg();
+			unsigned int mState[16];
+			unsigned int mIndex;
+			unsigned int rand();
+			float rand_float();
+			void srand(int aSeed);
+		};
+
+	};
+};
+
+#endif

+ 4 - 10
soloud.mod/soloud/include/soloud_monotone.h

@@ -1,6 +1,6 @@
 /*
 MONOTONE module for SoLoud audio engine
-Copyright (c) 2013-2015 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -26,6 +26,7 @@ freely, subject to the following restrictions:
 #define MONOTONE_H
 
 #include "soloud.h"
+#include "soloud_misc.h"
 
 namespace SoLoud
 {
@@ -88,13 +89,6 @@ namespace SoLoud
 	class Monotone : public AudioSource
 	{
 	public:
-		enum MONOTONE_WAVEFORMS
-		{
-			SQUARE = 0,
-			SAW    = 1,
-			SIN    = 2,
-			SAWSIN = 3
-		};
 		
 		int mNotesHz[800];
 		int mVibTable[32];
@@ -103,9 +97,9 @@ namespace SoLoud
 		MonotoneSong mSong;
 		Monotone();
 		~Monotone();
-		result setParams(int aHardwareChannels, int aWaveform = SQUARE);
+		result setParams(int aHardwareChannels, int aWaveform = Soloud::WAVE_SQUARE);
 		result load(const char *aFilename);
-		result loadMem(unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
+		result loadMem(const unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
 		result loadFile(File *aFile);
 		virtual AudioSourceInstance *createInstance();
 	public:

+ 74 - 0
soloud.mod/soloud/include/soloud_noise.h

@@ -0,0 +1,74 @@
+/*
+SoLoud audio engine
+Copyright (c) 2020 Jari Komppa
+
+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.
+*/
+
+#ifndef SOLOUD_NOISE_H
+#define SOLOUD_NOISE_H
+
+#include "soloud.h"
+#include "soloud_misc.h"
+
+namespace SoLoud
+{
+	class Noise;
+
+	class NoiseInstance : public AudioSourceInstance
+	{
+	public:
+		NoiseInstance(Noise *aParent);
+		~NoiseInstance();
+
+		virtual unsigned int getAudio(float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize);
+		virtual bool hasEnded();
+
+	public:
+		float mOctaveScale[10];
+	    Misc::Prg mPrg;
+	};
+
+	class Noise : public AudioSource
+	{
+	public:
+
+		enum NOISETYPES
+		{
+			WHITE = 0,
+			PINK,
+			BROWNISH,
+			BLUEISH
+		};
+
+		Noise();
+
+		void setOctaveScale(float aOct0, float aOct1, float aOct2, float aOct3, float aOct4, float aOct5, float aOct6, float aOct7, float aOct8, float aOct9);
+		void setType(int aType);
+
+		virtual ~Noise();
+		
+	public:
+		virtual AudioSourceInstance *createInstance();
+		float mOctaveScale[10];
+	};
+};
+
+#endif

+ 1 - 1
soloud.mod/soloud/include/soloud_openmpt.h

@@ -53,7 +53,7 @@ namespace SoLoud
 		Openmpt();
 		virtual ~Openmpt();
 		result load(const char* aFilename);
-		result loadMem(unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
+		result loadMem(const unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
 		result loadFile(File *aFile);
 		virtual AudioSourceInstance *createInstance();
 	};

+ 20 - 8
soloud.mod/soloud/include/soloud_robotizefilter.h

@@ -1,6 +1,6 @@
 /*
 SoLoud audio engine
-Copyright (c) 2013-2018 Jari Komppa
+Copyright (c) 2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -26,32 +26,44 @@ freely, subject to the following restrictions:
 #define SOLOUD_ROBOTIZEFILTER_H
 
 #include "soloud.h"
-#include "soloud_fftfilter.h"
+#include "soloud_filter.h"
+#include "soloud_misc.h"
 
 namespace SoLoud
 {
 	class RobotizeFilter;
 
-	class RobotizeFilterInstance : public FFTFilterInstance
+	class RobotizeFilterInstance : public FilterInstance
 	{
 		enum FILTERATTRIBUTE
 		{
-			WET = 0
+			WET = 0,
+			FREQ,
+			WAVE
 		};
 		RobotizeFilter *mParent;
 	public:
-		virtual void fftFilterChannel(float *aFFTBuffer, unsigned int aSamples, float aSamplerate, time aTime, unsigned int aChannel, unsigned int aChannels);
+		virtual void filterChannel(float *aBuffer, unsigned int aSamples, float aSamplerate, time aTime, unsigned int aChannel, unsigned int aChannels);
 		RobotizeFilterInstance(RobotizeFilter *aParent);
 	};
 
-	class RobotizeFilter : public FFTFilter
+	class RobotizeFilter : public Filter
 	{
 	public:
 		enum FILTERATTRIBUTE
 		{
-			WET = 0
+			WET = 0,
+			FREQ,
+			WAVE
 		};
-		float mBoost;
+		float mFreq;
+		int mWave;
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
+		void setParams(float aFreq, int aWaveform);
 		virtual FilterInstance *createInstance();
 		RobotizeFilter();
 	};

+ 3 - 13
soloud.mod/soloud/include/soloud_sfxr.h

@@ -27,22 +27,12 @@ freely, subject to the following restrictions:
 #define SFXR_H
 
 #include "soloud.h"
+#include "soloud_misc.h"
 
 namespace SoLoud
 {
 	class File;
 
-	class Prg
-	{
-	public:
-		// random generator
-		Prg();
-		unsigned int state[16];
-		unsigned int index;
-		unsigned int rand();
-		void srand(int aSeed);
-	};
-
 	struct SfxrParams
 	{
 		int wave_type;
@@ -89,7 +79,7 @@ namespace SoLoud
 	{
 		Sfxr *mParent;
 
-		Prg mRand;
+		Misc::Prg mRand;
 		SfxrParams mParams;
 
 		bool playing_sample;
@@ -152,7 +142,7 @@ namespace SoLoud
 			BLIP
 		};
 
-		Prg mRand;
+		Misc::Prg mRand;
 		
 		Sfxr();
 		virtual ~Sfxr();

+ 1 - 1
soloud.mod/soloud/include/soloud_tedsid.h

@@ -64,7 +64,7 @@ namespace SoLoud
 		~TedSid();
 		result load(const char *aFilename);
 		result loadToMem(const char *aFilename);
-		result loadMem(unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
+		result loadMem(const unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
 		result loadFileToMem(File *aFile);
 		result loadFile(File *aFile);
 		virtual AudioSourceInstance *createInstance();

+ 1 - 0
soloud.mod/soloud/include/soloud_thread.h

@@ -46,6 +46,7 @@ namespace SoLoud
 		void sleep(int aMSec);
         void wait(ThreadHandle aThreadHandle);
         void release(ThreadHandle aThreadHandle);
+		int getTimeMillis();
 
 #define MAX_THREADPOOL_TASKS 1024
 

+ 1 - 1
soloud.mod/soloud/include/soloud_wav.h

@@ -60,7 +60,7 @@ namespace SoLoud
 		Wav();
 		virtual ~Wav();
 		result load(const char *aFilename);
-		result loadMem(unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
+		result loadMem(const unsigned char *aMem, unsigned int aLength, bool aCopy = false, bool aTakeOwnership = true);
 		result loadFile(File *aFile);
 		result loadRawWave8(unsigned char *aMem, unsigned int aLength, float aSamplerate = 44100.0f, unsigned int aChannels = 1);
 		result loadRawWave16(short *aMem, unsigned int aLength, float aSamplerate = 44100.0f, unsigned int aChannels = 1);

+ 11 - 2
soloud.mod/soloud/include/soloud_waveshaperfilter.h

@@ -43,11 +43,20 @@ namespace SoLoud
 	class WaveShaperFilter : public Filter
 	{
 	public:
-		float mAmount, mWet;
+		enum FILTERPARAMS {
+			WET = 0,
+			AMOUNT
+		};
+		float mAmount;
 		virtual WaveShaperFilterInstance *createInstance();
-		result setParams(float aAmount, float aWet = 1.0f);
+		result setParams(float aAmount);
 		WaveShaperFilter();
 		virtual ~WaveShaperFilter();
+		virtual int getParamCount();
+		virtual const char* getParamName(unsigned int aParamIndex);
+		virtual unsigned int getParamType(unsigned int aParamIndex);
+		virtual float getParamMax(unsigned int aParamIndex);
+		virtual float getParamMin(unsigned int aParamIndex);
 	};
 }
 

+ 1 - 1
soloud.mod/soloud/include/soloud_wavstream.h

@@ -91,7 +91,7 @@ namespace SoLoud
 		WavStream();
 		virtual ~WavStream();
 		result load(const char *aFilename);
-		result loadMem(unsigned char *aData, unsigned int aDataLen, bool aCopy = false, bool aTakeOwnership = true);
+		result loadMem(const unsigned char *aData, unsigned int aDataLen, bool aCopy = false, bool aTakeOwnership = true);
 		result loadToMem(const char *aFilename);
 		result loadFile(File *aFile);
 		result loadFileToMem(File *aFile);		

+ 2 - 2
soloud.mod/soloud/scripts/checkapidoc.py

@@ -8,7 +8,7 @@ import os
 def checkfile(apifunc, fname):
     """ Checks whether the string can be found in a file """
     if apifunc in open(fname).read():
-        print(apifunc + " found in " + fname)
+        #print("; " + apifunc + " found in " + fname)
         return True
     return False
     
@@ -17,7 +17,7 @@ def checkfiles(apifunc):
         them to checkfile. If found, early out.
     """
     for file in glob.glob("../docsrc/*.mmd"):
-        #if checkfile(apifunc, file):
+        if checkfile(apifunc, file):
             return True
     return False
 

+ 1 - 0
soloud.mod/soloud/scripts/gen_blitzmax.py

@@ -21,6 +21,7 @@ C_TO_BMX_TYPES = {
     "int":"Int",
     "void":"Int",
     "const char *":"Byte Ptr",
+    "const unsigned char *":"Byte Ptr",
     "unsigned int":"Int",
     "float":"Float",
     "double":"Double",

+ 4 - 0
soloud.mod/soloud/scripts/gen_cs.py

@@ -18,6 +18,7 @@ C_TO_CS_TYPES = {
     "float *":"float[]",
     "File *":"SoloudObject",
     "unsigned char *":"IntPtr",
+    "const unsigned char *":"IntPtr",
     "unsigned char":"byte",
     "short *":"IntPtr"
 }
@@ -153,6 +154,9 @@ for x in soloud_codegen.soloud_type:
                 if y[0] == 'const char *':                    
                     charptr = True
                     ret = 'IntPtr'
+                if y[0] == 'const unsigned char *':                    
+                    charptr = True
+                    ret = 'IntPtr'
                 if y[0] == 'float *':
                     floatptr = True
                     ret = 'IntPtr'

+ 1 - 0
soloud.mod/soloud/scripts/gen_d.py

@@ -17,6 +17,7 @@ C_TO_D_TYPES = {
     "double":"double",
     "float *":"float[]",
     "File *":"SoloudObject",
+    "const unsigned char *":"ubyte*",
     "unsigned char *":"ubyte*",
     "unsigned char":"ubyte",
     "short *":"short[]"

+ 8 - 3
soloud.mod/soloud/scripts/gen_gamemaker.py

@@ -21,6 +21,7 @@ UNSUPPORTED_TYPES = {
     "float *":1,
     "File *":1,
     "unsigned char *":1,
+    "const unsigned char *":1,
     "short *":1
 }
 
@@ -63,7 +64,8 @@ C_TO_GMX_TYPES = {
     "float":"2",
     "double":"2",
     "float *":PTRTYPE,
-    "unsigned char *":PTRTYPE
+    "unsigned char *":PTRTYPE,
+    "const unsigned char *":PTRTYPE
 }
 
 for soloud_type in soloud_codegen.soloud_type:
@@ -254,7 +256,8 @@ MASK_TYPES = {
     "float":"float",
     "double":"double",
     "float *":"float *",
-    "unsigned char *":"usigned char *"
+    "unsigned char *":"usigned char *",
+    "const unsigned char *":"const usigned char *"
 }
 
 for soloud_type in soloud_codegen.soloud_type:
@@ -289,7 +292,8 @@ C_TO_GMX_DLL_TYPES = {
     "float":"double",
     "double":"double",
     "float *":"char *",
-    "unsigned char *":"char *"
+    "unsigned char *":"char *",
+    "const unsigned char *":"char *"
 }
 
 for soloud_type in soloud_codegen.soloud_type:
@@ -300,6 +304,7 @@ IS_HANDLE_TYPE = {
     "void":0,
     "const char *":0,
     "char *":0,
+    "const unsigned char *":0,
     "unsigned int":0,
     "float":0,
     "double":0,

+ 6 - 2
soloud.mod/soloud/scripts/gen_python.py

@@ -26,6 +26,7 @@ C_TO_PY_TYPES = {
     "float *":"ctypes.POINTER(ctypes.c_float * 256)",
     "File *":"ctypes.c_void_p",
     "unsigned char *":"ctypes.POINTER(ctypes.c_ubyte)",
+    "const unsigned char *":"ctypes.POINTER(ctypes.c_ubyte)",
     "unsigned char":"ctypes.c_ubyte",
     "short *":"ctypes.POINTER(ctypes.c_short)"
 }
@@ -71,8 +72,11 @@ fo.write('\n')
 fo.write('try:\n')
 fo.write('\tsoloud_dll = ctypes.CDLL("soloud_x86")\n')
 fo.write('except:\n')
-fo.write('\tprint("SoLoud dynamic link library (soloud_x86.dll on Windows) not found. Terminating.")\n')
-fo.write('\tsys.exit()')
+fo.write('\ttry:\n')
+fo.write('\t\tsoloud_dll = ctypes.CDLL("soloud_x64")\n')
+fo.write('\texcept:\n')
+fo.write('\t\tprint("SoLoud dynamic link library (soloud_x86.dll / soloud_x64.dll on Windows, .so on Linux / OSX) not found. Terminating.")\n')
+fo.write('\t\tsys.exit()')
 fo.write("\n")
 
 # Since there's no reason to use the "raw" data anymore,

+ 57 - 17
soloud.mod/soloud/scripts/makerel.py

@@ -45,6 +45,7 @@ sources = [
 "bin/audio/rainy_ambience.ogg",
 "bin/audio/ted_storm.prg.dump",
 "bin/audio/tetsno.ogg",
+"bin/audio/delphi_loop.ogg",
 "bin/audio/war_loop.ogg",
 "bin/audio/windy_ambience.ogg",
 "bin/audio/wavformats/ch1.flac",
@@ -369,7 +370,22 @@ sources = [
 "src/tools/tedsid2dump/tedplay.cpp",
 "src/tools/tedsid2dump/tedplay.h",
 "src/tools/tedsid2dump/tedsound.cpp",
-"src/tools/tedsid2dump/types.h"
+"src/tools/tedsid2dump/types.h",
+"demos/megademo/annex.cpp",
+"demos/megademo/filterfolio.cpp",
+"demos/piano/RtMidi.cpp",
+"demos/piano/RtMidi.h",
+"src/audiosource/noise/soloud_noise.cpp",
+"src/audiosource/tedsid/readme.txt",
+"src/backend/jack/soloud_jack.cpp",
+"src/backend/miniaudio/miniaudio.h",
+"src/backend/miniaudio/soloud_miniaudio.cpp",
+"src/backend/nosound/soloud_nosound.cpp",
+"src/core/soloud_misc.cpp",
+"src/filter/soloud_freeverbfilter.cpp",
+"include/soloud_freeverbfilter.h",
+"include/soloud_misc.h",
+"include/soloud_noise.h"
 ]
 
 notfound = []
@@ -386,6 +402,17 @@ def missingfiles(globpath):
                     notfound.append(x)
         else:
             missingfiles(x+"/*")
+
+def missingsources(globpath):
+    global notfound
+    for x in glob.glob(globpath):    
+        if os.path.isfile(x):
+            if x[-4:] not in [".bak", ".pyc", ".dll"] :
+                x=x.replace('\\','/')
+                if x[len(root):] not in sources:        
+                    notfound.append(x)
+        else:
+            missingsources(x+"/*")
     
 
 def checkfile(findstring, fname):
@@ -426,32 +453,29 @@ for x in sources:
     
 print("All listed files exist.")
 
-#    
-# Check that all of the listed assets are referenced in demos
-#    
+#
+# Verify that there are no new assets that are referenced in the demos
+# but not listed for release
+#
+
+missingsources(root+"demos/*")
+missingsources(root+"include/*")
+missingsources(root+"src/audiosource/*")
+missingsources(root+"src/backend/*")
+missingsources(root+"src/core/*")
+missingsources(root+"src/filter/*")
 
-for x in sources:
-    if "bin/audio" in x or "bin/graphics" in x:
-        checkuse(x[x.rfind("/")+1:])
- 
 if len(notfound) > 0:
-    print("Data files not found in any of the demo sources:")
+    print("Source files/directories found, but not in the list; edit makerel.py or remove them:")
     for x in notfound:
         print(x)
     exit()
 
-print("All listed assets can be found in at least one demo source.")
-
-#
-# Verify that there are no new assets that are referenced in the demos
-# but not listed for release
-#
-
 missingfiles(root+"bin/audio/*")
 missingfiles(root+"bin/graphics/*")
 
 if len(notfound) > 0:
-    print("Data files found in directory and sources, but not in the list:")
+    print("Data files found in directory and source files, but not in the list:")
     for x in notfound:
         print(x)
     exit()
@@ -474,6 +498,22 @@ if len(notfound) > 0:
 
 print("All prebuilt binaries are fresh enough.")
 
+#    
+# Check that all of the listed assets are referenced in demos
+#    
+
+for x in sources:
+    if "bin/audio" in x or "bin/graphics" in x:
+        checkuse(x[x.rfind("/")+1:])
+ 
+if len(notfound) > 0:
+    print("Data files not found in any of the demo sources:")
+    for x in notfound:
+        print(x)
+    exit()
+
+print("All listed assets can be found in at least one demo source.")
+
 #
 # Target directory
 #

+ 11 - 54
soloud.mod/soloud/src/audiosource/monotone/soloud_monotone.cpp

@@ -1,6 +1,6 @@
 /*
 MONOTONE module for SoLoud audio engine
-Copyright (c) 2013-2015 Jari Komppa
+Copyright (c) 2013-2020 Jari Komppa
 
 This software is provided 'as-is', without any express or implied
 warranty. In no event will the authors be held liable for any damages
@@ -60,7 +60,7 @@ namespace SoLoud
 		}
 	}
 
-	unsigned int MonotoneInstance::getAudio(float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize)
+	unsigned int MonotoneInstance::getAudio(float *aBuffer, unsigned int aSamplesToRead, unsigned int /*aBufferSize*/)
 	{
 		int samplesPerTick = (int)floor(mSamplerate / 60);
 		unsigned int i;
@@ -259,59 +259,14 @@ namespace SoLoud
 			
 			aBuffer[i] = 0;
 			int j;
-			switch (mParent->mWaveform)
+			for (j = 0; j < 12; j++)
 			{
-			case Monotone::SAW:
-				for (j = 0; j < 12; j++)
+				if (mOutput[j].mEnabled)
 				{
-					if (mOutput[j].mEnabled)
-					{
-						float bleh = mOutput[j].mSamplePos + mOutput[j].mSamplePosInc;
-						mOutput[j].mSamplePos = bleh - (long)bleh;
-						// saw:
-						aBuffer[i] += ((mOutput[j].mSamplePos) - 0.5f) * 0.5f;
-					}
-				}
-				break;
-			case Monotone::SIN:
-				for (j = 0; j < 12; j++)
-				{
-					if (mOutput[j].mEnabled)
-					{
-						float bleh = mOutput[j].mSamplePos + mOutput[j].mSamplePosInc;
-						mOutput[j].mSamplePos = bleh - (long)bleh;
-						// sin: 
-						aBuffer[i] += (float)sin(mOutput[j].mSamplePos * M_PI * 2) * 0.5f;
-					}
-				}
-				break;
-			case Monotone::SAWSIN:
-				for (j = 0; j < 12; j++)
-				{
-					if (mOutput[j].mEnabled)
-					{
-						float bleh = mOutput[j].mSamplePos + mOutput[j].mSamplePosInc;
-						mOutput[j].mSamplePos = bleh - (long)bleh;
-						// sawsin:
-						bleh = ((mOutput[j].mSamplePos) - 0.5f);
-						bleh *= (float)sin(mOutput[j].mSamplePos * M_PI * 2);
-						aBuffer[i] += bleh;
-					}
-				}
-				break;
-			case Monotone::SQUARE:
-			default:
-				for (j = 0; j < 12; j++)
-				{
-					if (mOutput[j].mEnabled)
-					{
-						float bleh = mOutput[j].mSamplePos + mOutput[j].mSamplePosInc;
-						mOutput[j].mSamplePos = bleh - (long)bleh;
-						// square:
-						aBuffer[i] += (mOutput[j].mSamplePos > 0.5f) ? 0.25f : -0.25f;
-					}
+					float bleh = mOutput[j].mSamplePos + mOutput[j].mSamplePosInc;
+					mOutput[j].mSamplePos = bleh - (long)bleh;					
+					aBuffer[i] += SoLoud::Misc::generateWaveform(mParent->mWaveform, mOutput[j].mSamplePos) * 0.5f;
 				}
-				break;
 			}
 
 			mSampleCount++;
@@ -330,6 +285,8 @@ namespace SoLoud
 		float temphz = 27.5f;
 		int IBO = 12; // Intervals Between Octaves
 		int IBN = 8; // Intervals Between Notes
+		// Fun fact: the resulting constant is pretty 
+		// close to Proton Mass consntant 1.00727646688
 		float interval = 1.00724641222f;//exp(ln(2)/(IBO*IBN));
 		int maxnote = 3 + (8 * IBO) + 1;
 
@@ -360,7 +317,7 @@ namespace SoLoud
 		mChannels = 1;
 
 		mHardwareChannels = 1;
-		mWaveform = SQUARE;
+		mWaveform = Soloud::WAVE_SQUARE;
 	}
 
 	void Monotone::clear()
@@ -400,7 +357,7 @@ namespace SoLoud
 		return SO_NO_ERROR;
 	}
 	
-	result Monotone::loadMem(unsigned char *aMem, unsigned int aLength, bool aCopy, bool aTakeOwnership)
+	result Monotone::loadMem(const unsigned char *aMem, unsigned int aLength, bool aCopy, bool aTakeOwnership)
 	{
 		MemoryFile mf;
 		int res = mf.openMem(aMem, aLength, aCopy, aTakeOwnership);

+ 133 - 0
soloud.mod/soloud/src/audiosource/noise/soloud_noise.cpp

@@ -0,0 +1,133 @@
+/*
+SoLoud audio engine
+Copyright (c) 2020 Jari Komppa
+
+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.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "soloud_noise.h"
+
+namespace SoLoud
+{
+
+	NoiseInstance::NoiseInstance(Noise *aParent)
+	{
+		for (int i = 0; i < 10; i++)
+			mOctaveScale[i] = aParent->mOctaveScale[i];
+		mPrg.srand(0xfade);
+	}
+
+	NoiseInstance::~NoiseInstance()
+	{
+	    
+	}
+
+	unsigned int NoiseInstance::getAudio(float* aBuffer, unsigned int aSamplesToRead, unsigned int /*aBufferSize*/)
+	{
+		int octavestep[10];
+		float octavevalue[10];
+		float totalscale = 0;
+		for (int j = 0; j < 10; j++)
+		{		
+			octavevalue[j] = 0;
+			octavestep[j] = 1 << j;
+			totalscale += mOctaveScale[j];
+		}
+
+		for (unsigned int i = 0; i < aSamplesToRead; i++)
+		{
+			aBuffer[i] = mPrg.rand_float() - 0.5f;
+			for (int j = 0; j < 10; j++)
+			{
+				octavestep[j]++;
+				if (octavestep[j] > (1 << (j + 1)))
+				{
+					octavestep[j] = 0;
+					octavevalue[j] = mPrg.rand_float() - 0.5f;
+				}
+				aBuffer[i] += octavevalue[j] * mOctaveScale[j];
+			}
+			aBuffer[i] *= 1.0f/totalscale;
+		}
+
+		return aSamplesToRead;
+	}
+
+	bool NoiseInstance::hasEnded()
+	{
+		return false;
+	}
+
+	void Noise::setOctaveScale(float aOct0, float aOct1, float aOct2, float aOct3, float aOct4, float aOct5, float aOct6, float aOct7, float aOct8, float aOct9)
+	{
+		mOctaveScale[0] = aOct0;
+		mOctaveScale[1] = aOct1;
+		mOctaveScale[2] = aOct2;
+		mOctaveScale[3] = aOct3;
+		mOctaveScale[4] = aOct4;
+		mOctaveScale[5] = aOct5;
+		mOctaveScale[6] = aOct6;
+		mOctaveScale[7] = aOct7;
+		mOctaveScale[8] = aOct8;
+		mOctaveScale[9] = aOct9;
+	}
+
+	void Noise::setType(int aType)
+	{
+		switch (aType)
+		{
+		default:
+		case WHITE:
+			setOctaveScale(1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+			break;
+		case PINK:
+			setOctaveScale(1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
+			break;
+		case BROWNISH:
+			setOctaveScale(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+			break;
+		case BLUEISH:
+			setOctaveScale(10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
+			break;
+		}
+	}
+
+	Noise::Noise()
+	{
+		mBaseSamplerate = 44100;
+		setType(WHITE);
+	}
+
+	Noise::~Noise()
+	{
+		stop();
+	}
+
+
+	AudioSourceInstance * Noise::createInstance() 
+	{
+		return new NoiseInstance(this);
+	}
+
+};

+ 2 - 2
soloud.mod/soloud/src/audiosource/openmpt/soloud_openmpt.cpp

@@ -81,7 +81,7 @@ namespace SoLoud
 		mModfile = 0;
 	}
 
-	result Openmpt::loadMem(unsigned char *aMem, unsigned int aLength, bool aCopy, bool aTakeOwnership)
+	result Openmpt::loadMem(const unsigned char *aMem, unsigned int aLength, bool aCopy, bool aTakeOwnership)
 	{
 		MemoryFile mf;
 		int res = mf.openMem(aMem, aLength, aCopy, aTakeOwnership);
@@ -142,8 +142,8 @@ namespace SoLoud
 		if (mData)
 		{
 			delete[] mData;
+			mData = 0;
 		}
-		mData = 0;
 		mDataLen = 0;
 	}
 

+ 1 - 1
soloud.mod/soloud/src/audiosource/openmpt/soloud_openmpt_dll.c

@@ -46,7 +46,7 @@ static HMODULE openDll()
 
 static void* getDllProc(HMODULE aDllHandle, const char *aProcName)
 {
-	return GetProcAddress(aDllHandle, aProcName);
+	return (void*)GetProcAddress(aDllHandle, (LPCSTR)aProcName);
 }
 
 #elif defined(__vita__)

+ 1 - 32
soloud.mod/soloud/src/audiosource/sfxr/soloud_sfxr.cpp

@@ -31,37 +31,6 @@ freely, subject to the following restrictions:
 
 namespace SoLoud
 {
-
-	Prg::Prg()
-	{
-		srand(0);
-	}
-
-	void Prg::srand(int aSeed)
-	{
-		index = 0;
-		int i;
-		for (i = 0; i < 16; i++)
-			state[i] = aSeed + i * aSeed + i;
-	}
-
-	// WELL512 implementation, public domain by Chris Lomont
-	unsigned int Prg::rand()
-	{
-		unsigned int a, b, c, d;
-		a = state[index];
-		c = state[(index+13)&15];
-		b = a^c^(a<<16)^(c<<15);
-		c = state[(index+9)&15];
-		c ^= (c>>11);
-		a = state[index] = b^c;
-		d = a^((a<<5)&0xDA442D24UL);
-		index = (index + 15)&15;
-		a = state[index];
-		state[index] = a^b^d^(a<<2)^(b<<18)^(c<<28);
-		return state[index];
-	}
-
 	SfxrInstance::SfxrInstance(Sfxr *aParent)
 	{
 		mParent = aParent;
@@ -73,7 +42,7 @@ namespace SoLoud
 
 #define frnd(x) ((float)(mRand.rand()%10001)/10000*(x))
 
-	unsigned int SfxrInstance::getAudio(float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize)
+	unsigned int SfxrInstance::getAudio(float *aBuffer, unsigned int aSamplesToRead, unsigned int /*aBufferSize*/)
 	{
 		float *buffer = aBuffer;
 		unsigned int i;

+ 1 - 1
soloud.mod/soloud/src/audiosource/speech/darray.cpp

@@ -66,5 +66,5 @@ void darray::put(int aData)
 {
 	char *s = getDataInPos(mUsed);
 
-	*s = aData;
+	*s = (char)aData;
 }

+ 3 - 3
soloud.mod/soloud/src/audiosource/speech/klatt.cpp

@@ -807,7 +807,7 @@ int klatt::phone_to_elm(char *aPhoneme, int aCount, darray *aElement)
     than internal i.e. ext != 0 if 'a' is NOT current element.
  */
 
-static void set_trans(Slope *t, Element * a, Element * b,int ext, int e)
+static void set_trans(Slope *t, Element * a, Element * b,int ext, int /* e */)
 {
 	int i;
 
@@ -903,7 +903,7 @@ void klatt::initsynth(int aElementCount,unsigned char *aElement)
 	mStressE.mValue = 0.0;
 }
 
-int klatt::synth(int aSampleCount, short *aSamplePointer)
+int klatt::synth(int /* aSampleCount */, short *aSamplePointer)
 {
 	short *samp = aSamplePointer;
 
@@ -957,7 +957,6 @@ int klatt::synth(int aSampleCount, short *aSamplePointer)
 		{
 			float base = mTop * 0.8f; // 3 * top / 5 
 			float tp[ELM_COUNT];
-			int j;
 
 			if (mTStress == mNTStress)
 			{
@@ -999,6 +998,7 @@ int klatt::synth(int aSampleCount, short *aSamplePointer)
 				}
 			}
 
+			int j;
 			for (j = 0; j < ELM_COUNT; j++)
 			{
 				tp[j] = interpolate(&start[j], &end[j], (float) currentElement->mInterpolator[j].mSteady, t, dur);

+ 1 - 1
soloud.mod/soloud/src/audiosource/speech/soloud_speech.cpp

@@ -52,7 +52,7 @@ namespace SoLoud
 		}
 	}
 
-	unsigned int SpeechInstance::getAudio(float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize)
+	unsigned int SpeechInstance::getAudio(float *aBuffer, unsigned int aSamplesToRead, unsigned int /*aBufferSize*/)
 	{
 		mSynth.init(mParent->mBaseFrequency, mParent->mBaseSpeed, mParent->mBaseDeclination, mParent->mBaseWaveform);
 		unsigned int samples_out = 0;

Some files were not shown because too many files changed in this diff