├── utils ├── raw2wav ├── levelplay ├── README └── vlevel-dir ├── vlevel-winamp ├── vlevel_winamp.dsw ├── vlevel │ ├── vlevel.h │ ├── volumeleveler.h │ ├── volumeleveler.cpp │ └── lgpl.txt ├── dsp.h ├── readme.txt ├── vlevel_wrapper.h ├── vlevel_winamp.cpp ├── vlevel_winamp.dsp ├── vlevel_wrapper.cpp └── gpl.txt ├── TODO ├── INSTALL ├── .gitignore ├── volumeleveler ├── Makefile ├── volumeleveler.h └── volumeleveler.cpp ├── README.orig ├── vlevel-bin ├── commandline.h ├── Makefile ├── commandline.cpp └── vlevel-bin.cpp ├── vlevel-jack ├── commandline.h ├── Makefile ├── commandline.cpp └── vlevel-jack.cpp ├── docs ├── notes.txt └── technical.txt ├── vlevel-ladspa ├── Makefile ├── vlevel-ladspa.h ├── vlevel-ladspa.cpp └── ladspa.h ├── Makefile ├── README.md └── COPYING /utils/raw2wav: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | sox -raw -r44100 -s -w -c2 $1 `basename $1 .raw`.wav 4 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel_winamp.dsw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozlima/vlevel/master/vlevel-winamp/vlevel_winamp.dsw -------------------------------------------------------------------------------- /utils/levelplay: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # uses vlevel to play .ogg files named on the command line 3 | 4 | ogg123 -d raw -f - "$@" | vlevel-bin | artscat 5 | -------------------------------------------------------------------------------- /utils/README: -------------------------------------------------------------------------------- 1 | These are a few scripts I use to make VLeveling stuff easier. They 2 | mostly work on Ogg files, and use SOX. They are short and 3 | self-explanatory. 4 | -------------------------------------------------------------------------------- /utils/vlevel-dir: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir vlevel 4 | 5 | for i in *.ogg 6 | do 7 | sox $i -t raw - | vlevel-bin $@ | sox -t raw -r 44100 -c 2 -ws - vlevel/`basename $i .ogg`.wav 8 | done -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | More extensive testing, exotic channel config, feedback on other platforms 2 | 3 | Optimize for mono and stereo special cases 4 | - i tried this, and I couldn't do better than -O3 -march=pentium4 5 | - someone else can try their hand, but beware. 6 | 7 | Cool FXRuby GUI with SOX 8 | 9 | Hopefully usable Winamp plugin before next version. Yay! 10 | 11 | Rememember: when updating version, change in docs, readme, and vlevel-bin.cpp 12 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | VLevel 0.3 INSTALL 2 | 3 | VLevel is distributed as source code. To build it, type "make". To 4 | install it, login as root (type "su") and type "make install". 5 | 6 | You can change where it is installed by editing Makefile before doing 7 | the above. 8 | 9 | I test VLevel on a Linux system, but it should build on any similar 10 | system. It should compile on Windows, but it won't be very useful 11 | until I write a Ruby script with a nice cross-platform GUI and SOX 12 | integration. 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vlevel-bin/vlevel-bin 2 | vlevel-jack/vlevel-jack 3 | 4 | # Created by http://www.gitignore.io 5 | 6 | ### C ### 7 | # Object files 8 | *.o 9 | *.ko 10 | *.obj 11 | *.elf 12 | 13 | # Libraries 14 | *.lib 15 | *.a 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | 32 | ### OSX ### 33 | .DS_Store 34 | .AppleDouble 35 | .LSOverride 36 | 37 | # Icon must end with two \r 38 | Icon 39 | 40 | # Thumbnails 41 | ._* 42 | 43 | # Files that might appear on external disk 44 | .Spotlight-V100 45 | .Trashes 46 | 47 | # Directories potentially created on remote AFP share 48 | .AppleDB 49 | .AppleDesktop 50 | Network Trash Folder 51 | Temporary Items 52 | .apdisk 53 | 54 | autom4te.cache 55 | autoscan.log 56 | configure.ac 57 | configure.scan 58 | -------------------------------------------------------------------------------- /volumeleveler/Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of VLevel, a dynamic volume normalizer. 2 | # 3 | # Copyright 2003 Tom Felker 4 | # 5 | # This library is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as 7 | # published by the Free Software Foundation; either version 2.1 of the 8 | # License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | # USA 19 | 20 | .PHONY: all 21 | all: volumeleveler.o 22 | 23 | .PHONY: install 24 | install: all 25 | 26 | .PHONY: clean 27 | clean: 28 | -rm -f volumeleveler.o 29 | 30 | volumeleveler.o: volumeleveler.cpp volumeleveler.h 31 | 32 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel/vlevel.h: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // vlevel.h - included by all 21 | 22 | #ifndef VLEVEL_H 23 | #define VLEVEL_H 24 | 25 | // Float actually is slightly less accurate (900/65536 in my tests), 26 | // but is needed by LADSPA. 27 | 28 | typedef float value_t; 29 | 30 | #define VLEVEL_ABS(x) fabsf(x) 31 | 32 | // same speed as above 33 | //#define VLEVEL_ABS(x) ((x) > 0 ? (x) : -(x)) 34 | 35 | // a bit faster on 2.96, a bit slower(!) on 3.2 36 | //#define VLEVEL_ABS(x) (x) 37 | 38 | #endif // ndef VLEVEL_H 39 | -------------------------------------------------------------------------------- /README.orig: -------------------------------------------------------------------------------- 1 | VLevel 0.5 README 2 | 3 | What is VLevel? 4 | 5 | VLevel is a tool to amplify the soft parts of music so you don't 6 | have to fiddle with the volume control. It looks ahead a few 7 | seconds, so it can change the volume gradually without ever 8 | clipping. Because the volume is changed gradually, "dynamic 9 | contrast" is preserved. 10 | 11 | How do I install VLevel? 12 | 13 | See the file INSTALL. For the impatient: "sudo make install". 14 | 15 | How do I use VLevel? 16 | 17 | VLevel is a filter, meaning you pipe raw data to it, and it outputs 18 | the leveled data. For example: 19 | 20 | vlevel-bin < in.cdda > out.cdda 21 | 22 | There are options to control the length of the look-ahead buffer, 23 | the strength of the effect, and the maximum amplification, as well 24 | as the format of the raw data. Type "vlevel-bin --help" for 25 | details. 26 | 27 | VLevel also works as a LADSPA plugin. See http://www.ladspa.org for 28 | a lists of hosts that VLevel can plug into. 29 | 30 | What other features are planed? 31 | 32 | A Ruby cross-platform GUI drag-n-drop converter that uses SOX. 33 | 34 | Can I distribute VLevel? 35 | 36 | Please do. VLevel is licenced under the LGPL, for more information, 37 | see the COPYING file. 38 | 39 | Where can I get more info? 40 | 41 | There is documentation in the docs directory. News, new versions, 42 | contact info, help, and more are available from the website: 43 | 44 | http://vlevel.sourceforge.net 45 | -------------------------------------------------------------------------------- /vlevel-bin/commandline.h: -------------------------------------------------------------------------------- 1 | // This file is part of CommandLine, a C++ argument processing class. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // commandline.h 21 | // declares the CommandLine class 22 | 23 | #include 24 | #include 25 | 26 | //////////////////////// 27 | // note: ill rewrite this to use a list of strings 28 | 29 | class CommandLine { 30 | public: 31 | // argv is a pointer to a const pointer to a const char 32 | CommandLine(int argc, const char * const * argv); 33 | 34 | std::string GetProgramName(); 35 | std::string GetOption(); 36 | std::string GetArgument(); 37 | bool End() const; 38 | 39 | private: 40 | std::string program_name; 41 | std::stack args; 42 | bool in_short; 43 | bool cur_is_arg; 44 | bool no_more_options; 45 | }; 46 | -------------------------------------------------------------------------------- /vlevel-jack/commandline.h: -------------------------------------------------------------------------------- 1 | // This file is part of CommandLine, a C++ argument processing class. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // commandline.h 21 | // declares the CommandLine class 22 | 23 | #include 24 | #include 25 | 26 | //////////////////////// 27 | // note: ill rewrite this to use a list of strings 28 | 29 | class CommandLine { 30 | public: 31 | // argv is a pointer to a const pointer to a const char 32 | CommandLine(int argc, const char * const * argv); 33 | 34 | std::string GetProgramName(); 35 | std::string GetOption(); 36 | std::string GetArgument(); 37 | bool End() const; 38 | 39 | private: 40 | std::string program_name; 41 | std::stack args; 42 | bool in_short; 43 | bool cur_is_arg; 44 | bool no_more_options; 45 | }; 46 | -------------------------------------------------------------------------------- /docs/notes.txt: -------------------------------------------------------------------------------- 1 | VLevel 0.3 notes.txt 2 | 3 | Channels 4 | 5 | VLevel abstracts audio into samples, each of which has as many 6 | values as there are channels, and most of the functions confusingly 7 | accept length in samples, but work on arrays of length (samples * 8 | values) doubles. 9 | 10 | You'd think this would be inneficient, but it's not. I tried 11 | changing the code to just work on arrays of double (which would only 12 | affect the lowest order bits, except for very short look-ahead), and 13 | it was actually a bit slower. 14 | 15 | I think the reason for this is that although when using channels, 16 | there is much more integer math and 2-iteration for loops, it means 17 | that the expensive slope calculation (not the whole search, but each 18 | slope = dy / dx) only has to be done half (1 / channels) as often. 19 | 20 | The moral is: channels aren't inneficient, don't waste your time 21 | abolishing them. Floating-point probably is, but fixed point may be 22 | even more ugly. 23 | 24 | The code currently allows for different functions to be called 25 | depending on the number of channels. For now, the generic code that 26 | works for any number of channels is fine, but speed optimization may 27 | be possible in the common mono and stereo cases. 28 | 29 | 30 | GCC Versions 31 | 32 | I discovered that while GCC 3.2 generates faster code than GCC 2.96, 33 | it's iostream implementation is slower by two orders of magnitude. 34 | I've changed the code to use FILE*, which is fast in either version, 35 | but that's ugly. I haven't tried other platforms or versions, but I 36 | see no reason they wouldn't work. 37 | -------------------------------------------------------------------------------- /vlevel-winamp/dsp.h: -------------------------------------------------------------------------------- 1 | // DSP plugin interface 2 | 3 | // notes: 4 | // any window that remains in foreground should optimally pass unused 5 | // keystrokes to the parent (winamp's) window, so that the user 6 | // can still control it. As for storing configuration, 7 | // Configuration data should be stored in \plugin.ini 8 | // (look at the vis plugin for configuration code) 9 | 10 | #ifndef INCLUDED_DSP_H 11 | #define INCLUDED_DSP_H 12 | 13 | typedef struct winampDSPModule { 14 | char *description; // description 15 | HWND hwndParent; // parent window (filled in by calling app) 16 | HINSTANCE hDllInstance; // instance handle to this DLL (filled in by calling app) 17 | 18 | void (*Config)(struct winampDSPModule *this_mod); // configuration dialog (if needed) 19 | int (*Init)(struct winampDSPModule *this_mod); // 0 on success, creates window, etc (if needed) 20 | 21 | // modify waveform samples: returns number of samples to actually write 22 | // (typically numsamples, but no more than twice numsamples, and no less than half numsamples) 23 | // numsamples should always be at least 128. should, but I'm not sure 24 | int (*ModifySamples)(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate); 25 | 26 | void (*Quit)(struct winampDSPModule *this_mod); // called when unloading 27 | 28 | void *userData; // user data, optional 29 | } winampDSPModule; 30 | 31 | typedef struct { 32 | int version; // DSP_HDRVER 33 | char *description; // description of library 34 | winampDSPModule* (*getModule)(int); // module retrieval function 35 | } winampDSPHeader; 36 | 37 | // exported symbols 38 | typedef winampDSPHeader* (*winampDSPGetHeaderType)(); 39 | 40 | // header version: 0x20 == 0.20 == winamp 2.0 41 | #define DSP_HDRVER 0x20 42 | 43 | #endif //#ifndef INCLUDED_DSP_H -------------------------------------------------------------------------------- /vlevel-winamp/readme.txt: -------------------------------------------------------------------------------- 1 | vlevel winamp plugin 0.1 2 | Copyright (C) 2003 Markus Sablatnig 3 | 4 | This program is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU General Public License 6 | as published by the Free Software Foundation; either version 2 7 | of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | 18 | 19 | vlevel 20 | ====== 21 | A big part of this software is the vlevel-library. VLevel is a dynamic compressor which amplifies the quiet parts of music. It uses a look-ahead buffer, so the changes are gradual and the audio never clips. 22 | VLevel was written by Tom Felker and is distributed under the Terms of the GNU Lesser General Public License(lGPL). 23 | More information at: www.sf.net/projects/vlevel 24 | 25 | 26 | What does this plugin do? 27 | ========================= 28 | It brings the benefits of vLevel to Nullsoft WinAmp. 29 | 30 | 31 | Basics 32 | ====== 33 | Version: Winamp2 or higher 34 | Platform: Win32 35 | License: GPL 36 | 37 | 38 | Todo 39 | ==== 40 | - test conversion function in wrapper class 41 | - add config-dialog resource 42 | - save/restore values to/from registry(or ini) on init/quit 43 | - write installer/uninstaller 44 | - maybe skinning support? 45 | 46 | Done 47 | ==== 48 | - DLL framework 49 | - wrapper class 50 | - reorder project files (use ..\volumeleveler; directory structure; ...) 51 | 52 | -------------------------------------------------------------------------------- /vlevel-bin/Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of VLevel, a dynamic volume normalizer. 2 | # 3 | # Copyright 2003 Tom Felker 4 | # 5 | # This library is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as 7 | # published by the Free Software Foundation; either version 2.1 of the 8 | # License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | # USA 19 | 20 | # This is evil, but it makes implicit link rules use g++, not gcc 21 | CC = $(CXX) 22 | 23 | .PHONY: all 24 | all: vlevel-bin 25 | 26 | .PHONY: install 27 | install: all 28 | cp -f vlevel-bin $(PREFIX)/bin/ 29 | 30 | .PHONY: clean 31 | clean: 32 | -rm -f *.o vlevel-bin 33 | 34 | # This isn't ideal - if ../volumeleveler/volumeleveler.cpp was changed, 35 | # but make wasn't yet run there, then the .o file won't be new, so 36 | # the project will be improperly built. Also, if volumeleveler.o doesn't 37 | # exist yet, then make won't build it. Unfortunately, it's discouraged 38 | # to make it a .PHONY, and besides, that causes relinking every time 39 | # make is run here, even during install (which leaves root's files). 40 | # Make sucks. 41 | 42 | ../volumeleveler/volumeleveler.o: 43 | $(MAKE) -C ../volumeleveler all 44 | 45 | vlevel-bin: vlevel-bin.o \ 46 | commandline.o \ 47 | ../volumeleveler/volumeleveler.o 48 | 49 | vlevel-bin.o: vlevel-bin.cpp \ 50 | commandline.h \ 51 | ../volumeleveler/volumeleveler.h \ 52 | 53 | commandline.o: commandline.cpp commandline.h 54 | -------------------------------------------------------------------------------- /vlevel-ladspa/Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of VLevel, a dynamic volume normalizer. 2 | # 3 | # Copyright 2003 Tom Felker 4 | # 5 | # This library is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as 7 | # published by the Free Software Foundation; either version 2.1 of the 8 | # License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | # USA 19 | 20 | # This is evil, but it makes implicit link rules use g++, not gcc 21 | CC = $(CXX) 22 | 23 | .PHONY: all 24 | all: vlevel-ladspa.so 25 | 26 | .PHONY: install 27 | install: all 28 | cp -f vlevel-ladspa.so $(LADSPA_PATH)/ 29 | 30 | .PHONY: clean 31 | clean: 32 | -rm -f *.o vlevel-ladspa.so 33 | 34 | # This isn't ideal - if ../volumeleveler/volumeleveler.cpp was changed, 35 | # but make wasn't yet run there, then the .o file won't be new, so 36 | # the project will be improperly built. Also, if volumeleveler.o doesn't 37 | # exist yet, then make won't build it. Unfortunately, it's discouraged 38 | # to make it a .PHONY, and besides, that causes relinking every time 39 | # make is run here, even during install (which leaves root's files). 40 | # Make sucks. 41 | 42 | ../volumeleveler/volumeleveler.o: 43 | $(MAKE) -C ../volumeleveler all 44 | 45 | vlevel-ladspa.so: vlevel-ladspa.o ../volumeleveler/volumeleveler.o 46 | $(CXX) $(CXXFLAGS) -shared -o vlevel-ladspa.so vlevel-ladspa.o ../volumeleveler/volumeleveler.o 47 | 48 | 49 | vlevel-ladspa.o: vlevel-ladspa.cpp \ 50 | vlevel-ladspa.h \ 51 | ladspa.h \ 52 | ../volumeleveler/volumeleveler.h \ 53 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of VLevel, a dynamic volume normalizer. 2 | # 3 | # Copyright 2003 Tom Felker 4 | # 5 | # This library is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as 7 | # published by the Free Software Foundation; either version 2.1 of the 8 | # License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | # USA 19 | 20 | # User-editable options: 21 | 22 | # Change this to suit your preferences (maybe add -march=cputype) 23 | 24 | # This is what works fastest with GCC on my system 25 | # 26 | # I'd be interested to see how setting -DEXPECT impacts performance - 27 | # on my system, it makes it a bit worse. 28 | 29 | export VERSION = 0.5.2 30 | 31 | #export CXXFLAGS = -Wall -O3 -fPIC -DPIC -g -march=pentium4 32 | export CXXFLAGS += -Wall -O3 -fPIC -DPIC -DVLEVEL_VERSION=\"$(VERSION)\" 33 | 34 | # On my system, ICC is quite a bit faster, with these options: 35 | #export CC=icc 36 | #export CXX=icc 37 | #export LD=icc 38 | #export CXXFLAGS = -fPIC -DPIC -g -O3 -rcd 39 | 40 | # This is where it will be installed 41 | export DESTDIR := / 42 | export PREFIX = $(DESTDIR)/usr/ 43 | export LADSPA_PATH = $(PREFIX)/lib/ladspa/ 44 | 45 | # End of user-editable options. 46 | 47 | export CC = $(CXX) 48 | 49 | .PHONY: all install clean 50 | 51 | all: 52 | $(MAKE) -C volumeleveler all 53 | $(MAKE) -C vlevel-bin all 54 | $(MAKE) -C vlevel-ladspa all 55 | $(MAKE) -C vlevel-jack all 56 | 57 | install: all 58 | $(MAKE) -C volumeleveler install 59 | $(MAKE) -C vlevel-bin install 60 | $(MAKE) -C vlevel-ladspa install 61 | $(MAKE) -C vlevel-jack install 62 | 63 | clean: 64 | $(MAKE) -C volumeleveler clean 65 | $(MAKE) -C vlevel-bin clean 66 | $(MAKE) -C vlevel-ladspa clean 67 | $(MAKE) -C vlevel-jack clean 68 | -------------------------------------------------------------------------------- /vlevel-jack/Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of VLevel, a dynamic volume normalizer. 2 | # 3 | # Copyright 2003 Tom Felker 4 | # 5 | # This library is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU Lesser General Public License as 7 | # published by the Free Software Foundation; either version 2.1 of the 8 | # License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | # USA 19 | 20 | PKG_CONFIG ?= pkg-config 21 | 22 | CC = $(CXX) 23 | CXXFLAGS += $(shell $(PKG_CONFIG) --cflags jack) 24 | LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L jack) 25 | LDLIBS += $(shell $(PKG_CONFIG) --libs-only-l jack) 26 | 27 | # commented out rules were used to build it on OSX (yes, it works) 28 | #LDFLAGS = -L/opt/local/lib 29 | #LDLIBS = -ljack -lpthread -framework CoreAudio -framework CoreServices -framework AudioUnit 30 | #CXXFLAGS= -I/opt/local/include -g -v 31 | 32 | .PHONY: all 33 | all: vlevel-jack 34 | 35 | .PHONY: install 36 | install: all 37 | cp -f vlevel-jack $(PREFIX)/bin/ 38 | 39 | .PHONY: clean 40 | clean: 41 | -rm -f *.o vlevel-jack 42 | 43 | # This isn't ideal - if ../volumeleveler/volumeleveler.cpp was changed, 44 | # but make wasn't yet run there, then the .o file won't be new, so 45 | # the project will be improperly built. Also, if volumeleveler.o doesn't 46 | # exist yet, then make won't build it. Unfortunately, it's discouraged 47 | # to make it a .PHONY, and besides, that causes relinking every time 48 | # make is run here, even during install (which leaves root's files). 49 | # Make sucks. 50 | 51 | ../volumeleveler/volumeleveler.o: 52 | $(MAKE) -C ../volumeleveler all 53 | 54 | vlevel-jack: vlevel-jack.o \ 55 | commandline.o \ 56 | ../volumeleveler/volumeleveler.o 57 | 58 | vlevel-jack.o: vlevel-jack.cpp \ 59 | commandline.h \ 60 | ../volumeleveler/volumeleveler.h \ 61 | 62 | commandline.o: commandline.cpp commandline.h 63 | -------------------------------------------------------------------------------- /vlevel-ladspa/vlevel-ladspa.h: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // vlevel-ladspa.h - for the LADSPA plugin 21 | 22 | #ifndef VLEVEL_LADSPA_H 23 | #define VLEVEL_LADSPA_H 24 | 25 | #include 26 | 27 | #include "../volumeleveler/volumeleveler.h" 28 | 29 | #include "ladspa.h" 30 | 31 | typedef LADSPA_Data value_t; 32 | 33 | #define CONTROL_PORT_COUNT 6 34 | 35 | #define CONTROL_PORT_LOOK_AHEAD 0 36 | #define CONTROL_PORT_STRENGTH 1 37 | #define CONTROL_PORT_USE_MAX_MULTIPLIER 2 38 | #define CONTROL_PORT_MAX_MULTIPLIER 3 39 | #define CONTROL_PORT_UNDO 4 40 | #define CONTROL_PORT_OUTPUT_MULTIPLIER 5 41 | #define AUDIO_PORT_INPUT_1 6 42 | #define AUDIO_PORT_OUTPUT_1 7 43 | #define AUDIO_PORT_INPUT_2 8 44 | #define AUDIO_PORT_OUTPUT_2 9 45 | 46 | #define UID_MONO 1981 47 | #define UID_STEREO 1982 48 | 49 | class VLevelInstance { 50 | public: 51 | VLevelInstance(size_t channels, unsigned long rate); 52 | ~VLevelInstance(); 53 | void ConnectPort(unsigned long port, value_t *data_location); 54 | void Activate(); 55 | void Run(unsigned long sample_count); 56 | void Deactivate(); 57 | private: 58 | VolumeLeveler vl; 59 | size_t nch; 60 | value_t **ports; 61 | value_t **in; 62 | value_t **out; 63 | unsigned long sample_rate; 64 | }; 65 | 66 | LADSPA_Handle Instantiate(const LADSPA_Descriptor *descriptor, unsigned long sample_rate); 67 | void ConnectPort(LADSPA_Handle instance, unsigned long port, value_t *data_location); 68 | void Activate(LADSPA_Handle instance); 69 | void Run(LADSPA_Handle instance, unsigned long sample_count); 70 | void Deactivate(LADSPA_Handle instance); 71 | void Cleanup(LADSPA_Handle instance); 72 | 73 | #endif // ndef VLEVEL_LADSPA_H 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VLevel 2 | 3 | ## What is VLevel? 4 | 5 | VLevel is a tool to amplify the soft parts of music so you don't 6 | have to fiddle with the volume control. It looks ahead a few 7 | seconds, so it can change the volume gradually without ever 8 | clipping. Because the volume is changed gradually, "dynamic 9 | contrast" is preserved. 10 | 11 | **This repository is a fork of the original vlevel code** since the 12 | last release of the [original source](http://vlevel.sourceforge.net/) 13 | is from 2004. Although this, the code is robust and it works pretty 14 | much unmodified nowadays. We imported from the 15 | [old CVS repository](http://vlevel.cvs.sourceforge.net/viewvc/vlevel/vlevel/) 16 | and added a new module in order to use it as a JACK client. After 17 | several months of test in a working production (a 24/7 broadcasting 18 | environment) we can confirm that the software is reliable. 19 | 20 | ## What are the supported platforms? 21 | 22 | We know VLevel to work in Linux and OSX environments. At this moment 23 | we cannot test it on other platforms, but we encourage you to 24 | collaborate. 25 | 26 | ## How do I install VLevel? 27 | 28 | See the file [INSTALL](INSTALL). For the impatient: `sudo make install` 29 | 30 | ## How do I use VLevel? 31 | 32 | Original VLevel is a filter, meaning you pipe raw CDDA 33 | ([Compact Disc Digital Audio](https://en.wikipedia.org/wiki/Compact_Disc_Digital_Audio)) 34 | data to it, and it outputs the leveled data. 35 | 36 | Example: 37 | 38 | vlevel-bin < in.cdda > out.cdda 39 | 40 | There are options to control the length of the look-ahead buffer, 41 | the strength of the effect, and the maximum amplification, as well 42 | as the format of the raw data. Type `vlevel-bin --help` for 43 | details. 44 | 45 | VLevel works also as a 46 | [JACK Audio Connection Kit](http://jackaudio.org/) client. 47 | 48 | For example 49 | 50 | vlevel-jack --length 22050 --max-multiplier 20 --strength 0.8 51 | 52 | will create 2 capture ports and 2 playback ports on the JACK graph 53 | that can be used in combination with any other JACK client. 54 | 55 | VLevel also works as a LADSPA plugin. See the 56 | [Linux Audio Developer's Simple Plugin API website](http://www.ladspa.org/) 57 | for a lists of hosts that VLevel can plug into. 58 | 59 | ## What other features are planed? 60 | 61 | a Lv2 Plugin and a GUI (especially for vlevel-jack) 62 | 63 | ## Can I distribute VLevel? 64 | 65 | Please do. VLevel is licenced under the GNU Lesser General Public 66 | License (LGPL), for more information, see the [COPYING](COPYING) file. 67 | 68 | ## Where can I get more info? 69 | 70 | There is documentation in the [docs](docs/) directory. Documentation, 71 | help, and more are also available from the 72 | [original project's website](http://vlevel.sourceforge.net/). 73 | 74 | Also support http://www.radiocicletta.it/, our beloved webradio :3 75 | -------------------------------------------------------------------------------- /vlevel-bin/commandline.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of CommandLine, a C++ argument processing class. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // commandline.cpp 21 | // defines the CommandLine class 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "commandline.h" 30 | 31 | using namespace std; 32 | 33 | // argv is a pointer to a const pointer to a const char 34 | CommandLine::CommandLine(int argc, const char * const * argv) 35 | { 36 | if(argc < 1) throw out_of_range("CommandLine::CommandLine(): argc < 1"); 37 | for(int i = argc - 1; i > 0; --i) args.push(argv[i]); 38 | in_short = false; 39 | cur_is_arg = false; 40 | no_more_options = false; 41 | program_name = argv[0]; 42 | } 43 | 44 | string CommandLine::GetOption() 45 | { 46 | if(no_more_options || args.empty()) return ""; 47 | if(cur_is_arg) { 48 | cerr << "ignoring an argument" << endl; 49 | args.pop(); 50 | if(args.empty()) return ""; 51 | } 52 | while(true) { 53 | if(args.top().empty()) { 54 | args.pop(); 55 | if(args.empty()) return ""; 56 | in_short = false; 57 | } else { 58 | break; 59 | } 60 | } 61 | if(in_short) { 62 | string retval(args.top().substr(0, 1)); 63 | args.top().erase(0, 1); 64 | return retval; 65 | } 66 | if(args.top() == "--") { 67 | no_more_options = true; 68 | args.pop(); 69 | return ""; 70 | } 71 | if(args.top().substr(0,2) == "--") { 72 | args.top().erase(0, 2); 73 | size_t eq_pos = args.top().find("="); 74 | string retval(args.top().substr(0, eq_pos)); 75 | args.top().erase(0, eq_pos); 76 | if(args.top().empty()) { 77 | args.pop(); 78 | } else { 79 | args.top().erase(0, 1); 80 | cur_is_arg = true; 81 | } 82 | return retval; 83 | } 84 | 85 | if(args.top() == "-") return ""; 86 | 87 | if(args.top().substr(0, 1) == "-") { 88 | args.top().erase(0, 1); 89 | in_short = true; 90 | string retval(args.top().substr(0, 1)); 91 | args.top().erase(0, 1); 92 | if(args.top().empty()) args.pop(); 93 | return retval; 94 | } 95 | 96 | return ""; 97 | } 98 | 99 | string CommandLine::GetArgument() 100 | { 101 | if(args.empty()) return ""; 102 | string retval = args.top(); 103 | if(!cur_is_arg && retval == "--") { 104 | args.pop(); 105 | if(args.empty()) return ""; 106 | retval = args.top(); 107 | } 108 | args.pop(); 109 | cur_is_arg = false; 110 | in_short = false; 111 | return retval; 112 | } 113 | 114 | string CommandLine::GetProgramName() 115 | { 116 | return program_name; 117 | } 118 | 119 | bool CommandLine::End() const { 120 | return args.empty(); 121 | } 122 | -------------------------------------------------------------------------------- /vlevel-jack/commandline.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of CommandLine, a C++ argument processing class. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // commandline.cpp 21 | // defines the CommandLine class 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "commandline.h" 30 | 31 | using namespace std; 32 | 33 | // argv is a pointer to a const pointer to a const char 34 | CommandLine::CommandLine(int argc, const char * const * argv) 35 | { 36 | if(argc < 1) throw out_of_range("CommandLine::CommandLine(): argc < 1"); 37 | for(int i = argc - 1; i > 0; --i) args.push(argv[i]); 38 | in_short = false; 39 | cur_is_arg = false; 40 | no_more_options = false; 41 | program_name = argv[0]; 42 | } 43 | 44 | string CommandLine::GetOption() 45 | { 46 | if(no_more_options || args.empty()) return ""; 47 | if(cur_is_arg) { 48 | cerr << "ignoring an argument" << endl; 49 | args.pop(); 50 | if(args.empty()) return ""; 51 | } 52 | while(true) { 53 | if(args.top().empty()) { 54 | args.pop(); 55 | if(args.empty()) return ""; 56 | in_short = false; 57 | } else { 58 | break; 59 | } 60 | } 61 | if(in_short) { 62 | string retval(args.top().substr(0, 1)); 63 | args.top().erase(0, 1); 64 | return retval; 65 | } 66 | if(args.top() == "--") { 67 | no_more_options = true; 68 | args.pop(); 69 | return ""; 70 | } 71 | if(args.top().substr(0,2) == "--") { 72 | args.top().erase(0, 2); 73 | size_t eq_pos = args.top().find("="); 74 | string retval(args.top().substr(0, eq_pos)); 75 | args.top().erase(0, eq_pos); 76 | if(args.top().empty()) { 77 | args.pop(); 78 | } else { 79 | args.top().erase(0, 1); 80 | cur_is_arg = true; 81 | } 82 | return retval; 83 | } 84 | 85 | if(args.top() == "-") return ""; 86 | 87 | if(args.top().substr(0, 1) == "-") { 88 | args.top().erase(0, 1); 89 | in_short = true; 90 | string retval(args.top().substr(0, 1)); 91 | args.top().erase(0, 1); 92 | if(args.top().empty()) args.pop(); 93 | return retval; 94 | } 95 | 96 | return ""; 97 | } 98 | 99 | string CommandLine::GetArgument() 100 | { 101 | if(args.empty()) return ""; 102 | string retval = args.top(); 103 | if(!cur_is_arg && retval == "--") { 104 | args.pop(); 105 | if(args.empty()) return ""; 106 | retval = args.top(); 107 | } 108 | args.pop(); 109 | cur_is_arg = false; 110 | in_short = false; 111 | return retval; 112 | } 113 | 114 | string CommandLine::GetProgramName() 115 | { 116 | return program_name; 117 | } 118 | 119 | bool CommandLine::End() const { 120 | return args.empty(); 121 | } 122 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel_wrapper.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // vlevel_wrapper.h - this file is part of vlevel winamp plugin 0.1 4 | // Copyright (C) 2003 Markus Sablatnig 5 | // Copyright (C) 2003 Tom Felker 6 | // 7 | // This program is free software; you can redistribute it and/or 8 | // modify it under the terms of the GNU General Public License 9 | // as published by the Free Software Foundation; either version 2 10 | // of the License, or (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program; if not, write to the Free Software 19 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | // 21 | /////////////////////////////////////////////////////////////////////////////// 22 | 23 | #ifndef INCLUDED_VLEVEL_WRAPPER_H 24 | #define INCLUDED_VLEVEL_WRAPPER_H 25 | 26 | // This is now the only volumeleveler header 27 | #include "..\\volumeleveler\\volumeleveler.h" 28 | 29 | // This class is a wrapper for VolumeLeveler. 30 | // It caches some settings and de-/interlaces 31 | // Exchange()'s in and output buffers 32 | class CVLWrapper 33 | { 34 | public: 35 | CVLWrapper(); 36 | ~CVLWrapper(); 37 | 38 | //these automatically mark the values as 'changed' 39 | inline void SetCachedChannels(size_t channels); // at least 1 40 | inline void SetCachedStrength(value_t v_strength); // 0.0 to 1.0 41 | inline void SetCachedMaxMultiplier(value_t v_maxMultiplier); // negative for no limit 42 | 43 | // these affect the internal representation of ms_samples 44 | inline void SetCachedLength(value_t v_length); // in seconds 45 | inline void SetCachedRate(size_t s_rate); // in Hz 46 | 47 | //these Get functions might be useful 48 | inline size_t GetCachedChannels() { return ms_channels; }; 49 | inline value_t GetCachedStrength() { return mv_strength; }; 50 | inline value_t GetCachedMaxMultiplier() { return mv_maxMultiplier; }; 51 | 52 | inline value_t GetCachedLength() { return mv_length; }; 53 | inline size_t GetCachedRate() { return ms_rate; }; 54 | inline size_t GetCachedSamples() { return ms_samples; }; 55 | 56 | // write cached values to the wrapped object 57 | // This is called automatically in Exchange() 58 | inline void CacheFlush( void ); 59 | 60 | // Exchange() handles it's own de- and re-interlacing and CacheFlush()s. 61 | // Each sample has nch values - just use the same convention as Winamp and VLevel. 62 | int Exchange(void *samples, int numsamples, int bps, int nch, int rate); 63 | 64 | 65 | private: 66 | 67 | // Instead of setting this directly, use SetLength() and SetRate(). 68 | inline void SetCachedSamples( size_t s_samples ); 69 | 70 | // main object 71 | VolumeLeveler* mpvl_wrapped; 72 | 73 | // cached values 74 | size_t ms_samples; 75 | size_t ms_channels; 76 | value_t mv_strength; 77 | value_t mv_maxMultiplier; 78 | 79 | // ms_samples is recomputed when these are changed. 80 | value_t mv_length; 81 | size_t ms_rate; 82 | 83 | // Using change flags is faster and more accurate. 84 | // It can cause unnecessary flushes when rate and length are changed inversely, 85 | // but perfect is the enemy of good in this case. 86 | bool mb_samplesOrChannelsChanged; 87 | bool mb_strengthChanged; 88 | bool mb_maxMultiplierChanged; 89 | 90 | }; //CVLWrapper 91 | 92 | #endif //#ifndef VLEVEL_WRAPPER_H 93 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel/volumeleveler.h: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // volumeleveler.h - declares the VolumeLeveler class 21 | // 22 | // A note on terminology: atoms are indivual value_t values; samples 23 | // are one or more atoms, for example, for stereo, a sample has 2 24 | // atoms, and channels is 2. 25 | 26 | #ifndef VOLUMELEVELER_H 27 | #define VOLUMELEVELER_H 28 | 29 | #include 30 | 31 | #include "vlevel.h" 32 | 33 | class VolumeLeveler { 34 | public: 35 | 36 | // constructs and destructs a VolumeLeveler with a length of l 37 | // samples with c channels each, an effect strength of s and a 38 | // maximum multiplier of m 39 | VolumeLeveler(size_t l = 44100, size_t c = 2, value_t s = .8, value_t m = 25); 40 | ~VolumeLeveler(); 41 | 42 | // Reallocates a buffer of l samples and c channels (contents are 43 | // lost) 44 | void SetSamplesAndChannels(size_t l, size_t c); 45 | 46 | // set and get the strength (between 0 and 1) (set doesn't affect 47 | // the buffer) if undo is true, vlevel will do the exact opposite, 48 | // so you can remove a vlevel. 49 | void SetStrength(value_t s); 50 | 51 | // set and get the max multiplier (set doesn't affect the buffer) 52 | void SetMaxMultiplier(value_t m); 53 | 54 | // get stuff 55 | inline size_t GetSamples() { return samples; }; 56 | inline size_t GetChannels() { return channels; }; 57 | inline value_t GetStrength() { return strength; }; 58 | inline value_t GetMaxMultiplier() { return max_multiplier; }; 59 | inline size_t GetSilence() { return silence; }; 60 | 61 | // get stats 62 | value_t GetMultiplier(); 63 | 64 | // fills the buffers with silence 65 | void Flush(); 66 | 67 | // replaces raw with processed, returns how many samples are 68 | // residual silence from when the buffers were empty. 69 | size_t Exchange(value_t **in_buf, value_t **out_buf, size_t in_samples); 70 | 71 | private: 72 | 73 | //void Exchange_1(value_t **in_buf, value_t **out_buf, size_t in_samples); 74 | //void Exchange_2(value_t **in_buf, value_t **out_buf, size_t in_samples); 75 | void Exchange_n(value_t **in_buf, value_t **out_buf, size_t in_samples); 76 | 77 | // the buffer 78 | value_t **bufs; 79 | 80 | // the length of the buffers 81 | size_t samples; 82 | 83 | // the number of channels 84 | size_t channels; 85 | 86 | // the strength of the effect (between 0 and 1) 87 | value_t strength; 88 | 89 | // the maximum value by which a sample will be scaled 90 | value_t max_multiplier; 91 | 92 | // the amount of silence (data that wasn't input) left in the buffer (samples). 93 | size_t silence; 94 | 95 | // position about to be returned (samples) 96 | size_t pos; 97 | 98 | // position of the max slope (samples) 99 | size_t max_slope_pos; 100 | 101 | // the current "blanket" amplitude 102 | value_t avg_amp; 103 | 104 | // the maximum slope 105 | value_t max_slope; 106 | 107 | // the value at the maximum slope 108 | value_t max_slope_val; 109 | 110 | }; 111 | 112 | #endif // ndef VOLUMELEVELER_H 113 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel_winamp.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // vlevel_winamp.cpp - this file is part of vlevel winamp plugin 0.1 4 | // Copyright (C) 2003 Markus Sablatnig 5 | // 6 | // This program is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU General Public License 8 | // as published by the Free Software Foundation; either version 2 9 | // of the License, or (at your option) any later version. 10 | // 11 | // This program is distributed in the hope that it will be useful, 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | // GNU General Public License for more details. 15 | // 16 | // You should have received a copy of the GNU General Public License 17 | // along with this program; if not, write to the Free Software 18 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 | // 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | #include 25 | #include 26 | #include "dsp.h" 27 | #include "vlevel_wrapper.h" 28 | 29 | // avoid stupid CRT silliness 30 | BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) 31 | { 32 | return TRUE; 33 | } 34 | 35 | // module getter. 36 | winampDSPModule *getModule(int which); 37 | 38 | void config(struct winampDSPModule *this_mod); 39 | int init(struct winampDSPModule *this_mod); 40 | void quit(struct winampDSPModule *this_mod); 41 | int modify_samples(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate); 42 | 43 | // Module header, includes version, description, and address of the module retriever function 44 | winampDSPHeader hdr = { DSP_HDRVER, "VLevel-Winamp v0.2 - an automatic volume leveler", getModule }; 45 | 46 | // first module 47 | winampDSPModule mod = 48 | { 49 | "VLevel-Winamp v0.2", 50 | NULL, // hwndParent 51 | NULL, // hDllInstance 52 | config, 53 | init, 54 | modify_samples, 55 | quit 56 | }; 57 | 58 | #ifdef __cplusplus 59 | extern "C" { 60 | #endif 61 | // this is the only exported symbol. returns our main header. 62 | __declspec( dllexport ) winampDSPHeader *winampDSPGetHeader2() 63 | { 64 | return &hdr; 65 | } 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | 71 | winampDSPModule *getModule(int which) 72 | { 73 | if( which == 0 ) 74 | return &mod; 75 | else 76 | return NULL; 77 | } 78 | 79 | void config(struct winampDSPModule *this_mod) 80 | { 81 | // TODO: Code this. 82 | MessageBox(this_mod->hwndParent,"Not implemented.", "TestMsg",MB_OK); 83 | } 84 | 85 | int init(struct winampDSPModule *this_mod) 86 | { 87 | CVLWrapper* pvlw_userData = 0; 88 | 89 | try 90 | { 91 | pvlw_userData = new CVLWrapper; 92 | if( !pvlw_userData ) 93 | return 1; 94 | this_mod->userData = static_cast(pvlw_userData); 95 | 96 | // TODO: read values from the ini file. 97 | // dsp.h says configuration data should be stored in \plugin.ini 98 | 99 | }//try 100 | catch(...) 101 | { 102 | if( pvlw_userData ) 103 | delete pvlw_userData; 104 | this_mod->userData = pvlw_userData = 0; 105 | 106 | return 1; 107 | }//catch 108 | 109 | return 0; 110 | } 111 | 112 | void quit(struct winampDSPModule *this_mod) 113 | { 114 | if( this_mod->userData ) 115 | delete this_mod->userData; 116 | this_mod->userData = 0; 117 | }//quit 118 | 119 | int modify_samples(struct winampDSPModule *this_mod, short int *samples, int numsamples, int bps, int nch, int srate) 120 | { 121 | assert(this_mod && this_mod->userData); 122 | return ((CVLWrapper *)(this_mod->userData))->Exchange((void *)samples, numsamples, bps, nch, srate); 123 | } 124 | 125 | // TODO: ...but maybe impossible. 126 | // We could elimate the delay caused by seeking if we flushed VLevel's internal buffer 127 | // before seeking. So if there's a way to intercept a seek, set a flag, and flush 128 | // the VolumeLeveler on the next modify_samples, it would be better. 129 | 130 | // TODO: ...but almost certainly impossible. 131 | // I think there will be an issue with the last buffer-ful of the song being discarded. 132 | // We can eliminate this if there was a way to instruct the host to call modify_samples 133 | // until it returns zero. I can dream, can't I? 134 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel_winamp.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="vlevel_winamp" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 6 | 7 | CFG=vlevel_winamp - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "vlevel_winamp.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "vlevel_winamp.mak" CFG="vlevel_winamp - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "vlevel_winamp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") 21 | !MESSAGE "vlevel_winamp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | MTL=midl.exe 30 | RSC=rc.exe 31 | 32 | !IF "$(CFG)" == "vlevel_winamp - Win32 Release" 33 | 34 | # PROP BASE Use_MFC 0 35 | # PROP BASE Use_Debug_Libraries 0 36 | # PROP BASE Output_Dir "Release" 37 | # PROP BASE Intermediate_Dir "Release" 38 | # PROP BASE Target_Dir "" 39 | # PROP Use_MFC 0 40 | # PROP Use_Debug_Libraries 0 41 | # PROP Output_Dir "Release" 42 | # PROP Intermediate_Dir "Release" 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VLEVEL_WINAMP_EXPORTS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VLEVEL_WINAMP_EXPORTS" /YX /FD /c 46 | # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 47 | # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 48 | # ADD BASE RSC /l 0xc07 /d "NDEBUG" 49 | # ADD RSC /l 0xc07 /d "NDEBUG" 50 | BSC32=bscmake.exe 51 | # ADD BASE BSC32 /nologo 52 | # ADD BSC32 /nologo 53 | LINK32=link.exe 54 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 55 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 56 | 57 | !ELSEIF "$(CFG)" == "vlevel_winamp - Win32 Debug" 58 | 59 | # PROP BASE Use_MFC 0 60 | # PROP BASE Use_Debug_Libraries 1 61 | # PROP BASE Output_Dir "Debug" 62 | # PROP BASE Intermediate_Dir "Debug" 63 | # PROP BASE Target_Dir "" 64 | # PROP Use_MFC 0 65 | # PROP Use_Debug_Libraries 1 66 | # PROP Output_Dir "Debug" 67 | # PROP Intermediate_Dir "Debug" 68 | # PROP Ignore_Export_Lib 0 69 | # PROP Target_Dir "" 70 | # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "VLEVEL_WINAMP_EXPORTS" /YX /FD /GZ /c 71 | # ADD CPP /nologo /MD /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /GZ /c 72 | # SUBTRACT CPP /YX 73 | # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 74 | # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 75 | # ADD BASE RSC /l 0xc07 /d "_DEBUG" 76 | # ADD RSC /l 0xc07 /d "_DEBUG" 77 | BSC32=bscmake.exe 78 | # ADD BASE BSC32 /nologo 79 | # ADD BSC32 /nologo 80 | LINK32=link.exe 81 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept 82 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /pdb:none /machine:I386 /out:"C:\Program Files\Winamp\Plugins\dsp_vlevel.dll" 83 | # SUBTRACT LINK32 /debug 84 | 85 | !ENDIF 86 | 87 | # Begin Target 88 | 89 | # Name "vlevel_winamp - Win32 Release" 90 | # Name "vlevel_winamp - Win32 Debug" 91 | # Begin Group "Quellcodedateien" 92 | 93 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 94 | # Begin Source File 95 | 96 | SOURCE=.\vlevel_winamp.cpp 97 | # End Source File 98 | # Begin Source File 99 | 100 | SOURCE=.\vlevel_wrapper.cpp 101 | # End Source File 102 | # Begin Source File 103 | 104 | SOURCE=..\volumeleveler\volumeleveler.cpp 105 | # End Source File 106 | # End Group 107 | # Begin Group "Header-Dateien" 108 | 109 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 110 | # Begin Source File 111 | 112 | SOURCE=\vlevel\volumeleveler\compiler.h 113 | # End Source File 114 | # Begin Source File 115 | 116 | SOURCE=.\DSP.H 117 | # End Source File 118 | # Begin Source File 119 | 120 | SOURCE=.\vlevel\vlevel.h 121 | # End Source File 122 | # Begin Source File 123 | 124 | SOURCE=.\vlevel_wrapper.h 125 | # End Source File 126 | # Begin Source File 127 | 128 | SOURCE=.\vlevel\volumeleveler.h 129 | # End Source File 130 | # End Group 131 | # Begin Group "Ressourcendateien" 132 | 133 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 134 | # End Group 135 | # End Target 136 | # End Project 137 | -------------------------------------------------------------------------------- /volumeleveler/volumeleveler.h: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // volumeleveler.h - declares the VolumeLeveler class 21 | // 22 | // A note on terminology: atoms are indivual value_t values; samples 23 | // are one or more atoms, for example, for stereo, a sample has 2 24 | // atoms, and channels is 2. 25 | 26 | #ifndef VOLUMELEVELER_H 27 | #define VOLUMELEVELER_H 28 | 29 | #include 30 | 31 | typedef float value_t; 32 | 33 | #define VLEVEL_ABS(x) fabsf(x) 34 | 35 | // same speed as above 36 | //#define VLEVEL_ABS(x) ((x) > 0 ? (x) : -(x)) 37 | 38 | // a bit faster on 2.96, a bit slower(!) on 3.2 39 | //#define VLEVEL_ABS(x) (x) 40 | 41 | // TODO: VLEVEL_MAX? or maybe that's not worth it 42 | 43 | 44 | // Branch Prediction: 45 | // 46 | // NOTE: for some strange reason, doing nothing is fastest, my 47 | // hand-tuned unlikely() macros is slightly slower, and letting 48 | // -fprofile-arcs and -fbranch-probabilities help the optimization is 49 | // slowest yet. This is the exact opposite of what I'd expect. Hmm. 50 | // I wish somebody would optimize GCC up to the speed of ICC. 51 | // 52 | // XXX: should be only for GCC versions that support this: 53 | // taken from linux/include/linux/compiler.h 54 | #ifdef EXPECT 55 | #warning using tweaks 56 | #define likely(x) __builtin_expect(!!(x), 1) 57 | #define unlikely(x) __builtin_expect(!!(x), 0) 58 | #else 59 | #define likely(x) (x) 60 | #define unlikely(x) (x) 61 | #endif 62 | 63 | // Converts from an integer format to value_t 64 | // values is the number of values in out, in needs values*bits/8 bytes. 65 | void ToValues(char *in, value_t *out, size_t values, 66 | size_t bits_per_value, bool has_sign); 67 | 68 | // Converts from value_t to an integer format 69 | // values is the number of values in in, out needs values*bits/8 bytes. 70 | void FromValues(value_t *in, char *out, size_t values, 71 | size_t bits_per_value, bool has_sign); 72 | 73 | class VolumeLeveler { 74 | public: 75 | 76 | // constructs and destructs a VolumeLeveler with a length of l 77 | // samples with c channels each, an effect strength of s and a 78 | // maximum multiplier of m 79 | VolumeLeveler(size_t l = 44100, size_t c = 2, value_t s = .8, value_t m = 25); 80 | ~VolumeLeveler(); 81 | 82 | // Reallocates a buffer of l samples and c channels (contents are 83 | // lost) 84 | void SetSamplesAndChannels(size_t l, size_t c); 85 | 86 | // set and get the strength (between 0 and 1) (set doesn't affect 87 | // the buffer) if undo is true, vlevel will do the exact opposite, 88 | // so you can remove a vlevel. 89 | void SetStrength(value_t s); 90 | 91 | // set and get the max multiplier (set doesn't affect the buffer) 92 | void SetMaxMultiplier(value_t m); 93 | 94 | // get stuff 95 | inline size_t GetSamples() { return samples; }; 96 | inline size_t GetChannels() { return channels; }; 97 | inline value_t GetStrength() { return strength; }; 98 | inline value_t GetMaxMultiplier() { return max_multiplier; }; 99 | inline size_t GetSilence() { return silence; }; 100 | 101 | // get stats 102 | value_t GetMultiplier(); 103 | inline value_t GetAverageAmp() { return avg_amp; }; 104 | 105 | // fills the buffers with silence 106 | void Flush(); 107 | 108 | // replaces raw with processed, returns how many samples are 109 | // residual silence from when the buffers were empty. 110 | size_t Exchange(value_t **in_buf, value_t **out_buf, size_t in_samples); 111 | 112 | private: 113 | 114 | //void Exchange_1(value_t **in_buf, value_t **out_buf, size_t in_samples); 115 | //void Exchange_2(value_t **in_buf, value_t **out_buf, size_t in_samples); 116 | void Exchange_n(value_t **in_buf, value_t **out_buf, size_t in_samples); 117 | 118 | // the buffer 119 | value_t **bufs; 120 | 121 | // the length of the buffers 122 | size_t samples; 123 | 124 | // the number of channels 125 | size_t channels; 126 | 127 | // the strength of the effect (between 0 and 1) 128 | value_t strength; 129 | 130 | // the maximum value by which a sample will be scaled 131 | value_t max_multiplier; 132 | 133 | // the amount of silence (data that wasn't input) left in the buffer (samples). 134 | size_t silence; 135 | 136 | // position about to be returned (samples) 137 | size_t pos; 138 | 139 | // position of the max slope (samples) 140 | size_t max_slope_pos; 141 | 142 | // the current "blanket" amplitude 143 | value_t avg_amp; 144 | 145 | // the maximum slope 146 | value_t max_slope; 147 | 148 | // the value at the maximum slope 149 | value_t max_slope_val; 150 | 151 | }; 152 | 153 | #endif // ndef VOLUMELEVELER_H 154 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel/volumeleveler.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // volumeleveler.cpp - defines the VolumeLeveler class 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "vlevel.h" 28 | #include "volumeleveler.h" 29 | 30 | using namespace std; 31 | 32 | VolumeLeveler::VolumeLeveler(size_t l, size_t c, value_t s, value_t m) 33 | { 34 | bufs = 0; 35 | SetSamplesAndChannels(l, c); 36 | SetStrength(s); 37 | SetMaxMultiplier(m); 38 | } 39 | 40 | VolumeLeveler::~VolumeLeveler() 41 | { 42 | for(size_t ch = 0; ch < channels; ++ch) 43 | delete [] bufs[ch]; 44 | delete [] bufs; 45 | } 46 | 47 | void VolumeLeveler::SetStrength(value_t s) 48 | { 49 | strength = s; 50 | } 51 | 52 | void VolumeLeveler::SetMaxMultiplier(value_t m) 53 | { 54 | if(m <= 0) m = HUGE_VAL; 55 | max_multiplier = m; 56 | } 57 | 58 | void VolumeLeveler::SetSamplesAndChannels(size_t s, size_t c) 59 | { 60 | assert(s > 1 && c > 0); 61 | 62 | if(bufs) { 63 | for(size_t ch = 0; ch < channels; ++ch) 64 | delete [] bufs[ch]; 65 | delete [] bufs; 66 | } 67 | 68 | bufs = new value_t*[c]; 69 | 70 | for(size_t ch = 0; ch < c; ++ch) 71 | bufs[ch] = new value_t[s]; 72 | 73 | samples = s; 74 | channels = c; 75 | Flush(); 76 | } 77 | 78 | void VolumeLeveler::Flush() 79 | { 80 | for(size_t ch = 0; ch < channels; ++ch) 81 | for(size_t i = 0; i < samples; ++i) 82 | bufs[ch][i] = 0; 83 | 84 | silence = samples; 85 | pos = max_slope_pos = 0; 86 | max_slope = max_slope_val = avg_amp = 0; 87 | } 88 | 89 | value_t VolumeLeveler::GetMultiplier() 90 | { 91 | value_t multiplier = pow(avg_amp, -strength); 92 | if(multiplier > max_multiplier) multiplier = max_multiplier; 93 | return multiplier; 94 | } 95 | 96 | size_t VolumeLeveler::Exchange(value_t **in_bufs, value_t **out_bufs, size_t in_samples) 97 | { 98 | switch(channels) { 99 | //case 1: 100 | // Exchange_1(in_bufs, out_bufs, in_samples); 101 | // break; 102 | //case 2: 103 | // Exchange_2(in_bufs, out_bufs, in_samples); 104 | // break; 105 | default: 106 | Exchange_n(in_bufs, out_bufs, in_samples); 107 | } 108 | 109 | if(silence >= in_samples) { 110 | silence -= in_samples; 111 | return in_samples; 112 | } else { 113 | size_t returned_silence = silence; 114 | silence = 0; 115 | return returned_silence; 116 | } 117 | } 118 | 119 | void VolumeLeveler::Exchange_n(value_t **in_bufs, value_t **out_bufs, size_t in_samples) 120 | { 121 | // for each user_pos in user_buf 122 | for(size_t user_pos = 0; user_pos < in_samples; ++user_pos) { 123 | 124 | // compute multiplier 125 | value_t multiplier = pow(avg_amp, -strength); 126 | 127 | // if avg_amp <= 0, then the above line sets multiplier to Inf, so 128 | // samples will scale to Inf or NaN. This causes a tick on the 129 | // first sample after a Flush() unless max_multiplier is not Inf. 130 | // hopefully this fix isn't too slow. 131 | if(avg_amp <= 0) multiplier = 0; 132 | 133 | // limit multiplier to max_multiplier. max_multiplier can be Inf 134 | // to disable this. 135 | if(multiplier > max_multiplier) multiplier = max_multiplier; 136 | 137 | // swap buf[pos] with user_buf[user_pos], scaling user[buf] by 138 | // multiplier and finding max of the new sample 139 | value_t new_val = 0; 140 | for(size_t ch = 0; ch < channels; ++ch) { 141 | value_t in = in_bufs[ch][user_pos]; 142 | out_bufs[ch][user_pos] = bufs[ch][pos] * multiplier; 143 | bufs[ch][pos] = in; 144 | if(VLEVEL_ABS(in) > new_val) new_val = fabs(in); 145 | } 146 | 147 | pos = (pos + 1) % samples; // now pos is the oldest, new one is pos-1 148 | 149 | avg_amp += max_slope; 150 | 151 | if(pos == max_slope_pos) { 152 | // recompute (this is expensive) 153 | max_slope = -HUGE_VAL; 154 | for(size_t i = 1; i < samples; ++i) { 155 | value_t sample_val = 0; 156 | for(size_t ch = 0; ch < channels; ++ch) { 157 | value_t ch_val = VLEVEL_ABS(bufs[ch][(pos + i) % samples]); 158 | if(ch_val > sample_val) sample_val = ch_val; 159 | } 160 | value_t slope = (sample_val - avg_amp) / i; 161 | if(slope >= max_slope) { // must be >=, otherwise clipping causes excessive computation 162 | max_slope_pos = (pos + i) % samples; 163 | max_slope = slope; 164 | max_slope_val = sample_val; 165 | } 166 | } 167 | } else { 168 | // only chance of higher slope is the new sample 169 | 170 | // recomputing max_slope isn't really necessary... 171 | max_slope = (max_slope_val - avg_amp) / ((max_slope_pos - pos + samples) % samples); 172 | // ...but it doesn't take long and has a small effect. 173 | 174 | value_t slope = (new_val - avg_amp) / (samples - 1); 175 | 176 | if(slope >= max_slope) { // probably needs to be >= for same reason as above 177 | max_slope_pos = (pos - 1) % samples; 178 | max_slope = slope; 179 | max_slope_val = new_val; 180 | } 181 | } 182 | } 183 | } 184 | 185 | -------------------------------------------------------------------------------- /docs/technical.txt: -------------------------------------------------------------------------------- 1 | VLevel 0.3 technical.txt 2 | 3 | This is an outline of how VLevel works, which will hopefully be useful 4 | to anyone who helps develop it. (And me in a month.) 5 | 6 | Code Layout 7 | 8 | The core of VLevel is the VolumeLeveler class. It contains the 9 | look-ahead buffer. It works on blocks of double-precision numbers, 10 | called values (value_t). Some number (channels) of values makes up 11 | a sample. Many of VolumeLeveler's functions take lengths in samples 12 | instead of values, so be careful. 13 | 14 | vlevel-bin drives the VolumeLeveler class, and also uses CommandLine 15 | to parse it's options. 16 | 17 | Soon, there will be a Ruby script using SOX that makes Ogg, FLAC, and wav 18 | files work with a nice drag-n-drop GUI. 19 | 20 | General Idea 21 | 22 | The intent is to make the quiet parts louder. This is done by 23 | computing the volume at each point, then scaling it as described in 24 | the Math section. The complex part is finding out what the volume 25 | is at each point (VolumeLeveler::avg_amp). It must vary smoothly so 26 | the volume changes aren't obvious, but it must always be above the 27 | peaks of the waveform, or clipping could occur. 28 | 29 | To do this, there is a fifo buffer. Imagine a graph of position 30 | vs. amplitude showing the contents of the buffer. A horizontal line 31 | is drawn across it, representing VolumeLeveler::avg_amp. From where 32 | avg_amp crosses the y-axis, a line is drawn with the maximum 33 | possible slope to intercept one of the amplitude points. This line 34 | which is as steep as possible, is the smooth line that avg_amp will 35 | follow. 36 | 37 | When the value at the head of the buffer is removed, it is scaled 38 | based on avg_amp. avg_amp is then incremented by the slope of the 39 | line. If we reach the point the line was drawn to (max_slope_pos), 40 | we search the fifo for the next point of highest slope. Otherwise, 41 | we only need to check the incoming sample to see if a line drawn to 42 | it has the highest slope. 43 | 44 | y y (a few samples later) 45 | 46 | ^ ^ ^ 47 | | / max_slope | 48 | | / | 49 | | /s |s\---------- avg_amp 50 | | / s |s \ 51 | | / s |s \ max_slope 52 | | / s s |s s \ 53 | |--s-ss-s----avg_amp |s s \ 54 | | ss ss s s |s s ss 55 | |ssssssssss |ssssss 56 | +------------> x +---------> x 57 | 58 | Sorry for the ASCII art. The result is that the average amplitude 59 | (avg_amp) varies slowly and always stays above the amplitude of each 60 | sample. When the samples are removed, they are scaled based on the 61 | next section. 62 | 63 | Math 64 | 65 | Once we have avg_amp, each sample is scaled when it is output 66 | according to this: 67 | 68 | output_sample = sample * avg_amp ^ (-strength) 69 | 70 | This is derived as follows: 71 | 72 | First, we convert the amplitude of avg_amp to decibels (1 = 0dB): 73 | 74 | avg_amp_db = 10 * log10(avg_amp) 75 | 76 | avg_amp_db is less than zero. We want to scale it to be closer to 77 | zero, in such a way that if strength is 1, it will become zero, and 78 | if strength is 0 it will remain unchanged. 79 | 80 | ideal_amp_db = avg_amp_db * (1 - strength) 81 | ideal_amp_db = 10 * log10(avg_amp) * (1 - strength) 82 | 83 | Now we convert back to samples: 84 | 85 | ideal_amp = 10 ^ (ideal_amp_db / 10) 86 | ideal_amp = 10 ^ (log10(avg_amp) * (1 - strength)) 87 | ideal_amp = (10 ^ log10(avg_amp)) ^ (1 - strength) 88 | ideal_amp = avg_amp ^ (1 - strength) 89 | 90 | Now we find out what we should multiply the samples by to change 91 | their peak amplitude, avg_amp, to their ideal peak amplitude, 92 | ideal_amp: 93 | 94 | multiplier = ideal_amp / avg_amp 95 | multiplier = avg_amp ^ (1 - strength) / avg_amp 96 | multiplier = avg_amp ^ (-strength) 97 | 98 | And finally, we multiply the sample by the multiplier: 99 | 100 | output_sample = sample * multiplier 101 | output_sample = sample * avg_amp ^ (-strength) 102 | 103 | Undoing the effect 104 | 105 | If the original values for strength weren't too close to 1, you can 106 | undo the VLevel by giving the undo option. It works by changing 107 | strength as shown below. 108 | 109 | When we first leveled, we scaled the amplitudes like so: 110 | 111 | ideal_amp_db = avg_amp_db * (1 - strength) 112 | 113 | To get that back, we solve for avg_amp_db 114 | 115 | avg_amp_db = ideal_amp_db * 1 / (1 - strength) 116 | 117 | In this pass, however, the original avg_amp_db becomes ideal_amp_db, 118 | and the original (1 - strength) becomes 1 / (1 - strength). Now 119 | we skip ahead a bit: 120 | 121 | multiplier = avg_amp ^ (1 - strength) / avg_amp 122 | 123 | Substituting as explained above and continuing: 124 | 125 | multiplier = avg_amp ^ (1 / (1 - strength)) / avg_amp 126 | multiplier = avg_amp ^ ((1 / (1 - strength)) - 1) 127 | multiplier = avg_amp ^ (strength / (1 - strength)) 128 | 129 | But how do we get VLevel to do this? Well, we can give it any 130 | strength, and it does this: 131 | 132 | multiplier = avg_amp ^ -strength 133 | 134 | And we want it to do this: 135 | 136 | multiplier = avg_amp ^ (undo_strength / (1 - undo_strength)) 137 | 138 | So... 139 | 140 | -strength = undo_strength / (1 - undo_strength) 141 | strength = undo_strength / (undo_strength - 1) 142 | 143 | By choosing strength as above before starting VLevel, we can then 144 | undo the first VLevel, with no change to the main algorithm. 145 | 146 | To be totally precise, we'd also have to make a min_multiplier with 147 | a value of 1 / orig_max_multiplier, but that would be slow, and does 148 | anybody care if we drop the static anyway? 149 | 150 | It's not perfect, probably because avg_amp moves linearly, not 151 | logarithmically, so there are some rounding errors. Someday I might 152 | try changing that, but it's a big change. 153 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel_wrapper.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // vlevel_wrapper.cpp - this file is part of vlevel winamp plugin 0.1 4 | // Copyright (C) 2003 Markus Sablatnig 5 | // Copyright (C) 2003 Tom Felker 6 | // 7 | // This program is free software; you can redistribute it and/or 8 | // modify it under the terms of the GNU General Public License 9 | // as published by the Free Software Foundation; either version 2 10 | // of the License, or (at your option) any later version. 11 | // 12 | // This program is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program; if not, write to the Free Software 19 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | // 21 | /////////////////////////////////////////////////////////////////////////////// 22 | 23 | #include 24 | #include 25 | 26 | #include "..\\volumeleveler\\volumeleveler.h" 27 | #include "vlevel_wrapper.h" 28 | 29 | CVLWrapper::CVLWrapper(): 30 | ms_samples(44100), 31 | ms_channels(2), 32 | mv_strength(.8), 33 | mv_maxMultiplier(25), 34 | mv_length(1), 35 | ms_rate(44100), 36 | mb_samplesOrChannelsChanged(false), 37 | mb_strengthChanged(false), 38 | mb_maxMultiplierChanged(false) 39 | { 40 | mpvl_wrapped = new VolumeLeveler(ms_samples, ms_channels, mv_strength, mv_maxMultiplier); 41 | 42 | // I'm surprised this isn't automatic. 43 | if(!mpvl_wrapped) 44 | throw std::bad_alloc(); 45 | } // CVLWrapper::CVLWrapper 46 | 47 | CVLWrapper::~CVLWrapper() 48 | { 49 | delete mpvl_wrapped; 50 | // TODO: when I cache the buffer allocations, I must delete them here. 51 | } 52 | 53 | void CVLWrapper::SetCachedChannels(size_t s_channels) 54 | { 55 | assert(s_channels > 0); 56 | if(ms_channels != s_channels) { 57 | ms_channels = s_channels; 58 | mb_samplesOrChannelsChanged = true; 59 | } 60 | } // CVLWrapper::SetCachedChannels 61 | 62 | void CVLWrapper::SetCachedStrength(value_t v_strength) 63 | { 64 | mv_strength = v_strength; 65 | mb_strengthChanged = true; 66 | } // CVLWrapper::SetCachedStrength 67 | 68 | void CVLWrapper::SetCachedMaxMultiplier(value_t v_maxMultiplier) 69 | { 70 | mv_maxMultiplier = v_maxMultiplier; 71 | mb_maxMultiplierChanged = true; 72 | } // CVLWrapper::SetCachedMaxMultiplier 73 | 74 | void CVLWrapper::SetCachedLength(value_t v_length) 75 | { 76 | mv_length = v_length; 77 | SetCachedSamples(GetCachedLength() * GetCachedRate()); 78 | } // CVLWrapper::SetCachedLength 79 | 80 | void CVLWrapper::SetCachedRate(size_t s_rate) 81 | { 82 | ms_rate = s_rate; 83 | ms_samples = mv_length * ms_rate; 84 | 85 | SetCachedSamples(GetCachedLength() * GetCachedRate()); 86 | } // CVLWrapper::SetCachedRate 87 | 88 | // Don't call this unless you've just computed s_amples from mv_length and ms_rate. 89 | void CVLWrapper::SetCachedSamples(size_t s_samples) 90 | { 91 | assert(s_samples > 1); 92 | if(ms_samples != s_samples) { 93 | ms_samples = s_samples; 94 | mb_samplesOrChannelsChanged = true; 95 | } 96 | } // CVLWrapper::SetCachedSamples 97 | 98 | void CVLWrapper::CacheFlush() 99 | { 100 | if( mb_samplesOrChannelsChanged) 101 | { 102 | mpvl_wrapped->SetSamplesAndChannels(ms_samples, ms_channels); 103 | mb_samplesOrChannelsChanged = false; 104 | } // if 105 | 106 | if( mb_strengthChanged ) 107 | { 108 | mpvl_wrapped->SetStrength(mv_strength); 109 | mb_strengthChanged = false; 110 | } // if 111 | 112 | if(mb_maxMultiplierChanged) 113 | { 114 | mpvl_wrapped->SetMaxMultiplier(mv_maxMultiplier); 115 | SetCachedMaxMultiplier(mpvl_wrapped->GetMaxMultiplier()); // turns negative mms to HUGE_VAL 116 | mb_maxMultiplierChanged = false; 117 | } // if 118 | } // CVLWrapper::CacheFlush 119 | 120 | int CVLWrapper::Exchange(void *raw_buf, int samples, int bits_per_value, int channels, int rate) 121 | { 122 | SetCachedChannels(channels); 123 | SetCachedRate(rate); 124 | CacheFlush(); 125 | 126 | size_t values = samples * channels; 127 | 128 | // TODO: cache these allocations for performance. 129 | // This buffer holds interleaved value_t data. 130 | value_t *raw_value_buf = new value_t[values]; 131 | // Allocate our per-channel value_t buffers. 132 | // This is the format VolumeLeveler requires. 133 | value_t **bufs = new value_t*[channels]; 134 | for(size_t ch = 0; ch < channels; ++ch) 135 | bufs[ch] = new value_t[samples]; 136 | 137 | // Take data from supplied integer raw_buf to allocated value_t interleaved raw_value_buf. 138 | ToValues((char *)raw_buf, raw_value_buf, values, bits_per_value, true); // true because data is signed. 139 | 140 | // De-interleave the data. 141 | for(size_t s = 0; s < samples; ++s) 142 | for(size_t ch = 0; ch < channels; ++ch) 143 | bufs[ch][s] = raw_value_buf[s * channels + ch]; 144 | 145 | // Perform the effect. 146 | // silence_samples is how many samples at the beginning of the returned buffer 147 | // are silent because the real data hasn't worked through VLevel's buffer yet. 148 | size_t silence_samples = mpvl_wrapped->Exchange(bufs, bufs, samples); 149 | 150 | size_t good_samples = samples - silence_samples; 151 | size_t good_values = good_samples * channels; 152 | 153 | // Re-interleave the data. 154 | // Visual C++ improperly lets the s defined above persist outside that loop. 155 | // Notice that leading silence_samples are stripped and good data is shifted. 156 | for(/* size_t */ s = 0; s < good_samples; ++s) 157 | for(size_t ch = 0; ch < channels; ++ch) 158 | raw_value_buf[s * channels + ch] = bufs[ch][s + silence_samples]; 159 | 160 | // Put the good data back into the supplied integer buffer. 161 | FromValues(raw_value_buf, (char *)raw_buf, good_values, bits_per_value, true); 162 | 163 | // Deallocate our buffers. 164 | for(/* size_t */ ch = 0; ch < channels; ++ch) 165 | delete [] bufs[ch]; 166 | delete [] bufs; 167 | delete [] raw_value_buf; 168 | 169 | // Winamp is sloppy about using int when size_t is correct. Oh, well. 170 | // dsp.h says we shouldn't return less than half as many samples as we're given, 171 | // but returning 0 seems to work fine. 172 | return good_samples; 173 | } // CVLWrapper::Exchange 174 | 175 | -------------------------------------------------------------------------------- /vlevel-ladspa/vlevel-ladspa.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // vlevel-ladspa.cpp - the ladspa plugin 21 | 22 | #include "../volumeleveler/volumeleveler.h" 23 | #include "ladspa.h" 24 | #include "vlevel-ladspa.h" 25 | 26 | using namespace std; 27 | 28 | // Is there a reason this must be allocated? It seems to work without it. 29 | 30 | // Why not just a LADSPA_Port struct with names and hints? 31 | 32 | LADSPA_PortDescriptor vlevel_port_descriptors[] = { 33 | LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, 34 | LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, 35 | LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, 36 | LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, 37 | LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL, 38 | LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL, 39 | LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, 40 | LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO, 41 | LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO, 42 | LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO 43 | }; 44 | 45 | const char *vlevel_port_names[] = { 46 | "Look-ahead (seconds)", 47 | "Strength", 48 | "Limit Multiplier", 49 | "Multiplier Limit", 50 | "Undo", 51 | "Current Multiplier", 52 | "Input 1", 53 | "Output 1", 54 | "Input 2", 55 | "Output 2" 56 | }; 57 | 58 | // Why can't I just specify the default, instead of _LOW _HIGH masks? 59 | 60 | LADSPA_PortRangeHint vlevel_port_range_hints[] = { 61 | { 62 | LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | 63 | LADSPA_HINT_DEFAULT_MIDDLE, 64 | 0, 5 65 | }, 66 | { 67 | LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | 68 | LADSPA_HINT_DEFAULT_HIGH, 69 | 0, 1 70 | }, 71 | { 72 | LADSPA_HINT_TOGGLED | 73 | LADSPA_HINT_DEFAULT_1, 74 | 0, 0 75 | }, 76 | { 77 | LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | 78 | LADSPA_HINT_DEFAULT_MIDDLE, 79 | 0, 20 80 | }, 81 | { 82 | LADSPA_HINT_TOGGLED | 83 | LADSPA_HINT_DEFAULT_0, 84 | 0, 0 85 | }, 86 | { 87 | LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 88 | 0, 20 89 | }, 90 | { 0, 0, 0 }, 91 | { 0, 0, 0 }, 92 | { 0, 0, 0 }, 93 | { 0, 0, 0 } 94 | }; 95 | 96 | LADSPA_Descriptor vlevel_descriptor_mono = { 97 | // UniqueID 98 | UID_MONO, 99 | // Label 100 | "vlevel_mono", 101 | // Properties 102 | 0, 103 | // Name 104 | "VLevel (Mono)", 105 | // Maker 106 | "Tom Felker", 107 | // Copyright 108 | "GPL", 109 | // PortCount 110 | CONTROL_PORT_COUNT + 2, 111 | // PortDescriptors 112 | vlevel_port_descriptors, 113 | // PortNames 114 | vlevel_port_names, 115 | // PortRangeHints 116 | vlevel_port_range_hints, 117 | // ImplementationData 118 | 0, 119 | // instantiate 120 | Instantiate, 121 | // connect_port 122 | ConnectPort, 123 | // activate 124 | Activate, 125 | // run 126 | Run, 127 | // run_adding 128 | 0, 129 | // set_run_adding_gain 130 | 0, 131 | // deactivate 132 | Deactivate, 133 | // cleanup 134 | Cleanup 135 | }; 136 | 137 | 138 | LADSPA_Descriptor vlevel_descriptor_stereo = { 139 | // UniqueID 140 | UID_STEREO, 141 | // Label 142 | "vlevel_stereo", 143 | // Properties 144 | 0, 145 | // Name 146 | "VLevel (Stereo)", 147 | // Maker 148 | "Tom Felker", 149 | // Copyright 150 | "GPL", 151 | // PortCount 152 | CONTROL_PORT_COUNT + 4, 153 | // PortDescriptors 154 | vlevel_port_descriptors, 155 | // PortNames 156 | vlevel_port_names, 157 | // PortRangeHints 158 | vlevel_port_range_hints, 159 | // ImplementationData 160 | 0, 161 | // instantiate 162 | Instantiate, 163 | // connect_port 164 | ConnectPort, 165 | // activate 166 | Activate, 167 | // run 168 | Run, 169 | // run_adding 170 | 0, 171 | // set_run_adding_gain 172 | 0, 173 | // deactivate 174 | Deactivate, 175 | // cleanup 176 | Cleanup 177 | }; 178 | 179 | const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) 180 | { 181 | switch(index) { 182 | case 0: 183 | return &vlevel_descriptor_mono; 184 | case 1: 185 | return &vlevel_descriptor_stereo; 186 | default: 187 | return 0; 188 | } 189 | } 190 | 191 | 192 | VLevelInstance::VLevelInstance(size_t channels, unsigned long rate): 193 | vl(2, channels), nch(channels), sample_rate(rate) 194 | { 195 | ports = new value_t*[CONTROL_PORT_COUNT + 2 * nch]; 196 | in = new value_t*[nch]; 197 | out = new value_t*[nch]; 198 | } 199 | 200 | VLevelInstance::~VLevelInstance() 201 | { 202 | delete [] ports; 203 | delete [] in; 204 | delete [] out; 205 | } 206 | void VLevelInstance::ConnectPort(unsigned long port, value_t *data_location) 207 | { 208 | ports[port] = data_location; 209 | 210 | if(port >= CONTROL_PORT_COUNT) { // is a control port 211 | if((port - CONTROL_PORT_COUNT) % 2 == 0) // is an input port 212 | in[(port - CONTROL_PORT_COUNT) / 2] = data_location; 213 | else if((port - CONTROL_PORT_COUNT) % 2 == 1) // is an output port 214 | out[(port - CONTROL_PORT_COUNT) / 2] = data_location; 215 | } 216 | } 217 | 218 | void VLevelInstance::Activate() 219 | { 220 | vl.Flush(); 221 | } 222 | 223 | void VLevelInstance::Run(unsigned long sample_count) 224 | { 225 | 226 | size_t samples = (size_t) (*ports[CONTROL_PORT_LOOK_AHEAD] * sample_rate); 227 | if(samples != vl.GetSamples()) { 228 | if(samples > 60 * sample_rate) samples = 60 * sample_rate; 229 | if(samples < 2) samples = 2; 230 | vl.SetSamplesAndChannels(samples, nch); 231 | } 232 | 233 | if(*ports[CONTROL_PORT_USE_MAX_MULTIPLIER] > 0) { 234 | vl.SetMaxMultiplier(*ports[CONTROL_PORT_MAX_MULTIPLIER]); 235 | } else { 236 | vl.SetMaxMultiplier(-1); 237 | } 238 | 239 | value_t strength = *ports[CONTROL_PORT_STRENGTH]; 240 | if(*ports[CONTROL_PORT_UNDO] > 0) 241 | strength /= (strength - 1); 242 | vl.SetStrength(strength); 243 | 244 | vl.Exchange(in, out, sample_count); 245 | 246 | *ports[CONTROL_PORT_OUTPUT_MULTIPLIER] = vl.GetMultiplier(); 247 | } 248 | 249 | void VLevelInstance::Deactivate() {} 250 | 251 | LADSPA_Handle Instantiate(const LADSPA_Descriptor *descriptor, unsigned long sample_rate) 252 | { 253 | switch(descriptor->UniqueID) { 254 | case UID_MONO: 255 | return (LADSPA_Handle)new VLevelInstance(1, sample_rate); 256 | case UID_STEREO: 257 | return (LADSPA_Handle)new VLevelInstance(2, sample_rate); 258 | } 259 | return 0; 260 | } 261 | 262 | void ConnectPort(LADSPA_Handle instance, unsigned long port, value_t *data_location) 263 | { 264 | ((VLevelInstance *)instance)->ConnectPort(port, data_location); 265 | } 266 | 267 | void Activate(LADSPA_Handle instance) 268 | { 269 | ((VLevelInstance *)instance)->Activate(); 270 | } 271 | 272 | void Run(LADSPA_Handle instance, unsigned long sample_count) 273 | { 274 | ((VLevelInstance *)instance)->Run(sample_count); 275 | } 276 | 277 | void Deactivate(LADSPA_Handle instance) 278 | { 279 | ((VLevelInstance *)instance)->Deactivate(); 280 | } 281 | 282 | void Cleanup(LADSPA_Handle instance) 283 | { 284 | delete (VLevelInstance *)instance; 285 | } 286 | -------------------------------------------------------------------------------- /vlevel-bin/vlevel-bin.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // vlevel-bin.cpp - the vlevel-bin command, uses VolumeLeveler 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | #include "../volumeleveler/volumeleveler.h" 33 | #include "commandline.h" 34 | 35 | using namespace std; 36 | 37 | void LevelRaw(istream &in, ostream& out, VolumeLeveler &vl, unsigned int bits_per_value); 38 | void Help(); 39 | 40 | void LevelRaw(FILE *in, FILE *out, VolumeLeveler &vl, unsigned int bits_per_value) 41 | { 42 | assert(bits_per_value % 8 == 0); 43 | 44 | // figure out the size of things 45 | size_t samples = vl.GetSamples(); 46 | size_t channels = vl.GetChannels(); 47 | size_t values = samples * channels; 48 | size_t bytes_per_value = bits_per_value / 8; 49 | size_t bytes = values * bytes_per_value; 50 | 51 | size_t s, ch; // VC++ 5.0's scoping rules are wrong, oh well. 52 | 53 | // allocate our interleaved buffers 54 | char *raw_buf = new char[bytes]; 55 | value_t *raw_value_buf = new value_t[values]; 56 | 57 | // allocate our per-channel buffers 58 | value_t **bufs = new value_t*[channels]; 59 | for(ch = 0; ch < channels; ++ch) 60 | bufs[ch] = new value_t[samples]; 61 | 62 | // how much data in the buffer is good 63 | size_t good_values, good_samples; 64 | // how much from the front of the buffer should be ignored 65 | size_t silence_values, silence_samples; 66 | 67 | while(!ferror(in) && !feof(in)) { 68 | // read and convert to value_t 69 | good_values = fread(raw_buf, bytes_per_value, values, in); 70 | good_samples = good_values / channels; 71 | ToValues(raw_buf, raw_value_buf, good_values, bits_per_value, true); 72 | 73 | // de-interleave the data 74 | for(size_t s = 0; s < good_samples; ++s) 75 | for(size_t ch = 0; ch < channels; ++ch) 76 | bufs[ch][s] = raw_value_buf[s * channels + ch]; 77 | 78 | // do the exchange 79 | silence_samples = vl.Exchange(bufs, bufs, good_samples); 80 | silence_values = silence_samples * channels; 81 | good_samples -= silence_samples; 82 | good_values -= silence_values; 83 | 84 | // interleave the data 85 | for(s = silence_samples; s < silence_samples + good_samples; ++s) 86 | for(size_t ch = 0; ch < channels; ++ch) 87 | raw_value_buf[s * channels + ch] = bufs[ch][s]; 88 | 89 | // write the data 90 | FromValues(&raw_value_buf[silence_values], raw_buf, good_values, bits_per_value, true); 91 | fwrite(raw_buf, bytes_per_value, good_values, out); 92 | } 93 | 94 | // silence the data 95 | for(s = 0; s < samples; ++s) 96 | for(size_t ch = 0; ch < channels; ++ch) 97 | bufs[ch][s] = 0; 98 | 99 | // exchange the data, 100 | silence_samples = vl.Exchange(bufs, bufs, samples); 101 | silence_values = silence_samples * channels; 102 | // good_samples = samples - silence_samples; 103 | good_values = values - silence_values; 104 | 105 | //interlace 106 | for(s = silence_samples; s < samples; ++s) 107 | for(size_t ch = 0; ch < channels; ++ch) 108 | raw_value_buf[s * channels + ch] = bufs[ch][s]; 109 | 110 | FromValues(&raw_value_buf[silence_values], raw_buf, good_values, bits_per_value, true); 111 | fwrite(raw_buf, bytes_per_value, good_values, out); 112 | 113 | delete [] raw_buf; 114 | delete [] raw_value_buf; 115 | for(ch = 0; ch < channels; ++ch) 116 | delete [] bufs[ch]; 117 | delete [] bufs; 118 | 119 | } 120 | 121 | void Help(const char *program) 122 | { 123 | cerr << "VLevel v" << VLEVEL_VERSION << endl 124 | << endl 125 | << "usage:" << endl 126 | << "\t" << program << " [options] < infile.cdda > outfile.cdda" << endl 127 | << endl 128 | << "options: (abbreviations also work)" << endl 129 | << "\t--length num" << endl 130 | << "\t\tSets the buffer to num samples long" << endl 131 | << "\t\tDefault is 132300 (three seconds at 44.1kHz)" << endl 132 | << "\t--channels num" << endl 133 | << "\t\tEach sample has num channels" << endl 134 | << "\t\tDefault is 2" << endl 135 | << "\t--strength num" << endl 136 | << "\t\tEffect strength, 1 is max, 0 is no effect." << endl 137 | << "\t\tDefault is .8" << endl 138 | << "\t--max-multiplier num" << endl 139 | << "\t\tSets the maximum amount a sample will be multiplied" << endl 140 | << "\t\tDefault is 20" << endl 141 | << "\t--undo" << endl 142 | << "\t\tReverses the effect of a previous VLevel" << endl; 143 | } 144 | 145 | int main(int argc, char *argv[]) 146 | { 147 | CommandLine cmd(argc, argv); 148 | size_t length = 3 * 44100; 149 | size_t channels = 2; 150 | value_t strength = .8, max_multiplier = 20; 151 | bool undo = false; 152 | string option, argument; 153 | 154 | while(option = cmd.GetOption(), !option.empty()) { 155 | 156 | if(option == "length" || option == "l") { 157 | if((istringstream(cmd.GetArgument()) >> length).fail()) { 158 | cerr << cmd.GetProgramName() << ": bad or no option for --length" << endl; 159 | return 2; 160 | } 161 | if(length < 2) { 162 | cerr << cmd.GetProgramName() << ": --length must be greater than 1" << endl; 163 | return 2; 164 | } 165 | } else if(option == "channels" || option == "c") { 166 | if((istringstream(cmd.GetArgument()) >> channels).fail()) { 167 | cerr << cmd.GetProgramName() << ": bad or no option for --channels" << endl; 168 | return 2; 169 | } 170 | if(channels < 1) { 171 | cerr << cmd.GetProgramName() << ": --channels must be greater than 0" << endl; 172 | return 2; 173 | } 174 | } else if(option == "strength" || option == "s") { 175 | if((istringstream(cmd.GetArgument()) >> strength).fail()) { 176 | cerr << cmd.GetProgramName() << ": bad or no option for --strength" << endl; 177 | return 2; 178 | } 179 | if(strength < 0 || strength > 1) { 180 | cerr << cmd.GetProgramName() << ": --strength must be between 0 and 1 inclusive." << endl; 181 | return 2; 182 | } 183 | } else if(option == "max-multiplier" || option == "m") { 184 | if((istringstream(cmd.GetArgument()) >> max_multiplier).fail()) { 185 | cerr << cmd.GetProgramName() << ": bad or no option for --max-multiplier" << endl 186 | << cmd.GetProgramName() << ": for no max multiplier, give a negative number" << endl; 187 | return 2; 188 | } 189 | } else if(option == "undo" || option == "u") { 190 | undo = true; 191 | } else if(option == "help" || option == "h") { 192 | Help(argv[0]); 193 | return 0; 194 | } else { 195 | cerr << cmd.GetProgramName() << ": unrecognized option " << option << endl; 196 | Help(argv[0]); 197 | return 2; 198 | } 199 | } 200 | 201 | // This works, see docs/technical.txt 202 | if(undo) strength = strength / (strength - 1); 203 | 204 | cerr << "Beginning VLevel with:" << endl 205 | << "length: " << length << endl 206 | << "channels: " << channels << endl 207 | << "strength: " << strength << endl 208 | << "max_multiplier: " << max_multiplier << endl; 209 | 210 | FILE *in = stdin; 211 | FILE *out = stdout; 212 | 213 | argument = cmd.GetArgument(); 214 | if(!argument.empty() && argument != "-") { 215 | in = fopen(argument.c_str(), "rb"); 216 | if(!in) { 217 | cerr << "Couldn't open input file '" << argument << "'.\n" << endl; 218 | return 2; 219 | } 220 | } 221 | argument = cmd.GetArgument(); 222 | if(!argument.empty() && argument != "-") { 223 | out = fopen(argument.c_str(), "wb"); 224 | if(!in) { 225 | cerr << "Couldn't open output file '" << argument << "'.\n" << endl; 226 | return 2; 227 | } 228 | } 229 | 230 | VolumeLeveler l(length, channels, strength, max_multiplier); 231 | LevelRaw(in, out, l, 16); 232 | return 0; 233 | } 234 | -------------------------------------------------------------------------------- /volumeleveler/volumeleveler.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | // 3 | // Copyright 2003 Tom Felker 4 | // 5 | // This library is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU Lesser General Public License 7 | // as published by the Free Software Foundation; either version 2.1 of 8 | // the License, or (at your option) any later version. 9 | // 10 | // This library is distributed in the hope that it will be useful, but 11 | // WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | // Lesser General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU Lesser General Public 16 | // License along with this library; if not, write to the Free Software 17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 18 | // USA 19 | 20 | // volumeleveler.cpp - defines the VolumeLeveler class 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "volumeleveler.h" 27 | 28 | using namespace std; 29 | 30 | VolumeLeveler::VolumeLeveler(size_t l, size_t c, value_t s, value_t m) 31 | { 32 | bufs = 0; 33 | SetSamplesAndChannels(l, c); 34 | SetStrength(s); 35 | SetMaxMultiplier(m); 36 | } 37 | 38 | VolumeLeveler::~VolumeLeveler() 39 | { 40 | for(size_t ch = 0; ch < channels; ++ch) 41 | delete [] bufs[ch]; 42 | delete [] bufs; 43 | } 44 | 45 | void VolumeLeveler::SetStrength(value_t s) 46 | { 47 | strength = s; 48 | } 49 | 50 | void VolumeLeveler::SetMaxMultiplier(value_t m) 51 | { 52 | if(m <= 0) m = HUGE_VAL; 53 | max_multiplier = m; 54 | } 55 | 56 | void VolumeLeveler::SetSamplesAndChannels(size_t s, size_t c) 57 | { 58 | assert(s > 1 && c > 0); 59 | 60 | if(bufs) { 61 | for(size_t ch = 0; ch < channels; ++ch) 62 | delete [] bufs[ch]; 63 | delete [] bufs; 64 | } 65 | 66 | bufs = new value_t*[c]; 67 | 68 | for(size_t ch = 0; ch < c; ++ch) 69 | bufs[ch] = new value_t[s]; 70 | 71 | samples = s; 72 | channels = c; 73 | Flush(); 74 | } 75 | 76 | void VolumeLeveler::Flush() 77 | { 78 | for(size_t ch = 0; ch < channels; ++ch) 79 | for(size_t i = 0; i < samples; ++i) 80 | bufs[ch][i] = 0; 81 | 82 | silence = samples; 83 | pos = max_slope_pos = 0; 84 | max_slope = max_slope_val = avg_amp = 0; 85 | } 86 | 87 | value_t VolumeLeveler::GetMultiplier() 88 | { 89 | value_t multiplier = pow(avg_amp, -strength); 90 | if(multiplier > max_multiplier) multiplier = max_multiplier; 91 | return multiplier; 92 | } 93 | 94 | size_t VolumeLeveler::Exchange(value_t **in_bufs, value_t **out_bufs, size_t in_samples) 95 | { 96 | switch(channels) { 97 | //case 1: 98 | // Exchange_1(in_bufs, out_bufs, in_samples); 99 | // break; 100 | //case 2: 101 | // Exchange_2(in_bufs, out_bufs, in_samples); 102 | // break; 103 | default: 104 | Exchange_n(in_bufs, out_bufs, in_samples); 105 | } 106 | 107 | if(silence >= in_samples) { 108 | silence -= in_samples; 109 | return in_samples; 110 | } else { 111 | size_t returned_silence = silence; 112 | silence = 0; 113 | return returned_silence; 114 | } 115 | } 116 | 117 | void VolumeLeveler::Exchange_n(value_t **in_bufs, value_t **out_bufs, size_t in_samples) 118 | { 119 | // for each user_pos in user_buf 120 | for(size_t user_pos = 0; user_pos < in_samples; ++user_pos) { 121 | 122 | // compute multiplier 123 | value_t multiplier = pow(avg_amp, -strength); 124 | 125 | // if avg_amp <= 0, then the above line sets multiplier to Inf, so 126 | // samples will scale to Inf or NaN. This causes a tick on the 127 | // first sample after a Flush() unless max_multiplier is not Inf. 128 | // hopefully this fix isn't too slow. 129 | if(unlikely(avg_amp <= 0)) multiplier = 0; 130 | 131 | // untested! 132 | // The advantage of using floats is that you can be 133 | // sloppy with going over 1. Since we have this nifty 134 | // average_amp calculation, let's apply it to limit 135 | // the audio to varying normally below 1. Again, 136 | // hopefully this won't slow things down too much. 137 | if(unlikely(avg_amp > 1)) multiplier = 1 / avg_amp; 138 | 139 | // limit multiplier to max_multiplier. max_multiplier can be Inf 140 | // to disable this. 141 | if(unlikely(multiplier > max_multiplier)) multiplier = max_multiplier; 142 | 143 | // swap buf[pos] with user_buf[user_pos], scaling user[buf] by 144 | // multiplier and finding max of the new sample 145 | value_t new_val = 0; 146 | for(size_t ch = 0; ch < channels; ++ch) { 147 | value_t in = in_bufs[ch][user_pos]; 148 | out_bufs[ch][user_pos] = bufs[ch][pos] * multiplier; 149 | bufs[ch][pos] = in; 150 | if(VLEVEL_ABS(in) > new_val) new_val = VLEVEL_ABS(in); 151 | } 152 | 153 | pos = (pos + 1) % samples; // now pos is the oldest, new one is pos-1 154 | 155 | avg_amp += max_slope; 156 | 157 | if(unlikely(pos == max_slope_pos)) { 158 | // recompute (this is expensive) 159 | max_slope = -HUGE_VAL; 160 | for(size_t i = 1; i < samples; ++i) { 161 | value_t sample_val = 0; 162 | for(size_t ch = 0; ch < channels; ++ch) { 163 | value_t ch_val = VLEVEL_ABS(bufs[ch][(pos + i) % samples]); 164 | if(ch_val > sample_val) sample_val = ch_val; 165 | } 166 | value_t slope = (sample_val - avg_amp) / i; 167 | // must be >=, otherwise clipping causes excessive computation 168 | // TODO: maybe optimize - just save i, then compute slope, pos, and val only once later. 169 | // maybe unlikely() 170 | if(unlikely(slope >= max_slope)) { 171 | max_slope_pos = (pos + i) % samples; 172 | max_slope = slope; 173 | max_slope_val = sample_val; 174 | } 175 | } 176 | } else { 177 | // only chance of higher slope is the new sample 178 | 179 | // recomputing max_slope isn't really necessary... 180 | max_slope = (max_slope_val - avg_amp) / ((max_slope_pos - pos + samples) % samples); 181 | // ...but it doesn't take long and has a small effect. 182 | 183 | value_t slope = (new_val - avg_amp) / (samples - 1); 184 | 185 | // probably needs to be >= for same reason as above 186 | // maybe unlikely() 187 | if(unlikely(slope >= max_slope)) { 188 | max_slope_pos = (pos - 1) % samples; 189 | max_slope = slope; 190 | max_slope_val = new_val; 191 | } 192 | } 193 | } 194 | } 195 | 196 | // this code has been proven correct, but not tested much. ;-) 197 | void ToValues(char *in, value_t *out, size_t values, 198 | size_t bits_per_value, bool has_sign) 199 | { 200 | switch(bits_per_value) { 201 | case 32: 202 | if(has_sign) { 203 | for(size_t i = 0; i < values; ++i) 204 | out[i] = ((value_t)((int32_t *)in)[i]) / 2147483648; 205 | } else { 206 | for(size_t i = 0; i < values; ++i) 207 | out[i] = (((value_t)((u_int32_t *)in)[i]) - 2147483648) / 2147483648; 208 | } 209 | break; 210 | case 16: 211 | if(has_sign) { 212 | for(size_t i = 0; i < values; ++i) 213 | out[i] = ((value_t)((int16_t *)in)[i]) / 32768; 214 | } else { 215 | for(size_t i = 0; i < values; ++i) 216 | out[i] = (((value_t)((u_int16_t *)in)[i]) - 32768) / 32768; 217 | } 218 | break; 219 | case 8: 220 | if(has_sign) { 221 | for(size_t i = 0; i < values; ++i) 222 | out[i] = ((value_t)((int8_t *)in)[i]) / 128; 223 | } else { 224 | for(size_t i = 0; i < values; ++i) 225 | out[i] = (((value_t)((u_int8_t *)in)[i]) - 128) / 128; 226 | } 227 | break; 228 | default: 229 | assert(false); 230 | } 231 | } 232 | 233 | 234 | // note: no clipping, just wrap. I don't know how badly clipping will perform. 235 | void FromValues(value_t *in, char *out, size_t values, 236 | size_t bits_per_value, bool has_sign) 237 | { 238 | switch(bits_per_value) { 239 | case 32: 240 | if(has_sign) { 241 | for(size_t i = 0; i < values; ++i) 242 | ((int32_t *)out)[i] = (int32_t)(in[i] * 2147483647); 243 | } else { 244 | for(size_t i = 0; i < values; ++i) 245 | ((u_int32_t *)out)[i] = (u_int32_t)((in[i] * 2147483647) + 2147483647); 246 | } 247 | break; 248 | case 16: 249 | if(has_sign) { 250 | for(size_t i = 0; i < values; ++i) 251 | ((int16_t *)out)[i] = (int16_t)(in[i] * 32767); 252 | } else { 253 | for(size_t i = 0; i < values; ++i) 254 | ((u_int16_t *)out)[i] = (u_int16_t)((in[i] * 32767) + 32767); 255 | } 256 | break; 257 | case 8: 258 | if(has_sign) { 259 | for(size_t i = 0; i < values; ++i) 260 | ((int8_t *)out)[i] = (int8_t)(in[i] * 127); 261 | } else { 262 | for(size_t i = 0; i < values; ++i) 263 | ((u_int8_t *)out)[i] = (u_int8_t)((in[i] * 127) + 127); 264 | } 265 | break; 266 | default: 267 | assert(false); 268 | } 269 | } 270 | 271 | -------------------------------------------------------------------------------- /vlevel-jack/vlevel-jack.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of VLevel, a dynamic volume normalizer. 2 | 3 | // ___ _ _ _ _ _ _ 4 | // | _ \__ _ __| (_)___ __(_)__| |___| |_| |_ __ _ 5 | // | / _` / _` | / _ \/ _| / _| / -_) _| _/ _` | 6 | // |_|_\__,_\__,_|_\___/\__|_\__|_\___|\__|\__\__,_| 7 | // La radio sempre in bolletta. 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "../volumeleveler/volumeleveler.h" 26 | #include "commandline.h" 27 | 28 | using namespace std; 29 | 30 | typedef jack_default_audio_sample_t sample_t; 31 | 32 | size_t sample_size = sizeof(jack_default_audio_sample_t); 33 | 34 | size_t lookahead_size = 512; 35 | size_t channels = 2; 36 | value_t strength = .8; 37 | value_t max_multiplier = 20; 38 | 39 | jack_client_t * client = NULL; 40 | VolumeLeveler * leveler = NULL; 41 | 42 | jack_port_t ** input_ports = NULL; 43 | jack_port_t ** output_ports = NULL; 44 | 45 | value_t ** input_bufferlist = NULL; 46 | value_t ** output_bufferlist = NULL; 47 | 48 | int vlevel_buffer_size_change_callback(jack_nframes_t nframes, void *arg) 49 | { 50 | if (leveler) 51 | { 52 | delete leveler; 53 | 54 | free(input_bufferlist); 55 | free(output_bufferlist); 56 | } 57 | 58 | input_bufferlist = (value_t **) calloc(channels, sizeof(value_t *)); 59 | output_bufferlist = (value_t **) calloc(channels, sizeof(value_t *)); 60 | 61 | leveler = new VolumeLeveler(lookahead_size, 62 | channels, 63 | strength, 64 | max_multiplier); 65 | 66 | return 0; 67 | } 68 | 69 | int vlevel_process_callback(jack_nframes_t nframes, void *arg) 70 | { 71 | for (size_t i = 0; i < channels; i++) 72 | { 73 | sample_t * jack_input = (sample_t *)jack_port_get_buffer(input_ports[i], nframes); 74 | sample_t * jack_output = (sample_t *)jack_port_get_buffer(output_ports[i], nframes); 75 | 76 | input_bufferlist[i] = jack_input; 77 | output_bufferlist[i] = jack_output; 78 | } 79 | 80 | leveler->Exchange(input_bufferlist, output_bufferlist, nframes); 81 | 82 | return 0; 83 | } 84 | 85 | void jack_shutdown(void *arg) 86 | { 87 | cout << "Jack server shutdown" << endl; 88 | exit(0); 89 | } 90 | 91 | void vlevel_help(const char* program) 92 | { 93 | cerr << "VLevel v" << VLEVEL_VERSION << " JACK edition" << endl 94 | << endl 95 | << "usage:" << endl 96 | << "\t" << program << " [options]" << endl 97 | << endl 98 | << "options: (abbreviations also work)" << endl 99 | << "\t--length num" << endl 100 | << "\t\tSize of the lookahead buffer. The longer, the slowest" << endl 101 | << "\t\tDefault is 512" << endl 102 | << "\t--channels num" << endl 103 | << "\t\tEach sample has num channels" << endl 104 | << "\t\tDefault is 2" << endl 105 | << "\t--strength num" << endl 106 | << "\t\tEffect strength, 1 is max, 0 is no effect." << endl 107 | << "\t\tDefault is .8" << endl 108 | << "\t--max-multiplier num" << endl 109 | << "\t\tSets the maximum amount a sample will be multiplied" << endl 110 | << "\t\tDefault is 20" << endl 111 | << "\t--undo" << endl 112 | << "\t\tReverses the effect of a previous VLevel" << endl; 113 | } 114 | 115 | int vlevel_parse_options( 116 | // in 117 | int argc, 118 | const char *const* argv, 119 | 120 | // out 121 | size_t * lookahead_size, 122 | size_t * channels, 123 | value_t * strength, 124 | value_t * max_multiplier 125 | ) 126 | { 127 | string option; 128 | string argument; 129 | 130 | bool undo(false); 131 | CommandLine cmd(argc, argv); 132 | 133 | while(option = cmd.GetOption(), !option.empty()) { 134 | if(option == "length" || option == "l") { 135 | if((istringstream(cmd.GetArgument()) >> *lookahead_size).fail()) { 136 | cerr << cmd.GetProgramName() << ": bad or no option for --length" << endl; 137 | return 2; 138 | } 139 | if(*channels < 1) { 140 | cerr << cmd.GetProgramName() << ": --channels must be greater than 0" << endl; 141 | return 2; 142 | } 143 | } else if(option == "channels" || option == "c") { 144 | if((istringstream(cmd.GetArgument()) >> *channels).fail()) { 145 | cerr << cmd.GetProgramName() << ": bad or no option for --channels" << endl; 146 | return 2; 147 | } 148 | if(*channels < 1) { 149 | cerr << cmd.GetProgramName() << ": --channels must be greater than 0" << endl; 150 | return 2; 151 | } 152 | } else if(option == "strength" || option == "s") { 153 | if((istringstream(cmd.GetArgument()) >> *strength).fail()) { 154 | cerr << cmd.GetProgramName() << ": bad or no option for --strength" << endl; 155 | return 2; 156 | } 157 | if(*strength < 0 || *strength > 1) { 158 | cerr << cmd.GetProgramName() << ": --strength must be between 0 and 1 inclusive." << endl; 159 | return 2; 160 | } 161 | } else if(option == "max-multiplier" || option == "m") { 162 | if((istringstream(cmd.GetArgument()) >> *max_multiplier).fail()) { 163 | cerr << cmd.GetProgramName() << ": bad or no option for --max-multiplier" << endl 164 | << cmd.GetProgramName() << ": for no max multiplier, give a negative number" << endl; 165 | return 2; 166 | } 167 | } else if(option == "undo" || option == "u") { 168 | undo = true; 169 | } else if(option == "help" || option == "h") { 170 | vlevel_help(argv[0]); 171 | exit(0); 172 | } else { 173 | cerr << cmd.GetProgramName() << ": unrecognized option " << option << endl; 174 | vlevel_help(argv[0]); 175 | return 2; 176 | } 177 | } 178 | 179 | // This works, see docs/technical.txt 180 | if(undo) 181 | *strength = *strength / (*strength - 1); 182 | 183 | return 0; 184 | } 185 | 186 | int main(int argc, char *argv[]) 187 | { 188 | int retval = vlevel_parse_options(argc, argv, &lookahead_size, &channels, &strength, &max_multiplier); 189 | if (retval != 0) 190 | exit(retval); 191 | 192 | cerr << "Beginning VLevel with:" << endl 193 | << "channels: " << channels << endl 194 | << "strength: " << strength << endl 195 | << "max_multiplier: " << max_multiplier << endl; 196 | 197 | if ((client = jack_client_open("vlevel", JackNullOption, NULL)) == 0) { 198 | cerr << "jack server not running?" << endl; 199 | return 1; 200 | } 201 | 202 | if (jack_set_buffer_size_callback(client, vlevel_buffer_size_change_callback, NULL)) { 203 | cerr << "failed to set buffer size callback" << endl; 204 | return 1; 205 | } 206 | 207 | jack_on_shutdown (client, jack_shutdown, NULL); 208 | 209 | input_ports = (jack_port_t **)calloc(channels, sizeof(jack_port_t *)); 210 | output_ports = (jack_port_t **)calloc(channels, sizeof(jack_port_t *)); 211 | 212 | char out [256]; 213 | char in [256]; 214 | 215 | for (size_t i = 0; i < channels; i++){ 216 | snprintf(in, sizeof(in), "capture_%ld", i + 1); 217 | snprintf(out, sizeof(out), "playback_%ld", i + 1); 218 | 219 | input_ports[i] = jack_port_register(client, 220 | in, 221 | JACK_DEFAULT_AUDIO_TYPE, 222 | JackPortIsInput, 223 | 0); 224 | 225 | output_ports[i] = jack_port_register(client, 226 | out, 227 | JACK_DEFAULT_AUDIO_TYPE, 228 | JackPortIsOutput, 229 | 0); 230 | } 231 | 232 | if (jack_set_process_callback(client, vlevel_process_callback, NULL)) { 233 | cerr << "cannot set process callback" << endl; 234 | return 1; 235 | } 236 | 237 | if (jack_activate (client)) { 238 | cerr << "cannot activate client" << endl; 239 | return 1; 240 | } 241 | 242 | sleep(-1); 243 | return 0; 244 | } 245 | -------------------------------------------------------------------------------- /vlevel-winamp/gpl.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | 504 | 505 | -------------------------------------------------------------------------------- /vlevel-winamp/vlevel/lgpl.txt: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | , 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | 504 | 505 | -------------------------------------------------------------------------------- /vlevel-ladspa/ladspa.h: -------------------------------------------------------------------------------- 1 | /* ladspa.h 2 | 3 | Linux Audio Developer's Simple Plugin API Version 1.1[LGPL]. 4 | Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, 5 | Stefan Westerfeld. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public License 9 | as published by the Free Software Foundation; either version 2.1 of 10 | the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 | USA. */ 21 | 22 | #ifndef LADSPA_INCLUDED 23 | #define LADSPA_INCLUDED 24 | 25 | #define LADSPA_VERSION "1.1" 26 | #define LADSPA_VERSION_MAJOR 1 27 | #define LADSPA_VERSION_MINOR 1 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /*****************************************************************************/ 34 | 35 | /* Overview: 36 | 37 | There is a large number of synthesis packages in use or development 38 | on the Linux platform at this time. This API (`The Linux Audio 39 | Developer's Simple Plugin API') attempts to give programmers the 40 | ability to write simple `plugin' audio processors in C/C++ and link 41 | them dynamically (`plug') into a range of these packages (`hosts'). 42 | It should be possible for any host and any plugin to communicate 43 | completely through this interface. 44 | 45 | This API is deliberately short and simple. To achieve compatibility 46 | with a range of promising Linux sound synthesis packages it 47 | attempts to find the `greatest common divisor' in their logical 48 | behaviour. Having said this, certain limiting decisions are 49 | implicit, notably the use of a fixed type (LADSPA_Data) for all 50 | data transfer and absence of a parameterised `initialisation' 51 | phase. See below for the LADSPA_Data typedef. 52 | 53 | Plugins are expected to distinguish between control and audio 54 | data. Plugins have `ports' that are inputs or outputs for audio or 55 | control data and each plugin is `run' for a `block' corresponding 56 | to a short time interval measured in samples. Audio data is 57 | communicated using arrays of LADSPA_Data, allowing a block of audio 58 | to be processed by the plugin in a single pass. Control data is 59 | communicated using single LADSPA_Data values. Control data has a 60 | single value at the start of a call to the `run()' or `run_adding()' 61 | function, and may be considered to remain this value for its 62 | duration. The plugin may assume that all its input and output ports 63 | have been connected to the relevant data location (see the 64 | `connect_port()' function below) before it is asked to run. 65 | 66 | Plugins will reside in shared object files suitable for dynamic 67 | linking by dlopen() and family. The file will provide a number of 68 | `plugin types' that can be used to instantiate actual plugins 69 | (sometimes known as `plugin instances') that can be connected 70 | together to perform tasks. 71 | 72 | This API contains very limited error-handling. */ 73 | 74 | /*****************************************************************************/ 75 | 76 | /* Fundamental data type passed in and out of plugin. This data type 77 | is used to communicate audio samples and control values. It is 78 | assumed that the plugin will work sensibly given any numeric input 79 | value although it may have a preferred range (see hints below). 80 | 81 | For audio it is generally assumed that 1.0f is the `0dB' reference 82 | amplitude and is a `normal' signal level. */ 83 | 84 | typedef float LADSPA_Data; 85 | 86 | /*****************************************************************************/ 87 | 88 | /* Special Plugin Properties: 89 | 90 | Optional features of the plugin type are encapsulated in the 91 | LADSPA_Properties type. This is assembled by ORing individual 92 | properties together. */ 93 | 94 | typedef int LADSPA_Properties; 95 | 96 | /* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a 97 | real-time dependency (e.g. listens to a MIDI device) and so its 98 | output must not be cached or subject to significant latency. */ 99 | #define LADSPA_PROPERTY_REALTIME 0x1 100 | 101 | /* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin 102 | may cease to work correctly if the host elects to use the same data 103 | location for both input and output (see connect_port()). This 104 | should be avoided as enabling this flag makes it impossible for 105 | hosts to use the plugin to process audio `in-place.' */ 106 | #define LADSPA_PROPERTY_INPLACE_BROKEN 0x2 107 | 108 | /* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin 109 | is capable of running not only in a conventional host but also in a 110 | `hard real-time' environment. To qualify for this the plugin must 111 | satisfy all of the following: 112 | 113 | (1) The plugin must not use malloc(), free() or other heap memory 114 | management within its run() or run_adding() functions. All new 115 | memory used in run() must be managed via the stack. These 116 | restrictions only apply to the run() function. 117 | 118 | (2) The plugin will not attempt to make use of any library 119 | functions with the exceptions of functions in the ANSI standard C 120 | and C maths libraries, which the host is expected to provide. 121 | 122 | (3) The plugin will not access files, devices, pipes, sockets, IPC 123 | or any other mechanism that might result in process or thread 124 | blocking. 125 | 126 | (4) The plugin will take an amount of time to execute a run() or 127 | run_adding() call approximately of form (A+B*SampleCount) where A 128 | and B depend on the machine and host in use. This amount of time 129 | may not depend on input signals or plugin state. The host is left 130 | the responsibility to perform timings to estimate upper bounds for 131 | A and B. */ 132 | #define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4 133 | 134 | #define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME) 135 | #define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN) 136 | #define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE) 137 | 138 | /*****************************************************************************/ 139 | 140 | /* Plugin Ports: 141 | 142 | Plugins have `ports' that are inputs or outputs for audio or 143 | data. Ports can communicate arrays of LADSPA_Data (for audio 144 | inputs/outputs) or single LADSPA_Data values (for control 145 | input/outputs). This information is encapsulated in the 146 | LADSPA_PortDescriptor type which is assembled by ORing individual 147 | properties together. 148 | 149 | Note that a port must be an input or an output port but not both 150 | and that a port must be a control or audio port but not both. */ 151 | 152 | typedef int LADSPA_PortDescriptor; 153 | 154 | /* Property LADSPA_PORT_INPUT indicates that the port is an input. */ 155 | #define LADSPA_PORT_INPUT 0x1 156 | 157 | /* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */ 158 | #define LADSPA_PORT_OUTPUT 0x2 159 | 160 | /* Property LADSPA_PORT_CONTROL indicates that the port is a control 161 | port. */ 162 | #define LADSPA_PORT_CONTROL 0x4 163 | 164 | /* Property LADSPA_PORT_AUDIO indicates that the port is a audio 165 | port. */ 166 | #define LADSPA_PORT_AUDIO 0x8 167 | 168 | #define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT) 169 | #define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT) 170 | #define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL) 171 | #define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO) 172 | 173 | /*****************************************************************************/ 174 | 175 | /* Plugin Port Range Hints: 176 | 177 | The host may wish to provide a representation of data entering or 178 | leaving a plugin (e.g. to generate a GUI automatically). To make 179 | this more meaningful, the plugin should provide `hints' to the host 180 | describing the usual values taken by the data. 181 | 182 | Note that these are only hints. The host may ignore them and the 183 | plugin must not assume that data supplied to it is meaningful. If 184 | the plugin receives invalid input data it is expected to continue 185 | to run without failure and, where possible, produce a sensible 186 | output (e.g. a high-pass filter given a negative cutoff frequency 187 | might switch to an all-pass mode). 188 | 189 | Hints are meaningful for all input and output ports but hints for 190 | input control ports are expected to be particularly useful. 191 | 192 | More hint information is encapsulated in the 193 | LADSPA_PortRangeHintDescriptor type which is assembled by ORing 194 | individual hint types together. Hints may require further 195 | LowerBound and UpperBound information. 196 | 197 | All the hint information for a particular port is aggregated in the 198 | LADSPA_PortRangeHint structure. */ 199 | 200 | typedef int LADSPA_PortRangeHintDescriptor; 201 | 202 | /* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field 203 | of the LADSPA_PortRangeHint should be considered meaningful. The 204 | value in this field should be considered the (inclusive) lower 205 | bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also 206 | specified then the value of LowerBound should be multiplied by the 207 | sample rate. */ 208 | #define LADSPA_HINT_BOUNDED_BELOW 0x1 209 | 210 | /* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field 211 | of the LADSPA_PortRangeHint should be considered meaningful. The 212 | value in this field should be considered the (inclusive) upper 213 | bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also 214 | specified then the value of UpperBound should be multiplied by the 215 | sample rate. */ 216 | #define LADSPA_HINT_BOUNDED_ABOVE 0x2 217 | 218 | /* Hint LADSPA_HINT_TOGGLED indicates that the data item should be 219 | considered a Boolean toggle. Data less than or equal to zero should 220 | be considered `off' or `false,' and data above zero should be 221 | considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in 222 | conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or 223 | LADSPA_HINT_DEFAULT_1. */ 224 | #define LADSPA_HINT_TOGGLED 0x4 225 | 226 | /* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified 227 | should be interpreted as multiples of the sample rate. For 228 | instance, a frequency range from 0Hz to the Nyquist frequency (half 229 | the sample rate) could be requested by this hint in conjunction 230 | with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds 231 | at all must support this hint to retain meaning. */ 232 | #define LADSPA_HINT_SAMPLE_RATE 0x8 233 | 234 | /* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the 235 | user will find it more intuitive to view values using a logarithmic 236 | scale. This is particularly useful for frequencies and gains. */ 237 | #define LADSPA_HINT_LOGARITHMIC 0x10 238 | 239 | /* Hint LADSPA_HINT_INTEGER indicates that a user interface would 240 | probably wish to provide a stepped control taking only integer 241 | values. Any bounds set should be slightly wider than the actual 242 | integer range required to avoid floating point rounding errors. For 243 | instance, the integer set {0,1,2,3} might be described as [-0.1, 244 | 3.1]. */ 245 | #define LADSPA_HINT_INTEGER 0x20 246 | 247 | /* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal' 248 | value for the port that is sensible as a default. For instance, 249 | this value is suitable for use as an initial value in a user 250 | interface or as a value the host might assign to a control port 251 | when the user has not provided one. Defaults are encoded using a 252 | mask so only one default may be specified for a port. Some of the 253 | hints make use of lower and upper bounds, in which case the 254 | relevant bound or bounds must be available and 255 | LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting 256 | default must be rounded if LADSPA_HINT_INTEGER is present. Default 257 | values were introduced in LADSPA v1.1. */ 258 | #define LADSPA_HINT_DEFAULT_MASK 0x3C0 259 | 260 | /* This default values indicates that no default is provided. */ 261 | #define LADSPA_HINT_DEFAULT_NONE 0x0 262 | 263 | /* This default hint indicates that the suggested lower bound for the 264 | port should be used. */ 265 | #define LADSPA_HINT_DEFAULT_MINIMUM 0x40 266 | 267 | /* This default hint indicates that a low value between the suggested 268 | lower and upper bounds should be chosen. For ports with 269 | LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 + 270 | log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper 271 | * 0.25). */ 272 | #define LADSPA_HINT_DEFAULT_LOW 0x80 273 | 274 | /* This default hint indicates that a middle value between the 275 | suggested lower and upper bounds should be chosen. For ports with 276 | LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 + 277 | log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper * 278 | 0.5). */ 279 | #define LADSPA_HINT_DEFAULT_MIDDLE 0xC0 280 | 281 | /* This default hint indicates that a high value between the suggested 282 | lower and upper bounds should be chosen. For ports with 283 | LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 + 284 | log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper 285 | * 0.75). */ 286 | #define LADSPA_HINT_DEFAULT_HIGH 0x100 287 | 288 | /* This default hint indicates that the suggested upper bound for the 289 | port should be used. */ 290 | #define LADSPA_HINT_DEFAULT_MAXIMUM 0x140 291 | 292 | /* This default hint indicates that the number 0 should be used. Note 293 | that this default may be used in conjunction with 294 | LADSPA_HINT_TOGGLED. */ 295 | #define LADSPA_HINT_DEFAULT_0 0x200 296 | 297 | /* This default hint indicates that the number 1 should be used. Note 298 | that this default may be used in conjunction with 299 | LADSPA_HINT_TOGGLED. */ 300 | #define LADSPA_HINT_DEFAULT_1 0x240 301 | 302 | /* This default hint indicates that the number 100 should be used. */ 303 | #define LADSPA_HINT_DEFAULT_100 0x280 304 | 305 | /* This default hint indicates that the Hz frequency of `concert A' 306 | should be used. This will be 440 unless the host uses an unusual 307 | tuning convention, in which case it may be within a few Hz. */ 308 | #define LADSPA_HINT_DEFAULT_440 0x2C0 309 | 310 | #define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW) 311 | #define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE) 312 | #define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED) 313 | #define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE) 314 | #define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC) 315 | #define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER) 316 | 317 | #define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK) 318 | #define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 319 | == LADSPA_HINT_DEFAULT_MINIMUM) 320 | #define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 321 | == LADSPA_HINT_DEFAULT_LOW) 322 | #define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 323 | == LADSPA_HINT_DEFAULT_MIDDLE) 324 | #define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 325 | == LADSPA_HINT_DEFAULT_HIGH) 326 | #define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 327 | == LADSPA_HINT_DEFAULT_MAXIMUM) 328 | #define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 329 | == LADSPA_HINT_DEFAULT_0) 330 | #define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 331 | == LADSPA_HINT_DEFAULT_1) 332 | #define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 333 | == LADSPA_HINT_DEFAULT_100) 334 | #define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \ 335 | == LADSPA_HINT_DEFAULT_440) 336 | 337 | typedef struct _LADSPA_PortRangeHint { 338 | 339 | /* Hints about the port. */ 340 | LADSPA_PortRangeHintDescriptor HintDescriptor; 341 | 342 | /* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When 343 | LADSPA_HINT_SAMPLE_RATE is also active then this value should be 344 | multiplied by the relevant sample rate. */ 345 | LADSPA_Data LowerBound; 346 | 347 | /* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When 348 | LADSPA_HINT_SAMPLE_RATE is also active then this value should be 349 | multiplied by the relevant sample rate. */ 350 | LADSPA_Data UpperBound; 351 | 352 | } LADSPA_PortRangeHint; 353 | 354 | /*****************************************************************************/ 355 | 356 | /* Plugin Handles: 357 | 358 | This plugin handle indicates a particular instance of the plugin 359 | concerned. It is valid to compare this to NULL (0 for C++) but 360 | otherwise the host should not attempt to interpret it. The plugin 361 | may use it to reference internal instance data. */ 362 | 363 | typedef void * LADSPA_Handle; 364 | 365 | /*****************************************************************************/ 366 | 367 | /* Descriptor for a Type of Plugin: 368 | 369 | This structure is used to describe a plugin type. It provides a 370 | number of functions to examine the type, instantiate it, link it to 371 | buffers and workspaces and to run it. */ 372 | 373 | typedef struct _LADSPA_Descriptor { 374 | 375 | /* This numeric identifier indicates the plugin type 376 | uniquely. Plugin programmers may reserve ranges of IDs from a 377 | central body to avoid clashes. Hosts may assume that IDs are 378 | below 0x1000000. */ 379 | unsigned long UniqueID; 380 | 381 | /* This identifier can be used as a unique, case-sensitive 382 | identifier for the plugin type within the plugin file. Plugin 383 | types should be identified by file and label rather than by index 384 | or plugin name, which may be changed in new plugin 385 | versions. Labels must not contain white-space characters. */ 386 | const char * Label; 387 | 388 | /* This indicates a number of properties of the plugin. */ 389 | LADSPA_Properties Properties; 390 | 391 | /* This member points to the null-terminated name of the plugin 392 | (e.g. "Sine Oscillator"). */ 393 | const char * Name; 394 | 395 | /* This member points to the null-terminated string indicating the 396 | maker of the plugin. This can be an empty string but not NULL. */ 397 | const char * Maker; 398 | 399 | /* This member points to the null-terminated string indicating any 400 | copyright applying to the plugin. If no Copyright applies the 401 | string "None" should be used. */ 402 | const char * Copyright; 403 | 404 | /* This indicates the number of ports (input AND output) present on 405 | the plugin. */ 406 | unsigned long PortCount; 407 | 408 | /* This member indicates an array of port descriptors. Valid indices 409 | vary from 0 to PortCount-1. */ 410 | const LADSPA_PortDescriptor * PortDescriptors; 411 | 412 | /* This member indicates an array of null-terminated strings 413 | describing ports (e.g. "Frequency (Hz)"). Valid indices vary from 414 | 0 to PortCount-1. */ 415 | const char * const * PortNames; 416 | 417 | /* This member indicates an array of range hints for each port (see 418 | above). Valid indices vary from 0 to PortCount-1. */ 419 | const LADSPA_PortRangeHint * PortRangeHints; 420 | 421 | /* This may be used by the plugin developer to pass any custom 422 | implementation data into an instantiate call. It must not be used 423 | or interpreted by the host. It is expected that most plugin 424 | writers will not use this facility as LADSPA_Handle should be 425 | used to hold instance data. */ 426 | void * ImplementationData; 427 | 428 | /* This member is a function pointer that instantiates a plugin. A 429 | handle is returned indicating the new plugin instance. The 430 | instantiation function accepts a sample rate as a parameter. The 431 | plugin descriptor from which this instantiate function was found 432 | must also be passed. This function must return NULL if 433 | instantiation fails. 434 | 435 | Note that instance initialisation should generally occur in 436 | activate() rather than here. */ 437 | LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor, 438 | unsigned long SampleRate); 439 | 440 | /* This member is a function pointer that connects a port on an 441 | instantiated plugin to a memory location at which a block of data 442 | for the port will be read/written. The data location is expected 443 | to be an array of LADSPA_Data for audio ports or a single 444 | LADSPA_Data value for control ports. Memory issues will be 445 | managed by the host. The plugin must read/write the data at these 446 | locations every time run() or run_adding() is called and the data 447 | present at the time of this connection call should not be 448 | considered meaningful. 449 | 450 | connect_port() may be called more than once for a plugin instance 451 | to allow the host to change the buffers that the plugin is 452 | reading or writing. These calls may be made before or after 453 | activate() or deactivate() calls. 454 | 455 | connect_port() must be called at least once for each port before 456 | run() or run_adding() is called. When working with blocks of 457 | LADSPA_Data the plugin should pay careful attention to the block 458 | size passed to the run function as the block allocated may only 459 | just be large enough to contain the block of samples. 460 | 461 | Plugin writers should be aware that the host may elect to use the 462 | same buffer for more than one port and even use the same buffer 463 | for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN). 464 | However, overlapped buffers or use of a single buffer for both 465 | audio and control data may result in unexpected behaviour. */ 466 | void (*connect_port)(LADSPA_Handle Instance, 467 | unsigned long Port, 468 | LADSPA_Data * DataLocation); 469 | 470 | /* This member is a function pointer that initialises a plugin 471 | instance and activates it for use. This is separated from 472 | instantiate() to aid real-time support and so that hosts can 473 | reinitialise a plugin instance by calling deactivate() and then 474 | activate(). In this case the plugin instance must reset all state 475 | information dependent on the history of the plugin instance 476 | except for any data locations provided by connect_port() and any 477 | gain set by set_run_adding_gain(). If there is nothing for 478 | activate() to do then the plugin writer may provide a NULL rather 479 | than an empty function. 480 | 481 | When present, hosts must call this function once before run() (or 482 | run_adding()) is called for the first time. This call should be 483 | made as close to the run() call as possible and indicates to 484 | real-time plugins that they are now live. Plugins should not rely 485 | on a prompt call to run() after activate(). activate() may not be 486 | called again unless deactivate() is called first. Note that 487 | connect_port() may be called before or after a call to 488 | activate(). */ 489 | void (*activate)(LADSPA_Handle Instance); 490 | 491 | /* This method is a function pointer that runs an instance of a 492 | plugin for a block. Two parameters are required: the first is a 493 | handle to the particular instance to be run and the second 494 | indicates the block size (in samples) for which the plugin 495 | instance may run. 496 | 497 | Note that if an activate() function exists then it must be called 498 | before run() or run_adding(). If deactivate() is called for a 499 | plugin instance then the plugin instance may not be reused until 500 | activate() has been called again. 501 | 502 | If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE 503 | then there are various things that the plugin should not do 504 | within the run() or run_adding() functions (see above). */ 505 | void (*run)(LADSPA_Handle Instance, 506 | unsigned long SampleCount); 507 | 508 | /* This method is a function pointer that runs an instance of a 509 | plugin for a block. This has identical behaviour to run() except 510 | in the way data is output from the plugin. When run() is used, 511 | values are written directly to the memory areas associated with 512 | the output ports. However when run_adding() is called, values 513 | must be added to the values already present in the memory 514 | areas. Furthermore, output values written must be scaled by the 515 | current gain set by set_run_adding_gain() (see below) before 516 | addition. 517 | 518 | run_adding() is optional. When it is not provided by a plugin, 519 | this function pointer must be set to NULL. When it is provided, 520 | the function set_run_adding_gain() must be provided also. */ 521 | void (*run_adding)(LADSPA_Handle Instance, 522 | unsigned long SampleCount); 523 | 524 | /* This method is a function pointer that sets the output gain for 525 | use when run_adding() is called (see above). If this function is 526 | never called the gain is assumed to default to 1. Gain 527 | information should be retained when activate() or deactivate() 528 | are called. 529 | 530 | This function should be provided by the plugin if and only if the 531 | run_adding() function is provided. When it is absent this 532 | function pointer must be set to NULL. */ 533 | void (*set_run_adding_gain)(LADSPA_Handle Instance, 534 | LADSPA_Data Gain); 535 | 536 | /* This is the counterpart to activate() (see above). If there is 537 | nothing for deactivate() to do then the plugin writer may provide 538 | a NULL rather than an empty function. 539 | 540 | Hosts must deactivate all activated units after they have been 541 | run() (or run_adding()) for the last time. This call should be 542 | made as close to the last run() call as possible and indicates to 543 | real-time plugins that they are no longer live. Plugins should 544 | not rely on prompt deactivation. Note that connect_port() may be 545 | called before or after a call to deactivate(). 546 | 547 | Deactivation is not similar to pausing as the plugin instance 548 | will be reinitialised when activate() is called to reuse it. */ 549 | void (*deactivate)(LADSPA_Handle Instance); 550 | 551 | /* Once an instance of a plugin has been finished with it can be 552 | deleted using the following function. The instance handle passed 553 | ceases to be valid after this call. 554 | 555 | If activate() was called for a plugin instance then a 556 | corresponding call to deactivate() must be made before cleanup() 557 | is called. */ 558 | void (*cleanup)(LADSPA_Handle Instance); 559 | 560 | } LADSPA_Descriptor; 561 | 562 | /**********************************************************************/ 563 | 564 | /* Accessing a Plugin: */ 565 | 566 | /* The exact mechanism by which plugins are loaded is host-dependent, 567 | however all most hosts will need to know is the name of shared 568 | object file containing the plugin types. To allow multiple hosts to 569 | share plugin types, hosts may wish to check for environment 570 | variable LADSPA_PATH. If present, this should contain a 571 | colon-separated path indicating directories that should be searched 572 | (in order) when loading plugin types. 573 | 574 | A plugin programmer must include a function called 575 | "ladspa_descriptor" with the following function prototype within 576 | the shared object file. This function will have C-style linkage (if 577 | you are using C++ this is taken care of by the `extern "C"' clause 578 | at the top of the file). 579 | 580 | A host will find the plugin shared object file by one means or 581 | another, find the ladspa_descriptor() function, call it, and 582 | proceed from there. 583 | 584 | Plugin types are accessed by index (not ID) using values from 0 585 | upwards. Out of range indexes must result in this function 586 | returning NULL, so the plugin count can be determined by checking 587 | for the least index that results in NULL being returned. */ 588 | 589 | const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index); 590 | 591 | /* Datatype corresponding to the ladspa_descriptor() function. */ 592 | typedef const LADSPA_Descriptor * 593 | (*LADSPA_Descriptor_Function)(unsigned long Index); 594 | 595 | /**********************************************************************/ 596 | 597 | #ifdef __cplusplus 598 | } 599 | #endif 600 | 601 | #endif /* LADSPA_INCLUDED */ 602 | 603 | /* EOF */ 604 | --------------------------------------------------------------------------------