fresh audaspace from trunk
authorJoseph Eagar <joeedh@gmail.com>
Sat, 4 Sep 2010 18:53:48 +0000 (18:53 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sat, 4 Sep 2010 18:53:48 +0000 (18:53 +0000)
161 files changed:
intern/audaspace/CMakeLists.txt [new file with mode: 0644]
intern/audaspace/COPYING [new file with mode: 0644]
intern/audaspace/COPYING.LESSER [new file with mode: 0644]
intern/audaspace/FX/AUD_AccumulatorFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_AccumulatorFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_BaseIIRFilterReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_ButterworthFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_ButterworthFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_CallbackIIRFilterReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_DelayFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_DelayFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_DelayReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_DelayReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_DoubleFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_DoubleFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_DoubleReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_DoubleReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_EffectFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_EffectFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_EffectReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_EffectReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_EnvelopeFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_EnvelopeFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_FaderFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_FaderFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_FaderReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_FaderReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_HighpassFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_HighpassFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_IIRFilterFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_IIRFilterFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_IIRFilterReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_IIRFilterReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_LimiterFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_LimiterFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_LimiterReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_LimiterReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_LoopFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_LoopFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_LoopReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_LoopReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_LowpassFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_LowpassFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_PingPongFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_PingPongFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_PitchFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_PitchFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_PitchReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_PitchReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_RectifyFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_RectifyFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_ReverseFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_ReverseFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_ReverseReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_ReverseReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_SquareFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SquareFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_SumFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SumFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_VolumeFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_VolumeFactory.h [new file with mode: 0644]
intern/audaspace/FX/Makefile [new file with mode: 0644]
intern/audaspace/Makefile [new file with mode: 0644]
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp [new file with mode: 0644]
intern/audaspace/OpenAL/AUD_OpenALDevice.h [new file with mode: 0644]
intern/audaspace/OpenAL/Makefile [new file with mode: 0644]
intern/audaspace/Python/AUD_PyAPI.cpp [new file with mode: 0644]
intern/audaspace/Python/AUD_PyAPI.h [new file with mode: 0644]
intern/audaspace/Python/Makefile [new file with mode: 0644]
intern/audaspace/SConscript [new file with mode: 0644]
intern/audaspace/SDL/AUD_SDLDevice.cpp [new file with mode: 0644]
intern/audaspace/SDL/AUD_SDLDevice.h [new file with mode: 0644]
intern/audaspace/SDL/Makefile [new file with mode: 0644]
intern/audaspace/SRC/AUD_SRCResampleFactory.cpp [new file with mode: 0644]
intern/audaspace/SRC/AUD_SRCResampleFactory.h [new file with mode: 0644]
intern/audaspace/SRC/AUD_SRCResampleReader.cpp [new file with mode: 0644]
intern/audaspace/SRC/AUD_SRCResampleReader.h [new file with mode: 0644]
intern/audaspace/SRC/Makefile [new file with mode: 0644]
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp [new file with mode: 0644]
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h [new file with mode: 0644]
intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp [new file with mode: 0644]
intern/audaspace/ffmpeg/AUD_FFMPEGReader.h [new file with mode: 0644]
intern/audaspace/ffmpeg/Makefile [new file with mode: 0644]
intern/audaspace/fftw/AUD_BandPassFactory.cpp [new file with mode: 0644]
intern/audaspace/fftw/AUD_BandPassFactory.h [new file with mode: 0644]
intern/audaspace/fftw/AUD_BandPassReader.cpp [new file with mode: 0644]
intern/audaspace/fftw/AUD_BandPassReader.h [new file with mode: 0644]
intern/audaspace/fftw/Makefile [new file with mode: 0644]
intern/audaspace/intern/AUD_3DMath.h [new file with mode: 0644]
intern/audaspace/intern/AUD_Buffer.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_Buffer.h [new file with mode: 0644]
intern/audaspace/intern/AUD_BufferReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_BufferReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_C-API.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_C-API.h [new file with mode: 0644]
intern/audaspace/intern/AUD_ChannelMapperFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ChannelMapperFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_ChannelMapperReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ChannelMapperReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_ConverterFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ConverterFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_ConverterFunctions.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ConverterFunctions.h [new file with mode: 0644]
intern/audaspace/intern/AUD_ConverterReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ConverterReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_DefaultMixer.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_DefaultMixer.h [new file with mode: 0644]
intern/audaspace/intern/AUD_FileFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_FileFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_I3DDevice.h [new file with mode: 0644]
intern/audaspace/intern/AUD_IDevice.h [new file with mode: 0644]
intern/audaspace/intern/AUD_IFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_IReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_LinearResampleFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_LinearResampleFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_LinearResampleReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_LinearResampleReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_Mixer.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_Mixer.h [new file with mode: 0644]
intern/audaspace/intern/AUD_MixerFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_MixerFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_NULLDevice.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_NULLDevice.h [new file with mode: 0644]
intern/audaspace/intern/AUD_PyInit.h [new file with mode: 0644]
intern/audaspace/intern/AUD_ReadDevice.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ReadDevice.h [new file with mode: 0644]
intern/audaspace/intern/AUD_Reference.h [new file with mode: 0644]
intern/audaspace/intern/AUD_ResampleFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SequencerFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_SequencerFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SequencerReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_SequencerReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SilenceFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_SilenceFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SilenceReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_SilenceReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SinusFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_SinusFactory.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SinusReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_SinusReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SoftwareDevice.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_SoftwareDevice.h [new file with mode: 0644]
intern/audaspace/intern/AUD_Space.h [new file with mode: 0644]
intern/audaspace/intern/AUD_StreamBufferFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_StreamBufferFactory.h [new file with mode: 0644]
intern/audaspace/intern/Makefile [new file with mode: 0644]
intern/audaspace/jack/AUD_JackDevice.cpp [new file with mode: 0644]
intern/audaspace/jack/AUD_JackDevice.h [new file with mode: 0644]
intern/audaspace/jack/Makefile [new file with mode: 0644]
intern/audaspace/make/msvc_9_0/audaspace.vcproj [new file with mode: 0644]
intern/audaspace/sndfile/AUD_SndFileFactory.cpp [new file with mode: 0644]
intern/audaspace/sndfile/AUD_SndFileFactory.h [new file with mode: 0644]
intern/audaspace/sndfile/AUD_SndFileReader.cpp [new file with mode: 0644]
intern/audaspace/sndfile/AUD_SndFileReader.h [new file with mode: 0644]
intern/audaspace/sndfile/Makefile [new file with mode: 0644]

diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b1ded10
--- /dev/null
@@ -0,0 +1,72 @@
+# $Id$
+# ***** BEGIN LGPL LICENSE BLOCK *****
+#
+# Copyright 2009 Jörg Hermann Müller
+#
+# This file is part of AudaSpace.
+#
+# AudaSpace is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# AudaSpace is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+#
+# ***** END LGPL LICENSE BLOCK *****
+
+SET(INC . intern FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC})
+
+FILE(GLOB SRC intern/*.cpp intern/*.h FX/*.cpp SRC/*.cpp)
+
+IF(WITH_FFMPEG)
+       SET(INC ${INC} ffmpeg ${FFMPEG_INC})
+       FILE(GLOB FFMPEGSRC ffmpeg/*.cpp)
+       ADD_DEFINITIONS(-DWITH_FFMPEG)
+ENDIF(WITH_FFMPEG)
+
+IF(WITH_SDL)
+       SET(INC ${INC} SDL ${SDL_INCLUDE_DIR})
+       FILE(GLOB SDLSRC SDL/*.cpp)
+       ADD_DEFINITIONS(-DWITH_SDL)
+ENDIF(WITH_SDL)
+
+IF(WITH_OPENAL)
+       SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR})
+       FILE(GLOB OPENALSRC OpenAL/*.cpp)
+       ADD_DEFINITIONS(-DWITH_OPENAL)
+ENDIF(WITH_OPENAL)
+
+IF(WITH_JACK)
+       SET(INC ${INC} jack ${JACK_INC})
+       FILE(GLOB JACKSRC jack/*.cpp)
+       ADD_DEFINITIONS(-DWITH_JACK)
+ENDIF(WITH_JACK)
+
+IF(WITH_SNDFILE)
+       SET(INC ${INC} sndfile ${SNDFILE_INC})
+       FILE(GLOB SNDFILESRC sndfile/*.cpp)
+       ADD_DEFINITIONS(-DWITH_SNDFILE)
+ENDIF(WITH_SNDFILE)
+
+#IF(WITH_FFTW3)
+#      SET(INC ${INC} fftw ${FFTW3_INC})
+#      FILE(GLOB FFTW3SRC fftw/*.cpp)
+#      ADD_DEFINITIONS(-DWITH_FFTW3)
+#ENDIF(WITH_FFTW3)
+
+IF(WITH_PYTHON)
+       SET(INC ${INC} Python ${PYTHON_INC})
+       FILE(GLOB PYTHONSRC Python/*.cpp)
+ELSE(WITH_PYTHON)
+       ADD_DEFINITIONS(-DDISABLE_PYTHON)
+ENDIF(WITH_PYTHON)
+
+SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${FFTW3SRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC} ${PYTHONSRC})
+
+BLENDERLIB(bf_intern_audaspace "${SRC}" "${INC}")
diff --git a/intern/audaspace/COPYING b/intern/audaspace/COPYING
new file mode 100644 (file)
index 0000000..94a9ed0
--- /dev/null
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/intern/audaspace/COPYING.LESSER b/intern/audaspace/COPYING.LESSER
new file mode 100644 (file)
index 0000000..cca7fc2
--- /dev/null
@@ -0,0 +1,165 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
new file mode 100644 (file)
index 0000000..0c51e52
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_AccumulatorFactory.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
+{
+       float in = reader->x(0);
+       float lastin = reader->x(-1);
+       float out = reader->y(-1) + in - lastin;
+       if(in > lastin)
+               out += in - lastin;
+       return out;
+}
+
+sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+{
+       float in = reader->x(0);
+       float lastin = reader->x(-1);
+       float out = reader->y(-1);
+       if(in > lastin)
+               out += in - lastin;
+       return out;
+}
+
+AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
+                                                                                          bool additive) :
+               AUD_EffectFactory(factory),
+               m_additive(additive)
+{
+}
+
+AUD_IReader* AUD_AccumulatorFactory::createReader() const
+{
+       return new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
+                                                       m_additive ? accumulatorFilterAdditive : accumulatorFilter);
+}
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.h b/intern/audaspace/FX/AUD_AccumulatorFactory.h
new file mode 100644 (file)
index 0000000..2b90fa4
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_ACCUMULATORFACTORY
+#define AUD_ACCUMULATORFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates an accumulator reader.
+ */
+class AUD_AccumulatorFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * Whether the accumulator is additive.
+        */
+       const bool m_additive;
+
+       // hide copy constructor and operator=
+       AUD_AccumulatorFactory(const AUD_AccumulatorFactory&);
+       AUD_AccumulatorFactory& operator=(const AUD_AccumulatorFactory&);
+
+public:
+       /**
+        * Creates a new accumulator factory.
+        * \param factory The input factory.
+        * \param additive Whether the accumulator is additive.
+        */
+       AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_ACCUMULATORFACTORY
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
new file mode 100644 (file)
index 0000000..9e14bcf
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_BaseIIRFilterReader.h"
+
+#include <cstring>
+
+#define CC m_channels + m_channel
+
+AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_IReader* reader, int in,
+                                                                                                int out) :
+               AUD_EffectReader(reader),
+               m_channels(reader->getSpecs().channels),
+               m_xlen(in), m_ylen(out),
+               m_xpos(0), m_ypos(0), m_channel(0)
+{
+       m_x = new sample_t[in * m_channels];
+       m_y = new sample_t[out * m_channels];
+
+       memset(m_x, 0, sizeof(sample_t) * in * m_channels);
+       memset(m_y, 0, sizeof(sample_t) * out * m_channels);
+}
+
+AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader()
+{
+       delete[] m_x;
+       delete[] m_y;
+}
+
+void AUD_BaseIIRFilterReader::read(int & length, sample_t* & buffer)
+{
+       sample_t* buf;
+
+       int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+
+       m_reader->read(length, buf);
+
+       if(m_buffer.getSize() < length * samplesize)
+               m_buffer.resize(length * samplesize);
+
+       buffer = m_buffer.getBuffer();
+
+       for(m_channel = 0; m_channel < m_channels; m_channel++)
+       {
+               for(int i = 0; i < length; i++)
+               {
+                       m_x[m_xpos * CC] = buf[i * CC];
+                       m_y[m_ypos * CC] = buffer[i * CC] = filter();
+
+                       m_xpos = (m_xpos + 1) % m_xlen;
+                       m_ypos = (m_ypos + 1) % m_ylen;
+               }
+       }
+}
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
new file mode 100644 (file)
index 0000000..7e2b719
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_BASEIIRFILTERREADER
+#define AUD_BASEIIRFILTERREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This class is a base class for infinite impulse response filters.
+ */
+class AUD_BaseIIRFilterReader : public AUD_EffectReader
+{
+private:
+       /**
+        * Channel count.
+        */
+       const int m_channels;
+
+       /**
+        * Length of input samples needed.
+        */
+       const int m_xlen;
+
+       /**
+        * Length of output samples needed.
+        */
+       const int m_ylen;
+
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer m_buffer;
+
+       /**
+        * The last in samples array.
+        */
+       sample_t* m_x;
+
+       /**
+        * The last out samples array.
+        */
+       sample_t* m_y;
+
+       /**
+        * Position of the current input sample in the input array.
+        */
+       int m_xpos;
+
+       /**
+        * Position of the current output sample in the output array.
+        */
+       int m_ypos;
+
+       /**
+        * Current channel.
+        */
+       int m_channel;
+
+       // hide copy constructor and operator=
+       AUD_BaseIIRFilterReader(const AUD_BaseIIRFilterReader&);
+       AUD_BaseIIRFilterReader& operator=(const AUD_BaseIIRFilterReader&);
+
+protected:
+       /**
+        * Creates a new base IIR filter reader.
+        * \param reader The reader to read from.
+        * \param in The count of past input samples needed.
+        * \param out The count of past output samples needed.
+        */
+       AUD_BaseIIRFilterReader(AUD_IReader* reader, int in, int out);
+
+public:
+       inline sample_t x(int pos)
+       {
+               return m_x[(m_xpos + pos + m_xlen) % m_xlen * m_channels + m_channel];
+       }
+
+       inline sample_t y(int pos)
+       {
+               return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_channels + m_channel];
+       }
+
+       virtual ~AUD_BaseIIRFilterReader();
+
+       virtual void read(int & length, sample_t* & buffer);
+
+       virtual sample_t filter()=0;
+};
+
+#endif //AUD_BASEIIRFILTERREADER
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
new file mode 100644 (file)
index 0000000..874ff0f
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ButterworthFactory.h"
+#include "AUD_IIRFilterReader.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define BWPB41 0.76536686473
+#define BWPB42 1.84775906502
+
+AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
+                                                                                          float frequency) :
+               AUD_EffectFactory(factory),
+               m_frequency(frequency)
+{
+}
+
+AUD_IReader* AUD_ButterworthFactory::createReader() const
+{
+       AUD_IReader* reader = getReader();
+
+       // calculate coefficients
+       float omega = 2 * tan(m_frequency * M_PI / reader->getSpecs().rate);
+       float o2 = omega * omega;
+       float o4 = o2 * o2;
+       float x1 = o2 + 2 * BWPB41 * omega + 4;
+       float x2 = o2 + 2 * BWPB42 * omega + 4;
+       float y1 = o2 - 2 * BWPB41 * omega + 4;
+       float y2 = o2 - 2 * BWPB42 * omega + 4;
+       float o228 = 2 * o2 - 8;
+       float norm = x1 * x2;
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back((x1 + x2) * o228 / norm);
+       a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
+       a.push_back((y1 + y2) * o228 / norm);
+       a.push_back(y1 * y2 / norm);
+       b.push_back(o4 / norm);
+       b.push_back(4 * o4 / norm);
+       b.push_back(6 * o4 / norm);
+       b.push_back(b[1]);
+       b.push_back(b[0]);
+
+       return new AUD_IIRFilterReader(reader, b, a);
+}
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
new file mode 100644 (file)
index 0000000..30b7a40
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_BUTTERWORTHFACTORY
+#define AUD_BUTTERWORTHFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a butterworth filter reader.
+ */
+class AUD_ButterworthFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The attack value in seconds.
+        */
+       const float m_frequency;
+
+       // hide copy constructor and operator=
+       AUD_ButterworthFactory(const AUD_ButterworthFactory&);
+       AUD_ButterworthFactory& operator=(const AUD_ButterworthFactory&);
+
+public:
+       /**
+        * Creates a new butterworth factory.
+        * \param factory The input factory.
+        * \param frequency The cutoff frequency.
+        */
+       AUD_ButterworthFactory(AUD_IFactory* factory, float frequency);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_BUTTERWORTHFACTORY
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
new file mode 100644 (file)
index 0000000..02ab6e1
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_CallbackIIRFilterReader.h"
+
+AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_IReader* reader,
+                                                                                                                int in, int out,
+                                                                                                                doFilterIIR doFilter,
+                                                                                                                endFilterIIR endFilter,
+                                                                                                                void* data) :
+       AUD_BaseIIRFilterReader(reader, in, out),
+       m_filter(doFilter), m_endFilter(endFilter), m_data(data)
+{
+}
+
+AUD_CallbackIIRFilterReader::~AUD_CallbackIIRFilterReader()
+{
+       if(m_endFilter)
+               m_endFilter(m_data);
+}
+
+sample_t AUD_CallbackIIRFilterReader::filter()
+{
+       return m_filter(this, m_data);
+}
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
new file mode 100644 (file)
index 0000000..6472c7b
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_CALLBACKIIRFILTERREADER
+#define AUD_CALLBACKIIRFILTERREADER
+
+#include "AUD_BaseIIRFilterReader.h"
+#include "AUD_Buffer.h"
+
+class AUD_CallbackIIRFilterReader;
+
+typedef sample_t (*doFilterIIR)(AUD_CallbackIIRFilterReader*, void*);
+typedef void (*endFilterIIR)(void*);
+
+/**
+ * This class provides an interface for infinite impulse response filters via a
+ * callback filter function.
+ */
+class AUD_CallbackIIRFilterReader : public AUD_BaseIIRFilterReader
+{
+private:
+       /**
+        * Filter function.
+        */
+       const doFilterIIR m_filter;
+
+       /**
+        * End filter function.
+        */
+       const endFilterIIR m_endFilter;
+
+       /**
+        * Data pointer.
+        */
+       void* m_data;
+
+       // hide copy constructor and operator=
+       AUD_CallbackIIRFilterReader(const AUD_CallbackIIRFilterReader&);
+       AUD_CallbackIIRFilterReader& operator=(const AUD_CallbackIIRFilterReader&);
+
+public:
+       /**
+        * Creates a new callback IIR filter reader.
+        * \param reader The reader to read from.
+        * \param in The count of past input samples needed.
+        * \param out The count of past output samples needed.
+        * \param doFilter The filter callback.
+        * \param endFilter The finishing callback.
+        * \param data Data pointer for the callbacks.
+        */
+       AUD_CallbackIIRFilterReader(AUD_IReader* reader, int in, int out,
+                                                               doFilterIIR doFilter,
+                                                               endFilterIIR endFilter = 0,
+                                                               void* data = 0);
+
+       virtual ~AUD_CallbackIIRFilterReader();
+
+       virtual sample_t filter();
+};
+
+#endif //AUD_CALLBACKIIRFILTERREADER
diff --git a/intern/audaspace/FX/AUD_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp
new file mode 100644 (file)
index 0000000..f98743d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_DelayFactory.h"
+#include "AUD_DelayReader.h"
+#include "AUD_Space.h"
+
+AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) :
+               AUD_EffectFactory(factory),
+               m_delay(delay)
+{
+}
+
+float AUD_DelayFactory::getDelay() const
+{
+       return m_delay;
+}
+
+AUD_IReader* AUD_DelayFactory::createReader() const
+{
+       return new AUD_DelayReader(getReader(), m_delay);
+}
diff --git a/intern/audaspace/FX/AUD_DelayFactory.h b/intern/audaspace/FX/AUD_DelayFactory.h
new file mode 100644 (file)
index 0000000..721262f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_DELAYFACTORY
+#define AUD_DELAYFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory plays another factory delayed.
+ */
+class AUD_DelayFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The delay in samples.
+        */
+       const float m_delay;
+
+       // hide copy constructor and operator=
+       AUD_DelayFactory(const AUD_DelayFactory&);
+       AUD_DelayFactory& operator=(const AUD_DelayFactory&);
+
+public:
+       /**
+        * Creates a new delay factory.
+        * \param factory The input factory.
+        * \param delay The desired delay in seconds.
+        */
+       AUD_DelayFactory(AUD_IFactory* factory, float delay = 0);
+
+       /**
+        * Returns the delay in seconds.
+        */
+       float getDelay() const;
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_DELAYFACTORY
diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp
new file mode 100644 (file)
index 0000000..e9f0c15
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_DelayReader.h"
+
+#include <cstring>
+
+AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) :
+               AUD_EffectReader(reader),
+               m_delay(int(delay * reader->getSpecs().rate)),
+               m_remdelay(int(delay * reader->getSpecs().rate)),
+               m_empty(true)
+{
+}
+
+void AUD_DelayReader::seek(int position)
+{
+       if(position < m_delay)
+       {
+               m_remdelay = m_delay - position;
+               m_reader->seek(0);
+       }
+       else
+       {
+               m_remdelay = 0;
+               m_reader->seek(position - m_delay);
+       }
+}
+
+int AUD_DelayReader::getLength() const
+{
+       int len = m_reader->getLength();
+       if(len < 0)
+               return len;
+       return len + m_delay;
+}
+
+int AUD_DelayReader::getPosition() const
+{
+       if(m_remdelay > 0)
+               return m_delay - m_remdelay;
+       return m_reader->getPosition() + m_delay;
+}
+
+void AUD_DelayReader::read(int & length, sample_t* & buffer)
+{
+       if(m_remdelay > 0)
+       {
+               AUD_Specs specs = m_reader->getSpecs();
+               int samplesize = AUD_SAMPLE_SIZE(specs);
+
+               if(m_buffer.getSize() < length * samplesize)
+               {
+                       m_buffer.resize(length * samplesize);
+                       m_empty = false;
+               }
+
+               buffer = m_buffer.getBuffer();
+
+               if(length > m_remdelay)
+               {
+                       if(!m_empty)
+                               memset(buffer, 0, m_remdelay * samplesize);
+
+                       int len = length - m_remdelay;
+                       sample_t* buf;
+                       m_reader->read(len, buf);
+
+                       memcpy(buffer + m_remdelay * specs.channels,
+                                  buf, len * samplesize);
+
+                       if(len < length-m_remdelay)
+                               length = m_remdelay + len;
+
+                       m_remdelay = 0;
+                       m_empty = false;
+               }
+               else
+               {
+                       if(!m_empty)
+                       {
+                               memset(buffer, 0, length * samplesize);
+                               m_empty = true;
+                       }
+                       m_remdelay -= length;
+               }
+       }
+       else
+               m_reader->read(length, buffer);
+}
diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h
new file mode 100644 (file)
index 0000000..121842b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_DELAYREADER
+#define AUD_DELAYREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This class reads another reader and changes it's delay.
+ */
+class AUD_DelayReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer m_buffer;
+
+       /**
+        * The delay level.
+        */
+       const int m_delay;
+
+       /**
+        * The remaining delay for playback.
+        */
+       int m_remdelay;
+
+       /**
+        * Whether the buffer is currently filled with zeros.
+        */
+       bool m_empty;
+
+       // hide copy constructor and operator=
+       AUD_DelayReader(const AUD_DelayReader&);
+       AUD_DelayReader& operator=(const AUD_DelayReader&);
+
+public:
+       /**
+        * Creates a new delay reader.
+        * \param reader The reader to read from.
+        * \param delay The delay in seconds.
+        */
+       AUD_DelayReader(AUD_IReader* reader, float delay);
+
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_DELAYREADER
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.cpp b/intern/audaspace/FX/AUD_DoubleFactory.cpp
new file mode 100644 (file)
index 0000000..9f625d0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_DoubleFactory.h"
+#include "AUD_DoubleReader.h"
+
+AUD_DoubleFactory::AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+               m_factory1(factory1), m_factory2(factory2)
+{
+}
+
+AUD_IReader* AUD_DoubleFactory::createReader() const
+{
+       AUD_IReader* reader1 = m_factory1->createReader();
+       AUD_IReader* reader2;
+
+       try
+       {
+               reader2 = m_factory2->createReader();
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1;
+               throw;
+       }
+
+       return new AUD_DoubleReader(reader1, reader2);
+}
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.h b/intern/audaspace/FX/AUD_DoubleFactory.h
new file mode 100644 (file)
index 0000000..f2e83b2
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_DOUBLEFACTORY
+#define AUD_DOUBLEFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory plays two other factories behind each other.
+ * \note Readers from the underlying factories must have the same sample rate and channel count.
+ */
+class AUD_DoubleFactory : public AUD_IFactory
+{
+private:
+       /**
+        * First played factory.
+        */
+       AUD_IFactory* m_factory1;
+
+       /**
+        * Second played factory.
+        */
+       AUD_IFactory* m_factory2;
+
+       // hide copy constructor and operator=
+       AUD_DoubleFactory(const AUD_DoubleFactory&);
+       AUD_DoubleFactory& operator=(const AUD_DoubleFactory&);
+
+public:
+       /**
+        * Creates a new double factory.
+        * \param factory1 The first input factory.
+        * \param factory2 The second input factory.
+        */
+       AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_DOUBLEFACTORY
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
new file mode 100644 (file)
index 0000000..5c6ca6a
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_DoubleReader.h"
+
+#include <cstring>
+
+static const char* specs_error = "AUD_DoubleReader: Both readers have to have "
+                                                                "the same specs.";
+
+AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
+                                                                  AUD_IReader* reader2) :
+               m_reader1(reader1), m_reader2(reader2), m_finished1(false)
+{
+       AUD_Specs s1, s2;
+       s1 = reader1->getSpecs();
+       s2 = reader2->getSpecs();
+       if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
+       {
+               delete reader1;
+               delete reader2;
+               AUD_THROW(AUD_ERROR_SPECS, specs_error);
+       }
+}
+
+AUD_DoubleReader::~AUD_DoubleReader()
+{
+       delete m_reader1;
+       delete m_reader2;
+}
+
+bool AUD_DoubleReader::isSeekable() const
+{
+       return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void AUD_DoubleReader::seek(int position)
+{
+       m_reader1->seek(position);
+
+       int pos1 = m_reader1->getPosition();
+
+       if((m_finished1 = (pos1 < position)))
+               m_reader2->seek(position - pos1);
+       else
+               m_reader2->seek(0);
+}
+
+int AUD_DoubleReader::getLength() const
+{
+       int len1 = m_reader1->getLength();
+       int len2 = m_reader2->getLength();
+       if(len1 < 0 || len2 < 0)
+               return -1;
+       return len1 + len2;
+}
+
+int AUD_DoubleReader::getPosition() const
+{
+       return m_reader1->getPosition() + m_reader2->getPosition();
+}
+
+AUD_Specs AUD_DoubleReader::getSpecs() const
+{
+       return m_reader1->getSpecs();
+}
+
+void AUD_DoubleReader::read(int & length, sample_t* & buffer)
+{
+       if(!m_finished1)
+       {
+               int len = length;
+               m_reader1->read(len, buffer);
+
+               if(len < length)
+               {
+                       AUD_Specs specs = m_reader1->getSpecs();
+                       int samplesize = AUD_SAMPLE_SIZE(specs);
+
+                       if(m_buffer.getSize() < length * samplesize)
+                               m_buffer.resize(length * samplesize);
+
+                       sample_t* buf = buffer;
+                       buffer = m_buffer.getBuffer();
+
+                       memcpy(buffer, buf, len * samplesize);
+
+                       len = length - len;
+                       length -= len;
+                       m_reader2->read(len, buf);
+
+                       memcpy(buffer + length * specs.channels, buf,
+                                  len * samplesize);
+
+                       length += len;
+
+                       m_finished1 = true;
+               }
+       }
+       else
+       {
+               m_reader2->read(length, buffer);
+       }
+}
diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h
new file mode 100644 (file)
index 0000000..d80ba33
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_DOUBLEREADER
+#define AUD_DOUBLEREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This reader plays two readers with the same specs sequently.
+ */
+class AUD_DoubleReader : public AUD_IReader
+{
+private:
+       /**
+        * The first reader.
+        */
+       AUD_IReader* m_reader1;
+
+       /**
+        * The second reader.
+        */
+       AUD_IReader* m_reader2;
+
+       /**
+        * Whether we've reached the end of the first reader.
+        */
+       bool m_finished1;
+
+       /**
+        * The playback buffer for the intersecting part.
+        */
+       AUD_Buffer m_buffer;
+
+       // hide copy constructor and operator=
+       AUD_DoubleReader(const AUD_DoubleReader&);
+       AUD_DoubleReader& operator=(const AUD_DoubleReader&);
+
+public:
+       /**
+        * Creates a new ping pong reader.
+        * \param reader1 The first reader to read from.
+        * \param reader2 The second reader to read from.
+        * \exception AUD_Exception Thrown if the specs from the readers differ.
+        */
+       AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2);
+
+       /**
+        * Destroys the reader.
+        */
+       virtual ~AUD_DoubleReader();
+
+       virtual bool isSeekable() const;
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual AUD_Specs getSpecs() const;
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_DOUBLEREADER
diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp
new file mode 100644 (file)
index 0000000..eda4e4e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_EffectFactory.h"
+#include "AUD_IReader.h"
+
+AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory)
+{
+       m_factory = factory;
+}
+
+AUD_EffectFactory::~AUD_EffectFactory()
+{
+}
+
+AUD_IFactory* AUD_EffectFactory::getFactory() const
+{
+       return m_factory;
+}
diff --git a/intern/audaspace/FX/AUD_EffectFactory.h b/intern/audaspace/FX/AUD_EffectFactory.h
new file mode 100644 (file)
index 0000000..fd3746d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_EFFECTFACTORY
+#define AUD_EFFECTFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory is a base class for all effect factories that take one other
+ * factory as input.
+ */
+class AUD_EffectFactory : public AUD_IFactory
+{
+private:
+       // hide copy constructor and operator=
+       AUD_EffectFactory(const AUD_EffectFactory&);
+       AUD_EffectFactory& operator=(const AUD_EffectFactory&);
+
+protected:
+       /**
+        * If there is no reader it is created out of this factory.
+        */
+       AUD_IFactory* m_factory;
+
+       /**
+        * Returns the reader created out of the factory.
+        * This method can be used for the createReader function of the implementing
+        * classes.
+        * \return The reader created out of the factory.
+        */
+       inline AUD_IReader* getReader() const
+       {
+               return m_factory->createReader();
+       }
+
+public:
+       /**
+        * Creates a new factory.
+        * \param factory The input factory.
+        */
+       AUD_EffectFactory(AUD_IFactory* factory);
+
+       /**
+        * Destroys the factory.
+        */
+       virtual ~AUD_EffectFactory();
+
+       /**
+        * Returns the saved factory.
+        * \return The factory or NULL if there has no factory been saved.
+        */
+       AUD_IFactory* getFactory() const;
+};
+
+#endif //AUD_EFFECTFACTORY
diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp
new file mode 100644 (file)
index 0000000..b54ca27
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_EffectReader.h"
+
+AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader)
+{
+       m_reader = reader;
+}
+
+AUD_EffectReader::~AUD_EffectReader()
+{
+       delete m_reader;
+}
+
+bool AUD_EffectReader::isSeekable() const
+{
+       return m_reader->isSeekable();
+}
+
+void AUD_EffectReader::seek(int position)
+{
+       m_reader->seek(position);
+}
+
+int AUD_EffectReader::getLength() const
+{
+       return m_reader->getLength();
+}
+
+int AUD_EffectReader::getPosition() const
+{
+       return m_reader->getPosition();
+}
+
+AUD_Specs AUD_EffectReader::getSpecs() const
+{
+       return m_reader->getSpecs();
+}
+
+void AUD_EffectReader::read(int & length, sample_t* & buffer)
+{
+       m_reader->read(length, buffer);
+}
diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h
new file mode 100644 (file)
index 0000000..c447f79
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_EFFECTREADER
+#define AUD_EFFECTREADER
+
+#include "AUD_IReader.h"
+
+/**
+ * This reader is a base class for all effect readers that take one other reader
+ * as input.
+ */
+class AUD_EffectReader : public AUD_IReader
+{
+private:
+       // hide copy constructor and operator=
+       AUD_EffectReader(const AUD_EffectReader&);
+       AUD_EffectReader& operator=(const AUD_EffectReader&);
+
+protected:
+       /**
+        * The reader to read from.
+        */
+       AUD_IReader* m_reader;
+
+public:
+       /**
+        * Creates a new effect reader.
+        * \param reader The reader to read from.
+        */
+       AUD_EffectReader(AUD_IReader* reader);
+
+       /**
+        * Destroys the reader.
+        */
+       virtual ~AUD_EffectReader();
+
+       virtual bool isSeekable() const;
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual AUD_Specs getSpecs() const;
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_EFFECTREADER
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
new file mode 100644 (file)
index 0000000..4777da7
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_EnvelopeFactory.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+#include <cmath>
+
+struct EnvelopeParameters
+{
+       float attack;
+       float release;
+       float threshold;
+       float arthreshold;
+};
+
+sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
+{
+       float in = fabs(reader->x(0));
+       float out = reader->y(-1);
+       if(in < param->threshold)
+               in = 0.0f;
+       return (in > out ? param->attack : param->release) * (out - in) + in;
+}
+
+void endEnvelopeFilter(EnvelopeParameters* param)
+{
+       delete param;
+}
+
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
+                                                                                float release, float threshold,
+                                                                                float arthreshold) :
+               AUD_EffectFactory(factory),
+               m_attack(attack),
+               m_release(release),
+               m_threshold(threshold),
+               m_arthreshold(arthreshold)
+{
+}
+
+AUD_IReader* AUD_EnvelopeFactory::createReader() const
+{
+       AUD_IReader* reader = getReader();
+
+       EnvelopeParameters* param = new EnvelopeParameters();
+       param->arthreshold = m_arthreshold;
+       param->attack = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_attack));
+       param->release = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_release));
+       param->threshold = m_threshold;
+
+       return new AUD_CallbackIIRFilterReader(reader, 1, 2,
+                                                                                  (doFilterIIR) envelopeFilter,
+                                                                                  (endFilterIIR) endEnvelopeFilter,
+                                                                                  param);
+}
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h
new file mode 100644 (file)
index 0000000..c31c672
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_ENVELOPEFACTORY
+#define AUD_ENVELOPEFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates an envelope follower reader.
+ */
+class AUD_EnvelopeFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The attack value in seconds.
+        */
+       const float m_attack;
+
+       /**
+        * The release value in seconds.
+        */
+       const float m_release;
+
+       /**
+        * The threshold value.
+        */
+       const float m_threshold;
+
+       /**
+        * The attack/release threshold value.
+        */
+       const float m_arthreshold;
+
+       // hide copy constructor and operator=
+       AUD_EnvelopeFactory(const AUD_EnvelopeFactory&);
+       AUD_EnvelopeFactory& operator=(const AUD_EnvelopeFactory&);
+
+public:
+       /**
+        * Creates a new envelope factory.
+        * \param factory The input factory.
+        * \param attack The attack value in seconds.
+        * \param release The release value in seconds.
+        * \param threshold The threshold value.
+        * \param arthreshold The attack/release threshold value.
+        */
+       AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release,
+                                               float threshold, float arthreshold);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_ENVELOPEFACTORY
diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp
new file mode 100644 (file)
index 0000000..bbe9319
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FaderFactory.h"
+#include "AUD_FaderReader.h"
+
+AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type,
+                                                                  float start, float length) :
+               AUD_EffectFactory(factory),
+               m_type(type),
+               m_start(start),
+               m_length(length)
+{
+}
+
+AUD_FadeType AUD_FaderFactory::getType() const
+{
+       return m_type;
+}
+
+float AUD_FaderFactory::getStart() const
+{
+       return m_start;
+}
+
+float AUD_FaderFactory::getLength() const
+{
+       return m_length;
+}
+
+AUD_IReader* AUD_FaderFactory::createReader() const
+{
+       return new AUD_FaderReader(getReader(), m_type, m_start, m_length);
+}
diff --git a/intern/audaspace/FX/AUD_FaderFactory.h b/intern/audaspace/FX/AUD_FaderFactory.h
new file mode 100644 (file)
index 0000000..af5d185
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FADERFACTORY
+#define AUD_FADERFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory fades another factory.
+ * If the fading type is AUD_FADE_IN, everything before the fading start will be
+ * silenced, for AUD_FADE_OUT that's true for everything after fading ends.
+ */
+class AUD_FaderFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The fading type.
+        */
+       const AUD_FadeType m_type;
+
+       /**
+        * The fading start.
+        */
+       const float m_start;
+
+       /**
+        * The fading length.
+        */
+       const float m_length;
+
+       // hide copy constructor and operator=
+       AUD_FaderFactory(const AUD_FaderFactory&);
+       AUD_FaderFactory& operator=(const AUD_FaderFactory&);
+
+public:
+       /**
+        * Creates a new fader factory.
+        * \param factory The input factory.
+        * \param type The fading type.
+        * \param start The time where fading should start in seconds.
+        * \param length How long fading should last in seconds.
+        */
+       AUD_FaderFactory(AUD_IFactory* factory,
+                                         AUD_FadeType type = AUD_FADE_IN,
+                                         float start = 0.0f, float length = 1.0f);
+
+       /**
+        * Returns the fading type.
+        */
+       AUD_FadeType getType() const;
+
+       /**
+        * Returns the fading start.
+        */
+       float getStart() const;
+
+       /**
+        * Returns the fading length.
+        */
+       float getLength() const;
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_FADERFACTORY
diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp
new file mode 100644 (file)
index 0000000..2292fa0
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FaderReader.h"
+
+#include <cstring>
+
+AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+                                                                float start,float length) :
+               AUD_EffectReader(reader),
+               m_type(type),
+               m_start(start),
+               m_length(length),
+               m_empty(true)
+{
+}
+
+void AUD_FaderReader::read(int & length, sample_t* & buffer)
+{
+       int position = m_reader->getPosition();
+       AUD_Specs specs = m_reader->getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
+
+       m_reader->read(length, buffer);
+
+       if((position + length) / (float)specs.rate <= m_start)
+       {
+               if(m_type != AUD_FADE_OUT)
+               {
+                       if(m_buffer.getSize() < length * samplesize)
+                       {
+                               m_buffer.resize(length * samplesize);
+                               m_empty = false;
+                       }
+
+                       buffer = m_buffer.getBuffer();
+
+                       if(!m_empty)
+                       {
+                               memset(buffer, 0, length * samplesize);
+                               m_empty = true;
+                       }
+               }
+       }
+       else if(position / (float)specs.rate >= m_start+m_length)
+       {
+               if(m_type == AUD_FADE_OUT)
+               {
+                       if(m_buffer.getSize() < length * samplesize)
+                       {
+                               m_buffer.resize(length * samplesize);
+                               m_empty = false;
+                       }
+
+                       buffer = m_buffer.getBuffer();
+
+                       if(!m_empty)
+                       {
+                               memset(buffer, 0, length * samplesize);
+                               m_empty = true;
+                       }
+               }
+       }
+       else
+       {
+               if(m_buffer.getSize() < length * samplesize)
+                       m_buffer.resize(length * samplesize);
+
+               sample_t* buf = m_buffer.getBuffer();
+               float volume = 1.0f;
+
+               for(int i = 0; i < length * specs.channels; i++)
+               {
+                       if(i % specs.channels == 0)
+                       {
+                               volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
+                               if(volume > 1.0f)
+                                       volume = 1.0f;
+                               else if(volume < 0.0f)
+                                       volume = 0.0f;
+
+                               if(m_type == AUD_FADE_OUT)
+                                       volume = 1.0f - volume;
+                       }
+
+                       buf[i] = buffer[i] * volume;
+               }
+
+               buffer = buf;
+               m_empty = false;
+       }
+}
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
new file mode 100644 (file)
index 0000000..d9d685a
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FADERREADER
+#define AUD_FADERREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This class fades another reader.
+ * If the fading type is AUD_FADE_IN, everything before the fading start will be
+ * silenced, for AUD_FADE_OUT that's true for everything after fading ends.
+ */
+class AUD_FaderReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The fading type.
+        */
+       const AUD_FadeType m_type;
+
+       /**
+        * The fading start.
+        */
+       const float m_start;
+
+       /**
+        * The fading length.
+        */
+       const float m_length;
+
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer m_buffer;
+
+       /**
+        * Whether the buffer is empty.
+        */
+       bool m_empty;
+
+       // hide copy constructor and operator=
+       AUD_FaderReader(const AUD_FaderReader&);
+       AUD_FaderReader& operator=(const AUD_FaderReader&);
+
+public:
+       /**
+        * Creates a new fader reader.
+        * \param type The fading type.
+        * \param start The time where fading should start in seconds.
+        * \param length How long fading should last in seconds.
+        */
+       AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+                                       float start,float length);
+
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_FADERREADER
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
new file mode 100644 (file)
index 0000000..d222e7f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_HighpassFactory.h"
+#include "AUD_IIRFilterReader.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
+                                                                                float Q) :
+               AUD_EffectFactory(factory),
+               m_frequency(frequency),
+               m_Q(Q)
+{
+}
+
+AUD_IReader* AUD_HighpassFactory::createReader() const
+{
+       AUD_IReader* reader = getReader();
+
+       // calculate coefficients
+       float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+       float alpha = sin(w0) / (2 * m_Q);
+       float norm = 1 + alpha;
+       float c = cos(w0);
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back(-2 * c / norm);
+       a.push_back((1 - alpha) / norm);
+       b.push_back((1 + c) / (2 * norm));
+       b.push_back((-1 - c) / norm);
+       b.push_back(b[0]);
+
+       return new AUD_IIRFilterReader(reader, b, a);
+}
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
new file mode 100644 (file)
index 0000000..1220157
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_HIGHPASSFACTORY
+#define AUD_HIGHPASSFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a highpass filter reader.
+ */
+class AUD_HighpassFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The attack value in seconds.
+        */
+       const float m_frequency;
+
+       /**
+        * The Q factor.
+        */
+       const float m_Q;
+
+       // hide copy constructor and operator=
+       AUD_HighpassFactory(const AUD_HighpassFactory&);
+       AUD_HighpassFactory& operator=(const AUD_HighpassFactory&);
+
+public:
+       /**
+        * Creates a new highpass factory.
+        * \param factory The input factory.
+        * \param frequency The cutoff frequency.
+        * \param Q The Q factor.
+        */
+       AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_HIGHPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
new file mode 100644 (file)
index 0000000..8cd49a0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_IIRFilterFactory.h"
+#include "AUD_IIRFilterReader.h"
+
+AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory,
+                                                                                  std::vector<float> b,
+                                                                                  std::vector<float> a) :
+               AUD_EffectFactory(factory), m_a(a), m_b(b)
+{
+}
+
+AUD_IReader* AUD_IIRFilterFactory::createReader() const
+{
+       return new AUD_IIRFilterReader(getReader(), m_b, m_a);
+}
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.h b/intern/audaspace/FX/AUD_IIRFilterFactory.h
new file mode 100644 (file)
index 0000000..567d4f3
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_IIRFILTERFACTORY
+#define AUD_IIRFILTERFACTORY
+
+#include "AUD_EffectFactory.h"
+
+#include <vector>
+
+/**
+ * This factory creates a IIR filter reader.
+ */
+class AUD_IIRFilterFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * Output filter coefficients.
+        */
+       std::vector<float> m_a;
+
+       /**
+        * Input filter coefficients.
+        */
+       std::vector<float> m_b;
+
+       // hide copy constructor and operator=
+       AUD_IIRFilterFactory(const AUD_IIRFilterFactory&);
+       AUD_IIRFilterFactory& operator=(const AUD_IIRFilterFactory&);
+
+public:
+       /**
+        * Creates a new IIR filter factory.
+        * \param factory The input factory.
+        * \param b The input filter coefficients.
+        * \param a The output filter coefficients.
+        */
+       AUD_IIRFilterFactory(AUD_IFactory* factory, std::vector<float> b,
+                                                std::vector<float> a);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_IIRFILTERFACTORY
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.cpp b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
new file mode 100644 (file)
index 0000000..120c9f8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_IIRFilterReader.h"
+
+AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_IReader* reader,
+                                                                                std::vector<float> b,
+                                                                                std::vector<float> a) :
+       AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
+{
+       for(int i = 1; i < m_a.size(); i++)
+               m_a[i] /= m_a[0];
+       for(int i = 0; i < m_b.size(); i++)
+               m_b[i] /= m_a[0];
+       m_a[0] = 1;
+}
+
+sample_t AUD_IIRFilterReader::filter()
+{
+       sample_t out = 0;
+
+       for(int i = 1; i < m_a.size(); i++)
+               out -= y(-i) * m_a[i];
+       for(int i = 0; i < m_b.size(); i++)
+               out += x(-i) * m_b[i];
+
+       return out;
+}
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h
new file mode 100644 (file)
index 0000000..303bc6d
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_IIRFILTERREADER
+#define AUD_IIRFILTERREADER
+
+#include "AUD_BaseIIRFilterReader.h"
+
+#include <vector>
+
+/**
+ * This class is for infinite impulse response filters with simple coefficients.
+ */
+class AUD_IIRFilterReader : public AUD_BaseIIRFilterReader
+{
+private:
+       /**
+        * Output filter coefficients.
+        */
+       std::vector<float> m_a;
+
+       /**
+        * Input filter coefficients.
+        */
+       std::vector<float> m_b;
+
+       // hide copy constructor and operator=
+       AUD_IIRFilterReader(const AUD_IIRFilterReader&);
+       AUD_IIRFilterReader& operator=(const AUD_IIRFilterReader&);
+
+public:
+       /**
+        * Creates a new IIR filter reader.
+        * \param reader The reader to read from.
+        * \param b The input filter coefficients.
+        * \param a The output filter coefficients.
+        */
+       AUD_IIRFilterReader(AUD_IReader* reader, std::vector<float> b,
+                                               std::vector<float> a);
+
+       virtual sample_t filter();
+};
+
+#endif //AUD_IIRFILTERREADER
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp
new file mode 100644 (file)
index 0000000..75501af
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LimiterFactory.h"
+#include "AUD_LimiterReader.h"
+#include "AUD_Space.h"
+
+AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory,
+                                                                          float start, float end) :
+               AUD_EffectFactory(factory),
+               m_start(start),
+               m_end(end)
+{
+}
+
+float AUD_LimiterFactory::getStart() const
+{
+       return m_start;
+}
+
+float AUD_LimiterFactory::getEnd() const
+{
+       return m_end;
+}
+
+AUD_IReader* AUD_LimiterFactory::createReader() const
+{
+       return new AUD_LimiterReader(getReader(), m_start, m_end);
+}
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.h b/intern/audaspace/FX/AUD_LimiterFactory.h
new file mode 100644 (file)
index 0000000..5d9491f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LIMITERFACTORY
+#define AUD_LIMITERFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory limits another factory in start and end time.
+ */
+class AUD_LimiterFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The start time.
+        */
+       const float m_start;
+
+       /**
+        * The end time.
+        */
+       const float m_end;
+
+       // hide copy constructor and operator=
+       AUD_LimiterFactory(const AUD_LimiterFactory&);
+       AUD_LimiterFactory& operator=(const AUD_LimiterFactory&);
+
+public:
+       /**
+        * Creates a new limiter factory.
+        * \param factory The input factory.
+        * \param start The desired start time.
+        * \param end The desired end time, a negative value signals that it should
+        *            play to the end.
+        */
+       AUD_LimiterFactory(AUD_IFactory* factory,
+                                          float start = 0, float end = -1);
+
+       /**
+        * Returns the start time.
+        */
+       float getStart() const;
+
+       /**
+        * Returns the end time.
+        */
+       float getEnd() const;
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_LIMITERFACTORY
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp
new file mode 100644 (file)
index 0000000..dd73012
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LimiterReader.h"
+#include "AUD_Buffer.h"
+
+#include <iostream>
+
+AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
+                                                                        float start, float end) :
+               AUD_EffectReader(reader),
+               m_start(int(start * reader->getSpecs().rate)),
+               m_end(int(end * reader->getSpecs().rate))
+{
+       if(m_start > 0)
+       {
+               if(m_reader->isSeekable())
+                       m_reader->seek(m_start);
+               else
+               {
+                       // skip first m_start samples by reading them
+                       int length = AUD_DEFAULT_BUFFER_SIZE;
+                       sample_t* buffer;
+                       for(int len = m_start;
+                               length == AUD_DEFAULT_BUFFER_SIZE;
+                               len -= AUD_DEFAULT_BUFFER_SIZE)
+                       {
+                               if(len < AUD_DEFAULT_BUFFER_SIZE)
+                                       length = len;
+                               m_reader->read(length, buffer);
+                       }
+               }
+       }
+}
+
+void AUD_LimiterReader::seek(int position)
+{
+       m_reader->seek(position + m_start);
+}
+
+int AUD_LimiterReader::getLength() const
+{
+       int len = m_reader->getLength();
+       if(len < 0 || (len > m_end && m_end >= 0))
+               len = m_end;
+       return len - m_start;
+}
+
+int AUD_LimiterReader::getPosition() const
+{
+       int pos = m_reader->getPosition();
+       return AUD_MIN(pos, m_end) - m_start;
+}
+
+void AUD_LimiterReader::read(int & length, sample_t* & buffer)
+{
+       if(m_end >= 0)
+       {
+               int position = m_reader->getPosition();
+               if(position + length > m_end)
+                       length = m_end - position;
+               if(length < 0)
+               {
+                       length = 0;
+                       return;
+               }
+       }
+       m_reader->read(length, buffer);
+}
diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h
new file mode 100644 (file)
index 0000000..59d6096
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LIMITERREADER
+#define AUD_LIMITERREADER
+
+#include "AUD_EffectReader.h"
+
+/**
+ * This reader limits another reader in start and end sample.
+ */
+class AUD_LimiterReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The start sample: inclusive.
+        */
+       const int m_start;
+
+       /**
+        * The end sample: exlusive.
+        */
+       const int m_end;
+
+       // hide copy constructor and operator=
+       AUD_LimiterReader(const AUD_LimiterReader&);
+       AUD_LimiterReader& operator=(const AUD_LimiterReader&);
+
+public:
+       /**
+        * Creates a new limiter reader.
+        * \param reader The reader to read from.
+        * \param start The desired start sample (inclusive).
+        * \param end The desired end sample (exklusive), a negative value signals
+        *            that it should play to the end.
+        */
+       AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1);
+
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LIMITERREADER
diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp
new file mode 100644 (file)
index 0000000..6805a8e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LoopFactory.h"
+#include "AUD_LoopReader.h"
+
+AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) :
+               AUD_EffectFactory(factory),
+               m_loop(loop)
+{
+}
+
+int AUD_LoopFactory::getLoop() const
+{
+       return m_loop;
+}
+
+AUD_IReader* AUD_LoopFactory::createReader() const
+{
+       return new AUD_LoopReader(getReader(), m_loop);
+}
diff --git a/intern/audaspace/FX/AUD_LoopFactory.h b/intern/audaspace/FX/AUD_LoopFactory.h
new file mode 100644 (file)
index 0000000..f9e358a
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LOOPFACTORY
+#define AUD_LOOPFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory loops another factory.
+ * \note The reader has to be seekable.
+ */
+class AUD_LoopFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The loop count.
+        */
+       const int m_loop;
+
+       // hide copy constructor and operator=
+       AUD_LoopFactory(const AUD_LoopFactory&);
+       AUD_LoopFactory& operator=(const AUD_LoopFactory&);
+
+public:
+       /**
+        * Creates a new loop factory.
+        * \param factory The input factory.
+        * \param loop The desired loop count, negative values result in endless
+        *        looping.
+        */
+       AUD_LoopFactory(AUD_IFactory* factory, int loop = -1);
+
+       /**
+        * Returns the loop count.
+        */
+       int getLoop() const;
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_LOOPFACTORY
diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp
new file mode 100644 (file)
index 0000000..7521f91
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LoopReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
+               AUD_EffectReader(reader), m_count(loop), m_left(loop)
+{
+}
+
+void AUD_LoopReader::seek(int position)
+{
+       int len = m_reader->getLength();
+       if(len < 0)
+               m_reader->seek(position);
+       else
+       {
+               if(m_count >= 0)
+               {
+                       m_left = m_count - (position / len);
+                       if(m_left < 0)
+                               m_left = 0;
+               }
+               m_reader->seek(position % len);
+       }
+}
+
+int AUD_LoopReader::getLength() const
+{
+       if(m_count < 0)
+               return -1;
+       return m_reader->getLength() * m_count;
+}
+
+int AUD_LoopReader::getPosition() const
+{
+       return m_reader->getPosition() * (m_count < 0 ? 1 : m_count);
+}
+
+void AUD_LoopReader::read(int & length, sample_t* & buffer)
+{
+       AUD_Specs specs = m_reader->getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
+
+       int len = length;
+
+       m_reader->read(len, buffer);
+
+       if(len < length && m_left)
+       {
+               int pos = 0;
+
+               if(m_buffer.getSize() < length * samplesize)
+                       m_buffer.resize(length * samplesize);
+
+               sample_t* buf = m_buffer.getBuffer();
+
+               memcpy(buf + pos * specs.channels, buffer, len * samplesize);
+
+               pos += len;
+
+               while(pos < length && m_left)
+               {
+                       if(m_left > 0)
+                               m_left--;
+
+                       m_reader->seek(0);
+
+                       len = length - pos;
+                       m_reader->read(len, buffer);
+
+                       // prevent endless loop
+                       if(!len)
+                               break;
+
+                       memcpy(buf + pos * specs.channels, buffer, len * samplesize);
+
+                       pos += len;
+               }
+
+               length = pos;
+               buffer = buf;
+       }
+       else
+               length = len;
+}
diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h
new file mode 100644 (file)
index 0000000..e0ed4cb
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LOOPREADER
+#define AUD_LOOPREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This class reads another reader and loops it.
+ * \note The other reader must be seekable.
+ */
+class AUD_LoopReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer m_buffer;
+
+       /**
+        * The loop count.
+        */
+       const int m_count;
+
+       /**
+        * The left loop count.
+        */
+       int m_left;
+
+       // hide copy constructor and operator=
+       AUD_LoopReader(const AUD_LoopReader&);
+       AUD_LoopReader& operator=(const AUD_LoopReader&);
+
+public:
+       /**
+        * Creates a new loop reader.
+        * \param reader The reader to read from.
+        * \param loop The desired loop count, negative values result in endless
+        *        looping.
+        */
+       AUD_LoopReader(AUD_IReader* reader, int loop);
+
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LOOPREADER
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
new file mode 100644 (file)
index 0000000..9244e07
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LowpassFactory.h"
+#include "AUD_IIRFilterReader.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
+                                                                          float Q) :
+               AUD_EffectFactory(factory),
+               m_frequency(frequency),
+               m_Q(Q)
+{
+}
+
+AUD_IReader* AUD_LowpassFactory::createReader() const
+{
+       AUD_IReader* reader = getReader();
+
+       // calculate coefficients
+       float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+       float alpha = sin(w0) / (2 * m_Q);
+       float norm = 1 + alpha;
+       float c = cos(w0);
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back(-2 * c / norm);
+       a.push_back((1 - alpha) / norm);
+       b.push_back((1 - c) / (2 * norm));
+       b.push_back((1 - c) / norm);
+       b.push_back(b[0]);
+
+       return new AUD_IIRFilterReader(reader, b, a);
+}
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
new file mode 100644 (file)
index 0000000..61b7651
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LOWPASSFACTORY
+#define AUD_LOWPASSFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a lowpass filter reader.
+ */
+class AUD_LowpassFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The attack value in seconds.
+        */
+       const float m_frequency;
+
+       /**
+        * The Q factor.
+        */
+       const float m_Q;
+
+       // hide copy constructor and operator=
+       AUD_LowpassFactory(const AUD_LowpassFactory&);
+       AUD_LowpassFactory& operator=(const AUD_LowpassFactory&);
+
+public:
+       /**
+        * Creates a new lowpass factory.
+        * \param factory The input factory.
+        * \param frequency The cutoff frequency.
+        * \param Q The Q factor.
+        */
+       AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_LOWPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp
new file mode 100644 (file)
index 0000000..b3aaa9e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_PingPongFactory.h"
+#include "AUD_DoubleReader.h"
+#include "AUD_ReverseFactory.h"
+
+AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) :
+               AUD_EffectFactory(factory)
+{
+}
+
+AUD_IReader* AUD_PingPongFactory::createReader() const
+{
+       AUD_IReader* reader = getReader();
+       AUD_IReader* reader2;
+       AUD_ReverseFactory factory(m_factory);
+
+       try
+       {
+               reader2 = factory.createReader();
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader;
+               throw;
+       }
+
+       return new AUD_DoubleReader(reader, reader2);
+}
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.h b/intern/audaspace/FX/AUD_PingPongFactory.h
new file mode 100644 (file)
index 0000000..82aedca
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_PINGPONGFACTORY
+#define AUD_PINGPONGFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory plays another factory first normal, then reversed.
+ * \note Readers from the underlying factory must be from the buffer type.
+ */
+class AUD_PingPongFactory : public AUD_EffectFactory
+{
+private:
+       // hide copy constructor and operator=
+       AUD_PingPongFactory(const AUD_PingPongFactory&);
+       AUD_PingPongFactory& operator=(const AUD_PingPongFactory&);
+
+public:
+       /**
+        * Creates a new ping pong factory.
+        * \param factory The input factory.
+        */
+       AUD_PingPongFactory(AUD_IFactory* factory);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_PINGPONGFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchFactory.cpp b/intern/audaspace/FX/AUD_PitchFactory.cpp
new file mode 100644 (file)
index 0000000..be28556
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_PitchFactory.h"
+#include "AUD_PitchReader.h"
+#include "AUD_Space.h"
+
+AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) :
+               AUD_EffectFactory(factory),
+               m_pitch(pitch)
+{
+}
+
+AUD_IReader* AUD_PitchFactory::createReader() const
+{
+       return new AUD_PitchReader(getReader(), m_pitch);
+}
diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h
new file mode 100644 (file)
index 0000000..52b9b7d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_PITCHFACTORY
+#define AUD_PITCHFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory changes the pitch of another factory.
+ */
+class AUD_PitchFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The pitch.
+        */
+       const float m_pitch;
+
+       // hide copy constructor and operator=
+       AUD_PitchFactory(const AUD_PitchFactory&);
+       AUD_PitchFactory& operator=(const AUD_PitchFactory&);
+
+public:
+       /**
+        * Creates a new pitch factory.
+        * \param factory The input factory.
+        * \param pitch The desired pitch.
+        */
+       AUD_PitchFactory(AUD_IFactory* factory, float pitch);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_PITCHFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchReader.cpp b/intern/audaspace/FX/AUD_PitchReader.cpp
new file mode 100644 (file)
index 0000000..19c3be3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_PitchReader.h"
+
+AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
+               AUD_EffectReader(reader), m_pitch(pitch)
+{
+}
+
+AUD_Specs AUD_PitchReader::getSpecs() const
+{
+       AUD_Specs specs = m_reader->getSpecs();
+       specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch));
+       return specs;
+}
diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h
new file mode 100644 (file)
index 0000000..cc188cf
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_PITCHREADER
+#define AUD_PITCHREADER
+
+#include "AUD_EffectReader.h"
+
+/**
+ * This class reads another reader and changes it's pitch.
+ */
+class AUD_PitchReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The pitch level.
+        */
+       const float m_pitch;
+
+       // hide copy constructor and operator=
+       AUD_PitchReader(const AUD_PitchReader&);
+       AUD_PitchReader& operator=(const AUD_PitchReader&);
+
+public:
+       /**
+        * Creates a new pitch reader.
+        * \param reader The reader to read from.
+        * \param pitch The size of the buffer.
+        */
+       AUD_PitchReader(AUD_IReader* reader, float pitch);
+
+       virtual AUD_Specs getSpecs() const;
+};
+
+#endif //AUD_PITCHREADER
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp
new file mode 100644 (file)
index 0000000..2228f94
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_RectifyFactory.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+#include <cmath>
+
+sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+{
+       return fabs(reader->x(0));
+}
+
+AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
+               AUD_EffectFactory(factory)
+{
+}
+
+AUD_IReader* AUD_RectifyFactory::createReader() const
+{
+       return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter);
+}
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.h b/intern/audaspace/FX/AUD_RectifyFactory.h
new file mode 100644 (file)
index 0000000..d8b39e8
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_RECTIFYFACTORY
+#define AUD_RECTIFYFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory rectifies another factory.
+ */
+class AUD_RectifyFactory : public AUD_EffectFactory
+{
+private:
+       // hide copy constructor and operator=
+       AUD_RectifyFactory(const AUD_RectifyFactory&);
+       AUD_RectifyFactory& operator=(const AUD_RectifyFactory&);
+
+public:
+       /**
+        * Creates a new rectify factory.
+        * \param factory The input factory.
+        */
+       AUD_RectifyFactory(AUD_IFactory* factory);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_RECTIFYFACTORY
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp
new file mode 100644 (file)
index 0000000..1002e2d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ReverseFactory.h"
+#include "AUD_ReverseReader.h"
+#include "AUD_Space.h"
+
+AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) :
+               AUD_EffectFactory(factory)
+{
+}
+
+AUD_IReader* AUD_ReverseFactory::createReader() const
+{
+       return new AUD_ReverseReader(getReader());
+}
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.h b/intern/audaspace/FX/AUD_ReverseFactory.h
new file mode 100644 (file)
index 0000000..a1995ee
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_REVERSEFACTORY
+#define AUD_REVERSEFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory reads another factory reverted.
+ * \note Readers from the underlying factory must be from the buffer type.
+ */
+class AUD_ReverseFactory : public AUD_EffectFactory
+{
+private:
+       // hide copy constructor and operator=
+       AUD_ReverseFactory(const AUD_ReverseFactory&);
+       AUD_ReverseFactory& operator=(const AUD_ReverseFactory&);
+
+public:
+       /**
+        * Creates a new reverse factory.
+        * \param factory The input factory.
+        */
+       AUD_ReverseFactory(AUD_IFactory* factory);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_REVERSEFACTORY
diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp
new file mode 100644 (file)
index 0000000..c651ea7
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ReverseReader.h"
+
+#include <cstring>
+
+static const char* props_error = "AUD_ReverseReader: The reader has to be "
+                                                                "seekable and a finite length.";
+
+AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
+               AUD_EffectReader(reader),
+               m_length(reader->getLength()),
+               m_position(0)
+{
+       if(m_length < 0 || !reader->isSeekable())
+               AUD_THROW(AUD_ERROR_PROPS, props_error);
+}
+
+void AUD_ReverseReader::seek(int position)
+{
+       m_position = position;
+}
+
+int AUD_ReverseReader::getLength() const
+{
+       return m_length;
+}
+
+int AUD_ReverseReader::getPosition() const
+{
+       return m_position;
+}
+
+void AUD_ReverseReader::read(int & length, sample_t* & buffer)
+{
+       // first correct the length
+       if(m_position + length > m_length)
+               length = m_length - m_position;
+
+       if(length <= 0)
+       {
+               length = 0;
+               return;
+       }
+
+       AUD_Specs specs = getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
+
+       // resize buffer if needed
+       if(m_buffer.getSize() < length * samplesize)
+               m_buffer.resize(length * samplesize);
+
+       buffer = m_buffer.getBuffer();
+
+       sample_t* buf;
+       int len = length;
+
+       // read from reader
+       m_reader->seek(m_length - m_position - len);
+       m_reader->read(len, buf);
+
+       // set null if reader didn't give enough data
+       if(len < length)
+       {
+               memset(buffer, 0, (length - len) * samplesize);
+               buffer += (length - len) * specs.channels;
+       }
+
+       // copy the samples reverted
+       for(int i = 0; i < len; i++)
+               memcpy(buffer + i * specs.channels,
+                          buf + (len - 1 - i) * specs.channels,
+                          samplesize);
+
+       m_position += length;
+
+       buffer = m_buffer.getBuffer();
+}
diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h
new file mode 100644 (file)
index 0000000..8eb960a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_REVERSEREADER
+#define AUD_REVERSEREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This class reads another reader from back to front.
+ * \note The underlying reader must be a buffer.
+ */
+class AUD_ReverseReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The sample count.
+        */
+       const int m_length;
+
+       /**
+        * The current position.
+        */
+       int m_position;
+
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer m_buffer;
+
+       // hide copy constructor and operator=
+       AUD_ReverseReader(const AUD_ReverseReader&);
+       AUD_ReverseReader& operator=(const AUD_ReverseReader&);
+
+public:
+       /**
+        * Creates a new reverse reader.
+        * \param reader The reader to read from.
+        * \exception AUD_Exception Thrown if the reader specified has an
+        *            undeterminable/infinite length or is not seekable.
+        */
+       AUD_ReverseReader(AUD_IReader* reader);
+
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_REVERSEREADER
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
new file mode 100644 (file)
index 0000000..c321a13
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SquareFactory.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
+{
+       float in = reader->x(0);
+       if(in >= *threshold)
+               return 1;
+       else if(in <= -*threshold)
+               return -1;
+       else
+               return 0;
+}
+
+void endSquareFilter(float* threshold)
+{
+       delete threshold;
+}
+
+AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
+               AUD_EffectFactory(factory),
+               m_threshold(threshold)
+{
+}
+
+float AUD_SquareFactory::getThreshold() const
+{
+       return m_threshold;
+}
+
+AUD_IReader* AUD_SquareFactory::createReader() const
+{
+       return new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
+                                                                                  (doFilterIIR) squareFilter,
+                                                                                  (endFilterIIR) endSquareFilter,
+                                                                                  new float(m_threshold));
+}
diff --git a/intern/audaspace/FX/AUD_SquareFactory.h b/intern/audaspace/FX/AUD_SquareFactory.h
new file mode 100644 (file)
index 0000000..da87dc6
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SQUAREFACTORY
+#define AUD_SQUAREFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory Transforms any signal to a square signal.
+ */
+class AUD_SquareFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The threshold.
+        */
+       const float m_threshold;
+
+       // hide copy constructor and operator=
+       AUD_SquareFactory(const AUD_SquareFactory&);
+       AUD_SquareFactory& operator=(const AUD_SquareFactory&);
+
+public:
+       /**
+        * Creates a new square factory.
+        * \param factory The input factory.
+        * \param threshold The threshold.
+        */
+       AUD_SquareFactory(AUD_IFactory* factory, float threshold = 0.0f);
+
+       /**
+        * Returns the threshold.
+        */
+       float getThreshold() const;
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_SQUAREFACTORY
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
new file mode 100644 (file)
index 0000000..a128e50
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SumFactory.h"
+#include "AUD_IIRFilterReader.h"
+
+AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
+               AUD_EffectFactory(factory)
+{
+}
+
+AUD_IReader* AUD_SumFactory::createReader() const
+{
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back(-1);
+       b.push_back(1);
+       return new AUD_IIRFilterReader(getReader(), b, a);
+}
diff --git a/intern/audaspace/FX/AUD_SumFactory.h b/intern/audaspace/FX/AUD_SumFactory.h
new file mode 100644 (file)
index 0000000..045a0a3
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SUMFACTORY
+#define AUD_SUMFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a sum reader.
+ */
+class AUD_SumFactory : public AUD_EffectFactory
+{
+private:
+       // hide copy constructor and operator=
+       AUD_SumFactory(const AUD_SumFactory&);
+       AUD_SumFactory& operator=(const AUD_SumFactory&);
+
+public:
+       /**
+        * Creates a new sum factory.
+        * \param factory The input factory.
+        */
+       AUD_SumFactory(AUD_IFactory* factory);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_SUMFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
new file mode 100644 (file)
index 0000000..6bfc112
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SuperposeFactory.h"
+#include "AUD_SuperposeReader.h"
+
+AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+               m_factory1(factory1), m_factory2(factory2)
+{
+}
+
+AUD_IReader* AUD_SuperposeFactory::createReader() const
+{
+       AUD_IReader* reader1 = m_factory1->createReader();
+       AUD_IReader* reader2;
+       try
+       {
+               reader2 = m_factory2->createReader();
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1;
+               throw;
+       }
+
+       return new AUD_SuperposeReader(reader1, reader2);
+}
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h
new file mode 100644 (file)
index 0000000..a7fde2c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SUPERPOSEFACTORY
+#define AUD_SUPERPOSEFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory plays two other factories behind each other.
+ * \note Readers from the underlying factories must have the same sample rate and channel count.
+ */
+class AUD_SuperposeFactory : public AUD_IFactory
+{
+private:
+       /**
+        * First played factory.
+        */
+       AUD_IFactory* m_factory1;
+
+       /**
+        * Second played factory.
+        */
+       AUD_IFactory* m_factory2;
+
+       // hide copy constructor and operator=
+       AUD_SuperposeFactory(const AUD_SuperposeFactory&);
+       AUD_SuperposeFactory& operator=(const AUD_SuperposeFactory&);
+
+public:
+       /**
+        * Creates a new superpose factory.
+        * \param factory1 The first input factory.
+        * \param factory2 The second input factory.
+        */
+       AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_SUPERPOSEFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp
new file mode 100644 (file)
index 0000000..546b79a
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SuperposeReader.h"
+
+#include <cstring>
+
+static const char* specs_error = "AUD_SuperposeReader: Both readers have to "
+                                                                "have the same specs.";
+
+AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) :
+       m_reader1(reader1), m_reader2(reader2)
+{
+       try
+       {
+               AUD_Specs s1, s2;
+               s1 = reader1->getSpecs();
+               s2 = reader2->getSpecs();
+               if(memcmp(&s1, &s2, sizeof(AUD_Specs)))
+                       AUD_THROW(AUD_ERROR_SPECS, specs_error);
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1;
+               delete reader2;
+
+               throw;
+       }
+}
+
+AUD_SuperposeReader::~AUD_SuperposeReader()
+{
+       delete m_reader1;
+       delete m_reader2;
+}
+
+bool AUD_SuperposeReader::isSeekable() const
+{
+       return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void AUD_SuperposeReader::seek(int position)
+{
+       m_reader1->seek(position);
+       m_reader2->seek(position);
+}
+
+int AUD_SuperposeReader::getLength() const
+{
+       int len1 = m_reader1->getLength();
+       int len2 = m_reader2->getLength();
+       if((len1 < 0) || (len2 < 0))
+               return -1;
+       return AUD_MIN(len1, len2);
+}
+
+int AUD_SuperposeReader::getPosition() const
+{
+       int pos1 = m_reader1->getPosition();
+       int pos2 = m_reader2->getPosition();
+       return AUD_MAX(pos1, pos2);
+}
+
+AUD_Specs AUD_SuperposeReader::getSpecs() const
+{
+       return m_reader1->getSpecs();
+}
+
+void AUD_SuperposeReader::read(int & length, sample_t* & buffer)
+{
+       AUD_Specs specs = m_reader1->getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
+
+       if(m_buffer.getSize() < length * samplesize)
+               m_buffer.resize(length * samplesize);
+       buffer = m_buffer.getBuffer();
+
+       int len1 = length;
+       sample_t* buf;
+       m_reader1->read(len1, buf);
+       memcpy(buffer, buf, len1 * samplesize);
+
+       if(len1 < length)
+               memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
+
+       int len2 = length;
+       m_reader2->read(len2, buf);
+
+       for(int i = 0; i < len2 * specs.channels; i++)
+               buffer[i] += buf[i];
+
+       length = AUD_MAX(len1, len2);
+}
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
new file mode 100644 (file)
index 0000000..eeceb9a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SUPERPOSEREADER
+#define AUD_SUPERPOSEREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This reader plays two readers with the same specs sequently.
+ */
+class AUD_SuperposeReader : public AUD_IReader
+{
+private:
+       /**
+        * The first reader.
+        */
+       AUD_IReader* m_reader1;
+
+       /**
+        * The second reader.
+        */
+       AUD_IReader* m_reader2;
+
+       /**
+        * The playback buffer for the intersecting part.
+        */
+       AUD_Buffer m_buffer;
+
+       // hide copy constructor and operator=
+       AUD_SuperposeReader(const AUD_SuperposeReader&);
+       AUD_SuperposeReader& operator=(const AUD_SuperposeReader&);
+
+public:
+       /**
+        * Creates a new superpose reader.
+        * \param reader1 The first reader to read from.
+        * \param reader2 The second reader to read from.
+        * \exception AUD_Exception Thrown if the specs from the readers differ.
+        */
+       AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2);
+
+       /**
+        * Destroys the reader.
+        */
+       virtual ~AUD_SuperposeReader();
+
+       virtual bool isSeekable() const;
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual AUD_Specs getSpecs() const;
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SUPERPOSEREADER
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
new file mode 100644 (file)
index 0000000..1b341a5
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_VolumeFactory.h"
+#include "AUD_IIRFilterReader.h"
+
+AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
+               AUD_EffectFactory(factory),
+               m_volume(volume)
+{
+}
+
+float AUD_VolumeFactory::getVolume() const
+{
+       return m_volume;
+}
+
+AUD_IReader* AUD_VolumeFactory::createReader() const
+{
+       std::vector<float> a, b;
+       a.push_back(1);
+       b.push_back(m_volume);
+       return new AUD_IIRFilterReader(getReader(), b, a);
+}
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h
new file mode 100644 (file)
index 0000000..a086aab
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_VOLUMEFACTORY
+#define AUD_VOLUMEFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory changes the volume of another factory.
+ * The set volume should be a value between 0.0 and 1.0, higher values at your
+ * own risk!
+ */
+class AUD_VolumeFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The volume.
+        */
+       const float m_volume;
+
+       // hide copy constructor and operator=
+       AUD_VolumeFactory(const AUD_VolumeFactory&);
+       AUD_VolumeFactory& operator=(const AUD_VolumeFactory&);
+
+public:
+       /**
+        * Creates a new volume factory.
+        * \param factory The input factory.
+        * \param volume The desired volume.
+        */
+       AUD_VolumeFactory(AUD_IFactory* factory, float volume);
+
+       /**
+        * Returns the volume.
+        */
+       float getVolume() const;
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_VOLUMEFACTORY
diff --git a/intern/audaspace/FX/Makefile b/intern/audaspace/FX/Makefile
new file mode 100644 (file)
index 0000000..bda0e2b
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = aud_fx
+DIR = $(OCGDIR)/intern/audaspace
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I../ffmpeg
+CPPFLAGS += -I../intern
+CPPFLAGS += -I../SDL
+CPPFLAGS += -I../SRC
+CPPFLAGS += -I..
+CPPFLAGS += -I.
diff --git a/intern/audaspace/Makefile b/intern/audaspace/Makefile
new file mode 100644 (file)
index 0000000..c1a613a
--- /dev/null
@@ -0,0 +1,119 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
+#
+# $Id$
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): GSR
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+include nan_definitions.mk
+
+LIBNAME = audaspace
+SOURCEDIR = intern/audaspace
+DIR = $(OCGDIR)/$(SOURCEDIR)
+DIRS = intern
+DIRS += FX
+DIRS += SDL
+DIRS += SRC
+DIRS += Python
+
+ifeq ($(WITH_FFMPEG),true)
+  DIRS += ffmpeg
+endif
+
+ifeq ($(WITH_OPENAL),true)
+  DIRS += OpenAL
+endif
+
+ifeq ($(WITH_JACK),true)
+  DIRS += jack
+endif
+
+ifeq ($(WITH_SNDFILE),true)
+  DIRS += sndfile
+endif
+
+#ifeq ($(WITH_FFTW3),true)
+#  DIRS += fftw
+#endif
+
+include nan_subdirs.mk
+
+install: $(ALL_OR_DEBUG)
+       @[ -d $(NAN_AUDASPACE) ] || mkdir $(NAN_AUDASPACE)
+       @[ -d $(NAN_AUDASPACE)/include ] || mkdir $(NAN_AUDASPACE)/include
+       @[ -d $(NAN_AUDASPACE)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+       @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaudaspace.a $(DIR)/$(DEBUG_DIR)libaud_sdl.a $(DIR)/$(DEBUG_DIR)libaud_python.a $(DIR)/$(DEBUG_DIR)libaud_fx.a $(DIR)/$(DEBUG_DIR)libaud_src.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+
+ifeq ($(WITH_FFMPEG),true)
+       @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_ffmpeg.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+ifeq ($(WITH_OPENAL),true)
+       @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_openal.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+ifeq ($(WITH_JACK),true)
+       @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_jack.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+ifeq ($(WITH_SNDFILE),true)
+       @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_sndfile.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+#ifeq ($(WITH_FFTW3),true)
+#      @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_fftw.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+#endif
+
+ifeq ($(OS),darwin)
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaudaspace.a
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_src.a
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_fx.a
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sdl.a
+
+ifeq ($(WITH_FFMPEG),true)
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_ffmpeg.a
+endif
+
+ifeq ($(WITH_OPENAL),true)
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_openal.a
+endif
+
+ifeq ($(WITH_JACK),true)
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_jack.a
+endif
+
+ifeq ($(WITH_SNDFILE),true)
+       ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sndfile.a
+endif
+
+#ifeq ($(WITH_FFTW3),true)
+#      ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_fftw.a
+#endif
+
+endif
+       @../tools/cpifdiff.sh intern/*.h $(NAN_AUDASPACE)/include/
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
new file mode 100644 (file)
index 0000000..a87a4ad
--- /dev/null
@@ -0,0 +1,1623 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_OpenALDevice.h"
+#include "AUD_IFactory.h"
+#include "AUD_IReader.h"
+#include "AUD_ConverterReader.h"
+
+#include <cstring>
+#include <limits>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+#define AUD_OPENAL_CYCLE_BUFFERS 3
+
+/// Saves the data for playback.
+struct AUD_OpenALHandle : AUD_Handle
+{
+       /// Whether it's a buffered or a streamed source.
+       bool isBuffered;
+
+       /// The reader source.
+       AUD_IReader* reader;
+
+       /// Whether to keep the source if end of it is reached.
+       bool keep;
+
+       /// OpenAL sample format.
+       ALenum format;
+
+       /// OpenAL source.
+       ALuint source;
+
+       /// OpenAL buffers.
+       ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
+
+       /// The first buffer to be read next.
+       int current;
+
+       /// Whether the stream doesn't return any more data.
+       bool data_end;
+
+       /// The loop count of the source.
+       int loopcount;
+
+       /// The stop callback.
+       stopCallback stop;
+
+       /// Stop callback data.
+       void* stop_data;
+};
+
+struct AUD_OpenALBufferedFactory
+{
+       /// The factory.
+       AUD_IFactory* factory;
+
+       /// The OpenAL buffer.
+       ALuint buffer;
+};
+
+typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
+typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+
+/******************************************************************************/
+/**************************** Threading Code **********************************/
+/******************************************************************************/
+
+void* AUD_openalRunThread(void* device)
+{
+       AUD_OpenALDevice* dev = (AUD_OpenALDevice*)device;
+       dev->updateStreams();
+       return NULL;
+}
+
+void AUD_OpenALDevice::start()
+{
+       lock();
+
+       if(!m_playing)
+       {
+               pthread_attr_t attr;
+               pthread_attr_init(&attr);
+               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+               pthread_create(&m_thread, &attr, AUD_openalRunThread, this);
+
+               pthread_attr_destroy(&attr);
+
+               m_playing = true;
+       }
+
+       unlock();
+}
+
+void AUD_OpenALDevice::updateStreams()
+{
+       AUD_OpenALHandle* sound;
+
+       int length;
+       sample_t* buffer;
+
+       ALint info;
+       AUD_DeviceSpecs specs = m_specs;
+
+       while(1)
+       {
+               lock();
+
+               alcSuspendContext(m_context);
+
+               {
+                       // for all sounds
+                       for(AUD_HandleIterator it = m_playingSounds->begin(); it != m_playingSounds->end(); it++)
+                       {
+                               sound = *it;
+
+                               // is it a streamed sound?
+                               if(!sound->isBuffered)
+                               {
+                                       // check for buffer refilling
+                                       alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
+
+                                       if(info)
+                                       {
+                                               specs.specs = sound->reader->getSpecs();
+
+                                               // for all empty buffers
+                                               while(info--)
+                                               {
+                                                       // if there's still data to play back
+                                                       if(!sound->data_end)
+                                                       {
+                                                               // read data
+                                                               length = m_buffersize;
+                                                               sound->reader->read(length, buffer);
+
+                                                               // looping necessary?
+                                                               if(length == 0 && sound->loopcount)
+                                                               {
+                                                                       if(sound->loopcount > 0)
+                                                                               sound->loopcount--;
+
+                                                                       sound->reader->seek(0);
+
+                                                                       length = m_buffersize;
+                                                                       sound->reader->read(length, buffer);
+                                                               }
+
+                                                               // read nothing?
+                                                               if(length == 0)
+                                                               {
+                                                                       sound->data_end = true;
+                                                                       break;
+                                                               }
+
+                                                               // unqueue buffer
+                                                               alSourceUnqueueBuffers(sound->source, 1,
+                                                                                               &sound->buffers[sound->current]);
+                                                               ALenum err;
+                                                               if((err = alGetError()) != AL_NO_ERROR)
+                                                               {
+                                                                       sound->data_end = true;
+                                                                       break;
+                                                               }
+
+                                                               // fill with new data
+                                                               alBufferData(sound->buffers[sound->current],
+                                                                                        sound->format,
+                                                                                        buffer, length *
+                                                                                        AUD_DEVICE_SAMPLE_SIZE(specs),
+                                                                                        specs.rate);
+
+                                                               if((err = alGetError()) != AL_NO_ERROR)
+                                                               {
+                                                                       sound->data_end = true;
+                                                                       break;
+                                                               }
+
+                                                               // and queue again
+                                                               alSourceQueueBuffers(sound->source, 1,
+                                                                                               &sound->buffers[sound->current]);
+                                                               if(alGetError() != AL_NO_ERROR)
+                                                               {
+                                                                       sound->data_end = true;
+                                                                       break;
+                                                               }
+
+                                                               sound->current = (sound->current+1) %
+                                                                                                AUD_OPENAL_CYCLE_BUFFERS;
+                                                       }
+                                                       else
+                                                               break;
+                                               }
+                                       }
+                               }
+
+                               // check if the sound has been stopped
+                               alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
+
+                               if(info != AL_PLAYING)
+                               {
+                                       // if it really stopped
+                                       if(sound->data_end)
+                                       {
+                                               if(sound->stop)
+                                                       sound->stop(sound->stop_data);
+
+                                               // increment the iterator to the next value,
+                                               // because the sound gets deleted in the list here.
+                                               ++it;
+                                               // pause or
+                                               if(sound->keep)
+                                                       pause(sound);
+                                               // stop
+                                               else
+                                                       stop(sound);
+                                               // decrement again, so that we get the next sound in the
+                                               // next loop run
+                                               if(m_playingSounds->empty())
+                                                       break;
+                                               else
+                                                       --it;
+                                       }
+                                       // continue playing
+                                       else
+                                               alSourcePlay(sound->source);
+                               }
+                       }
+               }
+
+               alcProcessContext(m_context);
+
+               // stop thread
+               if(m_playingSounds->empty())
+               {
+                       unlock();
+                       m_playing = false;
+                       pthread_exit(NULL);
+               }
+
+               unlock();
+
+#ifdef WIN32
+               Sleep(20);
+#else
+               usleep(20000);
+#endif
+       }
+}
+
+/******************************************************************************/
+/**************************** IDevice Code ************************************/
+/******************************************************************************/
+
+bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
+{
+       for(AUD_HandleIterator i = m_playingSounds->begin();
+               i != m_playingSounds->end(); i++)
+               if(*i == handle)
+                       return true;
+       for(AUD_HandleIterator i = m_pausedSounds->begin();
+               i != m_pausedSounds->end(); i++)
+               if(*i == handle)
+                       return true;
+       return false;
+}
+
+static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened.";
+
+AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
+{
+       // cannot determine how many channels or which format OpenAL uses, but
+       // it at least is able to play 16 bit stereo audio
+       specs.channels = AUD_CHANNELS_STEREO;
+       specs.format = AUD_FORMAT_S16;
+
+#if 0
+       if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE)
+       {
+               ALCchar* devices = const_cast<ALCchar*>(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
+               printf("OpenAL devices (standard is: %s):\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
+
+               while(*devices)
+               {
+                       printf("%s\n", devices);
+                       devices += strlen(devices) + 1;
+               }
+       }
+#endif
+
+       m_device = alcOpenDevice(NULL);
+
+       if(!m_device)
+               AUD_THROW(AUD_ERROR_OPENAL, open_error);
+
+       // at least try to set the frequency
+       ALCint attribs[] = { ALC_FREQUENCY, specs.rate, 0 };
+       ALCint* attributes = attribs;
+       if(specs.rate == AUD_RATE_INVALID)
+               attributes = NULL;
+
+       m_context = alcCreateContext(m_device, attributes);
+       alcMakeContextCurrent(m_context);
+
+       alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
+
+       // check for specific formats and channel counts to be played back
+       if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
+               specs.format = AUD_FORMAT_FLOAT32;
+
+       m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
+
+       alGetError();
+
+       m_specs = specs;
+       m_buffersize = buffersize;
+       m_playing = false;
+
+       m_playingSounds = new std::list<AUD_OpenALHandle*>();
+       m_pausedSounds = new std::list<AUD_OpenALHandle*>();
+       m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
+
+       pthread_mutexattr_t attr;
+       pthread_mutexattr_init(&attr);
+       pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+       pthread_mutex_init(&m_mutex, &attr);
+
+       pthread_mutexattr_destroy(&attr);
+}
+
+AUD_OpenALDevice::~AUD_OpenALDevice()
+{
+       AUD_OpenALHandle* sound;
+
+       lock();
+       alcSuspendContext(m_context);
+
+       // delete all playing sounds
+       while(!m_playingSounds->empty())
+       {
+               sound = *(m_playingSounds->begin());
+               alDeleteSources(1, &sound->source);
+               if(!sound->isBuffered)
+               {
+                       delete sound->reader;
+                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+               }
+               delete sound;
+               m_playingSounds->erase(m_playingSounds->begin());
+       }
+
+       // delete all paused sounds
+       while(!m_pausedSounds->empty())
+       {
+               sound = *(m_pausedSounds->begin());
+               alDeleteSources(1, &sound->source);
+               if(!sound->isBuffered)
+               {
+                       delete sound->reader;
+                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+               }
+               delete sound;
+               m_pausedSounds->erase(m_pausedSounds->begin());
+       }
+
+       // delete all buffered factories
+       while(!m_bufferedFactories->empty())
+       {
+               alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
+               delete *m_bufferedFactories->begin();
+               m_bufferedFactories->erase(m_bufferedFactories->begin());
+       }
+
+       alcProcessContext(m_context);
+
+       // wait for the thread to stop
+       if(m_playing)
+       {
+               unlock();
+               pthread_join(m_thread, NULL);
+       }
+       else
+               unlock();
+
+       delete m_playingSounds;
+       delete m_pausedSounds;
+       delete m_bufferedFactories;
+
+       // quit OpenAL
+       alcMakeContextCurrent(NULL);
+       alcDestroyContext(m_context);
+       alcCloseDevice(m_device);
+
+       pthread_mutex_destroy(&m_mutex);
+}
+
+AUD_DeviceSpecs AUD_OpenALDevice::getSpecs() const
+{
+       return m_specs;
+}
+
+bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
+{
+       bool valid = true;
+       format = 0;
+
+       switch(m_specs.format)
+       {
+       case AUD_FORMAT_S16:
+               switch(specs.channels)
+               {
+               case AUD_CHANNELS_MONO:
+                       format = AL_FORMAT_MONO16;
+                       break;
+               case AUD_CHANNELS_STEREO:
+                       format = AL_FORMAT_STEREO16;
+                       break;
+               case AUD_CHANNELS_SURROUND4:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_QUAD16");
+                               break;
+                       }
+               case AUD_CHANNELS_SURROUND51:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_51CHN16");
+                               break;
+                       }
+               case AUD_CHANNELS_SURROUND61:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_61CHN16");
+                               break;
+                       }
+               case AUD_CHANNELS_SURROUND71:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_71CHN16");
+                               break;
+                       }
+               default:
+                       valid = false;
+               }
+               break;
+       case AUD_FORMAT_FLOAT32:
+               switch(specs.channels)
+               {
+               case AUD_CHANNELS_MONO:
+                       format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
+                       break;
+               case AUD_CHANNELS_STEREO:
+                       format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
+                       break;
+               case AUD_CHANNELS_SURROUND4:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_QUAD32");
+                               break;
+                       }
+               case AUD_CHANNELS_SURROUND51:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_51CHN32");
+                               break;
+                       }
+               case AUD_CHANNELS_SURROUND61:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_61CHN32");
+                               break;
+                       }
+               case AUD_CHANNELS_SURROUND71:
+                       if(m_useMC)
+                       {
+                               format = alGetEnumValue("AL_FORMAT_71CHN32");
+                               break;
+                       }
+               default:
+                       valid = false;
+               }
+               break;
+       default:
+               valid = false;
+       }
+
+       if(!format)
+               valid = false;
+
+       return valid;
+}
+
+static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
+                                                                        "generated.";
+static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
+                                                                        "generated.";
+static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
+                                                                "queued to the source.";
+static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
+                                                                         "filled with data.";
+
+AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
+{
+       lock();
+
+       AUD_OpenALHandle* sound = NULL;
+
+       try
+       {
+               // check if it is a buffered factory
+               for(AUD_BFIterator i = m_bufferedFactories->begin();
+                       i != m_bufferedFactories->end(); i++)
+               {
+                       if((*i)->factory == factory)
+                       {
+                               // create the handle
+                               sound = new AUD_OpenALHandle;
+                               sound->keep = keep;
+                               sound->current = -1;
+                               sound->isBuffered = true;
+                               sound->data_end = true;
+                               sound->loopcount = 0;
+                               sound->stop = NULL;
+                               sound->stop_data = NULL;
+
+                               alcSuspendContext(m_context);
+
+                               // OpenAL playback code
+                               try
+                               {
+                                       alGenSources(1, &sound->source);
+                                       if(alGetError() != AL_NO_ERROR)
+                                               AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
+
+                                       try
+                                       {
+                                               alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
+                                               if(alGetError() != AL_NO_ERROR)
+                                                       AUD_THROW(AUD_ERROR_OPENAL, queue_error);
+                                       }
+                                       catch(AUD_Exception&)
+                                       {
+                                               alDeleteSources(1, &sound->source);
+                                               throw;
+                                       }
+                               }
+                               catch(AUD_Exception&)
+                               {
+                                       delete sound;
+                                       alcProcessContext(m_context);
+                                       throw;
+                               }
+
+                               // play sound
+                               m_playingSounds->push_back(sound);
+
+                               alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+                               start();
+
+                               alcProcessContext(m_context);
+                       }
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               unlock();
+               throw;
+       }
+
+       unlock();
+
+       if(sound)
+               return sound;
+
+       AUD_IReader* reader = factory->createReader();
+
+       AUD_DeviceSpecs specs = m_specs;
+       specs.specs = reader->getSpecs();
+
+       // check format
+       bool valid = specs.channels != AUD_CHANNELS_INVALID;
+
+       if(m_specs.format != AUD_FORMAT_FLOAT32)
+               reader = new AUD_ConverterReader(reader, m_specs);
+
+       // create the handle
+       sound = new AUD_OpenALHandle;
+       sound->keep = keep;
+       sound->reader = reader;
+       sound->current = 0;
+       sound->isBuffered = false;
+       sound->data_end = false;
+       sound->loopcount = 0;
+       sound->stop = NULL;
+       sound->stop_data = NULL;
+
+       valid &= getFormat(sound->format, specs.specs);
+
+       if(!valid)
+       {
+               delete sound;
+               delete reader;
+               return NULL;
+       }
+
+       lock();
+       alcSuspendContext(m_context);
+
+       // OpenAL playback code
+       try
+       {
+               alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+               if(alGetError() != AL_NO_ERROR)
+                       AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
+
+               try
+               {
+                       sample_t* buf;
+                       int length;
+
+                       for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
+                       {
+                               length = m_buffersize;
+                               reader->read(length, buf);
+                               alBufferData(sound->buffers[i], sound->format, buf,
+                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
+                                                        specs.rate);
+                               if(alGetError() != AL_NO_ERROR)
+                                       AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
+                       }
+
+                       alGenSources(1, &sound->source);
+                       if(alGetError() != AL_NO_ERROR)
+                               AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
+
+                       try
+                       {
+                               alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
+                                                                        sound->buffers);
+                               if(alGetError() != AL_NO_ERROR)
+                                       AUD_THROW(AUD_ERROR_OPENAL, queue_error);
+                       }
+                       catch(AUD_Exception&)
+                       {
+                               alDeleteSources(1, &sound->source);
+                               throw;
+                       }
+               }
+               catch(AUD_Exception&)
+               {
+                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+                       throw;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               delete sound;
+               delete reader;
+               alcProcessContext(m_context);
+               unlock();
+               throw;
+       }
+
+       // play sound
+       m_playingSounds->push_back(sound);
+       alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+
+       start();
+
+       alcProcessContext(m_context);
+       unlock();
+
+       return sound;
+}
+
+bool AUD_OpenALDevice::pause(AUD_Handle* handle)
+{
+       bool result = false;
+
+       lock();
+
+       // only songs that are played can be paused
+       for(AUD_HandleIterator i = m_playingSounds->begin();
+               i != m_playingSounds->end(); i++)
+       {
+               if(*i == handle)
+               {
+                       m_pausedSounds->push_back(*i);
+                       alSourcePause((*i)->source);
+                       m_playingSounds->erase(i);
+                       result = true;
+                       break;
+               }
+       }
+
+       unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::resume(AUD_Handle* handle)
+{
+       bool result = false;
+
+       lock();
+
+       // only songs that are paused can be resumed
+       for(AUD_HandleIterator i = m_pausedSounds->begin();
+               i != m_pausedSounds->end(); i++)
+       {
+               if(*i == handle)
+               {
+                       m_playingSounds->push_back(*i);
+                       start();
+                       m_pausedSounds->erase(i);
+                       result = true;
+                       break;
+               }
+       }
+
+       unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::stop(AUD_Handle* handle)
+{
+       AUD_OpenALHandle* sound;
+
+       bool result = false;
+
+       lock();
+
+       for(AUD_HandleIterator i = m_playingSounds->begin();
+               i != m_playingSounds->end(); i++)
+       {
+               if(*i == handle)
+               {
+                       sound = *i;
+                       alDeleteSources(1, &sound->source);
+                       if(!sound->isBuffered)
+                       {
+                               delete sound->reader;
+                               alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+                       }
+                       delete *i;
+                       m_playingSounds->erase(i);
+                       result = true;
+                       break;
+               }
+       }
+       if(!result)
+       {
+               for(AUD_HandleIterator i = m_pausedSounds->begin();
+                       i != m_pausedSounds->end(); i++)
+               {
+                       if(*i == handle)
+                       {
+                               sound = *i;
+                               alDeleteSources(1, &sound->source);
+                               if(!sound->isBuffered)
+                               {
+                                       delete sound->reader;
+                                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+                               }
+                               delete *i;
+                               m_pausedSounds->erase(i);
+                               result = true;
+                               break;
+                       }
+               }
+       }
+
+       unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::getKeep(AUD_Handle* handle)
+{
+       bool result = false;
+
+       lock();
+
+       if(isValid(handle))
+               result = ((AUD_OpenALHandle*)handle)->keep;
+
+       unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
+{
+       bool result = false;
+
+       lock();
+
+       if(isValid(handle))
+       {
+               ((AUD_OpenALHandle*)handle)->keep = keep;
+               result = true;
+       }
+
+       unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
+{
+       bool result = false;
+
+       lock();
+
+       if(isValid(handle))
+       {
+               AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle;
+               if(alhandle->isBuffered)
+                       alSourcef(alhandle->source, AL_SEC_OFFSET, position);
+               else
+               {
+                       alhandle->reader->seek((int)(position *
+                                                                                alhandle->reader->getSpecs().rate));
+                       alhandle->data_end = false;
+
+                       ALint info;
+
+                       alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info);
+
+                       if(info != AL_PLAYING)
+                       {
+                               if(info == AL_PAUSED)
+                                       alSourceStop(alhandle->source);
+
+                               alSourcei(alhandle->source, AL_BUFFER, 0);
+                               alhandle->current = 0;
+
+                               ALenum err;
+                               if((err = alGetError()) == AL_NO_ERROR)
+                               {
+                                       sample_t* buf;
+                                       int length;
+                                       AUD_DeviceSpecs specs = m_specs;
+                                       specs.specs = alhandle->reader->getSpecs();
+
+                                       for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
+                                       {
+                                               length = m_buffersize;
+                                               alhandle->reader->read(length, buf);
+                                               alBufferData(alhandle->buffers[i], alhandle->format,
+                                                                        buf,
+                                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
+                                                                        specs.rate);
+
+                                               if(alGetError() != AL_NO_ERROR)
+                                                       break;
+                                       }
+
+                                       alSourceQueueBuffers(alhandle->source,
+                                                                                AUD_OPENAL_CYCLE_BUFFERS,
+                                                                                alhandle->buffers);
+                               }
+
+                               alSourceRewind(alhandle->source);
+                       }
+               }
+               result = true;
+       }
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
+{
+       float position = 0.0f;
+
+       lock();
+
+       if(isValid(handle))
+       {
+               AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
+               alGetSourcef(h->source, AL_SEC_OFFSET, &position);
+               if(!h->isBuffered)
+               {
+                       AUD_Specs specs = h->reader->getSpecs();
+                       position += (h->reader->getPosition() - m_buffersize *
+                                                                       AUD_OPENAL_CYCLE_BUFFERS) /
+                                          (float)specs.rate;
+               }
+       }
+
+       unlock();
+       return position;
+}
+
+AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
+{
+       AUD_Status status = AUD_STATUS_INVALID;
+
+       lock();
+
+       for(AUD_HandleIterator i = m_playingSounds->begin();
+               i != m_playingSounds->end(); i++)
+       {
+               if(*i == handle)
+               {
+                       status = AUD_STATUS_PLAYING;
+                       break;
+               }
+       }
+       if(status == AUD_STATUS_INVALID)
+       {
+               for(AUD_HandleIterator i = m_pausedSounds->begin();
+                       i != m_pausedSounds->end(); i++)
+               {
+                       if(*i == handle)
+                       {
+                               status = AUD_STATUS_PAUSED;
+                               break;
+                       }
+               }
+       }
+
+       unlock();
+
+       return status;
+}
+
+void AUD_OpenALDevice::lock()
+{
+       pthread_mutex_lock(&m_mutex);
+}
+
+void AUD_OpenALDevice::unlock()
+{
+       pthread_mutex_unlock(&m_mutex);
+}
+
+float AUD_OpenALDevice::getVolume() const
+{
+       float result;
+       alGetListenerf(AL_GAIN, &result);
+       return result;
+}
+
+void AUD_OpenALDevice::setVolume(float volume)
+{
+       alListenerf(AL_GAIN, volume);
+}
+
+float AUD_OpenALDevice::getVolume(AUD_Handle* handle)
+{
+       lock();
+       float result = std::numeric_limits<float>::quiet_NaN();
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result);
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume)
+{
+       lock();
+       bool result = isValid(handle);
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume);
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getPitch(AUD_Handle* handle)
+{
+       lock();
+       float result = std::numeric_limits<float>::quiet_NaN();
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result);
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
+{
+       lock();
+       bool result = isValid(handle);
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
+       unlock();
+       return result;
+}
+
+int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle)
+{
+       lock();
+       int result = 0;
+       if(isValid(handle))
+               result = ((AUD_OpenALHandle*)handle)->loopcount;
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
+{
+       lock();
+       bool result = isValid(handle);
+       if(result)
+               ((AUD_OpenALHandle*)handle)->loopcount = count;
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
+{
+       lock();
+       bool result = isValid(handle);
+       if(result)
+       {
+               AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
+               h->stop = callback;
+               h->stop_data = data;
+       }
+       unlock();
+       return result;
+}
+
+/* AUD_XXX Temorary disabled
+
+bool AUD_OpenALDevice::bufferFactory(void *value)
+{
+       bool result = false;
+       AUD_IFactory* factory = (AUD_IFactory*) value;
+
+       // load the factory into an OpenAL buffer
+       if(factory)
+       {
+               // check if the factory is already buffered
+               lock();
+               for(AUD_BFIterator i = m_bufferedFactories->begin();
+                       i != m_bufferedFactories->end(); i++)
+               {
+                       if((*i)->factory == factory)
+                       {
+                               result = true;
+                               break;
+                       }
+               }
+               unlock();
+               if(result)
+                       return result;
+
+               AUD_IReader* reader = factory->createReader();
+
+               if(reader == NULL)
+                       return false;
+
+               AUD_DeviceSpecs specs = m_specs;
+               specs.specs = reader->getSpecs();
+
+               if(m_specs.format != AUD_FORMAT_FLOAT32)
+                       reader = new AUD_ConverterReader(reader, m_specs);
+
+               ALenum format;
+
+               if(!getFormat(format, specs.specs))
+               {
+                       delete reader;
+                       return false;
+               }
+
+               // load into a buffer
+               lock();
+               alcSuspendContext(m_context);
+
+               AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
+               bf->factory = factory;
+
+               try
+               {
+                       alGenBuffers(1, &bf->buffer);
+                       if(alGetError() != AL_NO_ERROR)
+                               AUD_THROW(AUD_ERROR_OPENAL);
+
+                       try
+                       {
+                               sample_t* buf;
+                               int length = reader->getLength();
+
+                               reader->read(length, buf);
+                               alBufferData(bf->buffer, format, buf,
+                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
+                                                        specs.rate);
+                               if(alGetError() != AL_NO_ERROR)
+                                       AUD_THROW(AUD_ERROR_OPENAL);
+                       }
+                       catch(AUD_Exception&)
+                       {
+                               alDeleteBuffers(1, &bf->buffer);
+                               throw;
+                       }
+               }
+               catch(AUD_Exception&)
+               {
+                       delete bf;
+                       delete reader;
+                       alcProcessContext(m_context);
+                       unlock();
+                       return false;
+               }
+
+               m_bufferedFactories->push_back(bf);
+
+               alcProcessContext(m_context);
+               unlock();
+       }
+       else
+       {
+               // stop all playing and paused buffered sources
+               lock();
+               alcSuspendContext(m_context);
+
+               AUD_OpenALHandle* sound;
+               AUD_HandleIterator it = m_playingSounds->begin();
+               while(it != m_playingSounds->end())
+               {
+                       sound = *it;
+                       ++it;
+
+                       if(sound->isBuffered)
+                               stop(sound);
+               }
+               alcProcessContext(m_context);
+
+               while(!m_bufferedFactories->empty())
+               {
+                       alDeleteBuffers(1,
+                                                       &(*(m_bufferedFactories->begin()))->buffer);
+                       delete *m_bufferedFactories->begin();
+                       m_bufferedFactories->erase(m_bufferedFactories->begin());
+               }
+               unlock();
+       }
+
+       return true;
+}*/
+
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
+
+AUD_Vector3 AUD_OpenALDevice::getListenerLocation() const
+{
+       ALfloat p[3];
+       alGetListenerfv(AL_POSITION, p);
+       return AUD_Vector3(p[0], p[1], p[2]);
+}
+
+void AUD_OpenALDevice::setListenerLocation(const AUD_Vector3& location)
+{
+       alListenerfv(AL_POSITION, (ALfloat*)location.get());
+}
+
+AUD_Vector3 AUD_OpenALDevice::getListenerVelocity() const
+{
+       ALfloat v[3];
+       alGetListenerfv(AL_VELOCITY, v);
+       return AUD_Vector3(v[0], v[1], v[2]);
+}
+
+void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
+{
+       alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
+}
+
+AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
+{
+       // AUD_XXX not implemented yet
+       return AUD_Quaternion(0, 0, 0, 0);
+}
+
+void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
+{
+       ALfloat direction[6];
+       direction[0] = -2 * (orientation.w() * orientation.y() +
+                                                orientation.x() * orientation.z());
+       direction[1] = 2 * (orientation.x() * orientation.w() -
+                                               orientation.z() * orientation.y());
+       direction[2] = 2 * (orientation.x() * orientation.x() +
+                                               orientation.y() * orientation.y()) - 1;
+       direction[3] = 2 * (orientation.x() * orientation.y() -
+                                               orientation.w() * orientation.z());
+       direction[4] = 1 - 2 * (orientation.x() * orientation.x() +
+                                                       orientation.z() * orientation.z());
+       direction[5] = 2 * (orientation.w() * orientation.x() +
+                                               orientation.y() * orientation.z());
+       alListenerfv(AL_ORIENTATION, direction);
+}
+
+float AUD_OpenALDevice::getSpeedOfSound() const
+{
+       return alGetFloat(AL_SPEED_OF_SOUND);
+}
+
+void AUD_OpenALDevice::setSpeedOfSound(float speed)
+{
+       alSpeedOfSound(speed);
+}
+
+float AUD_OpenALDevice::getDopplerFactor() const
+{
+       return alGetFloat(AL_DOPPLER_FACTOR);
+}
+
+void AUD_OpenALDevice::setDopplerFactor(float factor)
+{
+       alDopplerFactor(factor);
+}
+
+AUD_DistanceModel AUD_OpenALDevice::getDistanceModel() const
+{
+       switch(alGetInteger(AL_DISTANCE_MODEL))
+       {
+       case AL_INVERSE_DISTANCE:
+               return AUD_DISTANCE_MODEL_INVERSE;
+       case AL_INVERSE_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
+       case AL_LINEAR_DISTANCE:
+               return AUD_DISTANCE_MODEL_LINEAR;
+       case AL_LINEAR_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
+       case AL_EXPONENT_DISTANCE:
+               return AUD_DISTANCE_MODEL_EXPONENT;
+       case AL_EXPONENT_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
+       default:
+               return AUD_DISTANCE_MODEL_INVALID;
+       }
+}
+
+void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
+{
+       switch(model)
+       {
+       case AUD_DISTANCE_MODEL_INVERSE:
+               alDistanceModel(AL_INVERSE_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
+               alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+               break;
+       case AUD_DISTANCE_MODEL_LINEAR:
+               alDistanceModel(AL_LINEAR_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
+               alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
+               break;
+       case AUD_DISTANCE_MODEL_EXPONENT:
+               alDistanceModel(AL_EXPONENT_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
+               alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
+               break;
+       default:
+               alDistanceModel(AL_NONE);
+       }
+}
+
+AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle)
+{
+       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+       ALfloat p[3];
+       lock();
+
+       if(isValid(handle))
+       {
+               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p);
+               result = AUD_Vector3(p[0], p[1], p[2]);
+       }
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION,
+                                  (ALfloat*)location.get());
+
+       unlock();
+       return result;
+}
+
+AUD_Vector3 AUD_OpenALDevice::getSourceVelocity(AUD_Handle* handle)
+{
+       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+       ALfloat v[3];
+       lock();
+
+       if(isValid(handle))
+       {
+               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v);
+               result = AUD_Vector3(v[0], v[1], v[2]);
+       }
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY,
+                                  (ALfloat*)velocity.get());
+
+       unlock();
+       return result;
+}
+
+AUD_Quaternion AUD_OpenALDevice::getSourceOrientation(AUD_Handle* handle)
+{
+       // AUD_XXX not implemented yet
+       return AUD_Quaternion(0, 0, 0, 0);
+}
+
+bool AUD_OpenALDevice::setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+       {
+               ALfloat direction[3];
+               direction[0] = -2 * (orientation.w() * orientation.y() +
+                                                        orientation.x() * orientation.z());
+               direction[1] = 2 * (orientation.x() * orientation.w() -
+                                                       orientation.z() * orientation.y());
+               direction[2] = 2 * (orientation.x() * orientation.x() +
+                                                       orientation.y() * orientation.y()) - 1;
+               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_DIRECTION,
+                                  direction);
+       }
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::isRelative(AUD_Handle* handle)
+{
+       int result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setRelative(AUD_Handle* handle, bool relative)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
+                                 relative);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getVolumeMaximum(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setVolumeMaximum(AUD_Handle* handle, float volume)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
+                                 volume);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getVolumeMinimum(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setVolumeMinimum(AUD_Handle* handle, float volume)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
+                                 volume);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getDistanceMaximum(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setDistanceMaximum(AUD_Handle* handle, float distance)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
+                                 distance);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getDistanceReference(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setDistanceReference(AUD_Handle* handle, float distance)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
+                                 distance);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getAttenuation(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setAttenuation(AUD_Handle* handle, float factor)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
+                                 factor);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getConeAngleOuter(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setConeAngleOuter(AUD_Handle* handle, float angle)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
+                                 angle);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getConeAngleInner(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setConeAngleInner(AUD_Handle* handle, float angle)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
+                                 angle);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getConeVolumeOuter(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setConeVolumeOuter(AUD_Handle* handle, float volume)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
+                                 volume);
+
+       unlock();
+       return result;
+}
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
new file mode 100644 (file)
index 0000000..985954f
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_OPENALDEVICE
+#define AUD_OPENALDEVICE
+
+#include "AUD_IDevice.h"
+#include "AUD_I3DDevice.h"
+struct AUD_OpenALHandle;
+struct AUD_OpenALBufferedFactory;
+
+#include <AL/al.h>
+#include <AL/alc.h>
+#include <list>
+#include <pthread.h>
+
+/**
+ * This device plays through OpenAL.
+ */
+class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
+{
+private:
+       /**
+        * The OpenAL device handle.
+        */
+       ALCdevice* m_device;
+
+       /**
+        * The OpenAL context.
+        */
+       ALCcontext* m_context;
+
+       /**
+        * The specification of the device.
+        */
+       AUD_DeviceSpecs m_specs;
+
+       /**
+        * Whether the device has the AL_EXT_MCFORMATS extension.
+        */
+       bool m_useMC;
+
+       /**
+        * The list of sounds that are currently playing.
+        */
+       std::list<AUD_OpenALHandle*>* m_playingSounds;
+
+       /**
+        * The list of sounds that are currently paused.
+        */
+       std::list<AUD_OpenALHandle*>* m_pausedSounds;
+
+       /**
+        * The list of buffered factories.
+        */
+       std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
+
+       /**
+        * The mutex for locking.
+        */
+       pthread_mutex_t m_mutex;
+
+       /**
+        * The streaming thread.
+        */
+       pthread_t m_thread;
+
+       /**
+        * The condition for streaming thread wakeup.
+        */
+       bool m_playing;
+
+       /**
+        * Buffer size.
+        */
+       int m_buffersize;
+
+       /**
+        * Starts the streaming thread.
+        */
+       void start();
+
+       /**
+        * Checks if a handle is valid.
+        * \param handle The handle to check.
+        * \return Whether the handle is valid.
+        */
+       bool isValid(AUD_Handle* handle);
+
+       /**
+        * Gets the format according to the specs.
+        * \param format The variable to put the format into.
+        * \param specs The specs to read the channel count from.
+        * \return Whether the format is valid or not.
+        */
+       bool getFormat(ALenum &format, AUD_Specs specs);
+
+       // hide copy constructor and operator=
+       AUD_OpenALDevice(const AUD_OpenALDevice&);
+       AUD_OpenALDevice& operator=(const AUD_OpenALDevice&);
+
+public:
+       /**
+        * Opens the OpenAL audio device for playback.
+        * \param specs The wanted audio specification.
+        * \param buffersize The size of the internal buffer.
+        * \note The specification really used for opening the device may differ.
+        * \note The buffersize will be multiplicated by three for this device.
+        * \exception AUD_Exception Thrown if the audio device cannot be opened.
+        */
+       AUD_OpenALDevice(AUD_DeviceSpecs specs,
+                                        int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+
+       /**
+        * Streaming thread main function.
+        */
+       void updateStreams();
+
+       virtual ~AUD_OpenALDevice();
+
+       virtual AUD_DeviceSpecs getSpecs() const;
+       virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
+       virtual bool pause(AUD_Handle* handle);
+       virtual bool resume(AUD_Handle* handle);
+       virtual bool stop(AUD_Handle* handle);
+       virtual bool getKeep(AUD_Handle* handle);
+       virtual bool setKeep(AUD_Handle* handle, bool keep);
+       virtual bool seek(AUD_Handle* handle, float position);
+       virtual float getPosition(AUD_Handle* handle);
+       virtual AUD_Status getStatus(AUD_Handle* handle);
+       virtual void lock();
+       virtual void unlock();
+       virtual float getVolume() const;
+       virtual void setVolume(float volume);
+       virtual float getVolume(AUD_Handle* handle);
+       virtual bool setVolume(AUD_Handle* handle, float volume);
+       virtual float getPitch(AUD_Handle* handle);
+       virtual bool setPitch(AUD_Handle* handle, float pitch);
+       virtual int getLoopCount(AUD_Handle* handle);
+       virtual bool setLoopCount(AUD_Handle* handle, int count);
+       virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL);
+
+       virtual AUD_Vector3 getListenerLocation() const;
+       virtual void setListenerLocation(const AUD_Vector3& location);
+       virtual AUD_Vector3 getListenerVelocity() const;
+       virtual void setListenerVelocity(const AUD_Vector3& velocity);
+       virtual AUD_Quaternion getListenerOrientation() const;
+       virtual void setListenerOrientation(const AUD_Quaternion& orientation);
+       virtual float getSpeedOfSound() const;
+       virtual void setSpeedOfSound(float speed);
+       virtual float getDopplerFactor() const;
+       virtual void setDopplerFactor(float factor);
+       virtual AUD_DistanceModel getDistanceModel() const;
+       virtual void setDistanceModel(AUD_DistanceModel model);
+       virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle);
+       virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location);
+       virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle);
+       virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity);
+       virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle);
+       virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation);
+       virtual bool isRelative(AUD_Handle* handle);
+       virtual bool setRelative(AUD_Handle* handle, bool relative);
+       virtual float getVolumeMaximum(AUD_Handle* handle);
+       virtual bool setVolumeMaximum(AUD_Handle* handle, float volume);
+       virtual float getVolumeMinimum(AUD_Handle* handle);
+       virtual bool setVolumeMinimum(AUD_Handle* handle, float volume);
+       virtual float getDistanceMaximum(AUD_Handle* handle);
+       virtual bool setDistanceMaximum(AUD_Handle* handle, float distance);
+       virtual float getDistanceReference(AUD_Handle* handle);
+       virtual bool setDistanceReference(AUD_Handle* handle, float distance);
+       virtual float getAttenuation(AUD_Handle* handle);
+       virtual bool setAttenuation(AUD_Handle* handle, float factor);
+       virtual float getConeAngleOuter(AUD_Handle* handle);
+       virtual bool setConeAngleOuter(AUD_Handle* handle, float angle);
+       virtual float getConeAngleInner(AUD_Handle* handle);
+       virtual bool setConeAngleInner(AUD_Handle* handle, float angle);
+       virtual float getConeVolumeOuter(AUD_Handle* handle);
+       virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume);
+};
+
+#endif //AUD_OPENALDEVICE
diff --git a/intern/audaspace/OpenAL/Makefile b/intern/audaspace/OpenAL/Makefile
new file mode 100644 (file)
index 0000000..4cf9f66
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = aud_openal
+DIR = $(OCGDIR)/intern/audaspace
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I../intern
+CPPFLAGS += -I.
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
new file mode 100644 (file)
index 0000000..b0c55d5
--- /dev/null
@@ -0,0 +1,2973 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * AudaSpace is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_PyAPI.h"
+#include "structmember.h"
+
+#include "AUD_I3DDevice.h"
+#include "AUD_NULLDevice.h"
+#include "AUD_DelayFactory.h"
+#include "AUD_DoubleFactory.h"
+#include "AUD_FaderFactory.h"
+#include "AUD_HighpassFactory.h"
+#include "AUD_LimiterFactory.h"
+#include "AUD_LoopFactory.h"
+#include "AUD_LowpassFactory.h"
+#include "AUD_PingPongFactory.h"
+#include "AUD_PitchFactory.h"
+#include "AUD_ReverseFactory.h"
+#include "AUD_SinusFactory.h"
+#include "AUD_FileFactory.h"
+#include "AUD_SquareFactory.h"
+#include "AUD_StreamBufferFactory.h"
+#include "AUD_SuperposeFactory.h"
+#include "AUD_VolumeFactory.h"
+#include "AUD_IIRFilterFactory.h"
+
+#ifdef WITH_SDL
+#include "AUD_SDLDevice.h"
+#endif
+
+#ifdef WITH_OPENAL
+#include "AUD_OpenALDevice.h"
+#endif
+
+#ifdef WITH_JACK
+#include "AUD_JackDevice.h"
+#endif
+
+// ====================================================================
+
+typedef enum
+{
+       AUD_DEVICE_NULL = 0,
+       AUD_DEVICE_OPENAL,
+       AUD_DEVICE_SDL,
+       AUD_DEVICE_JACK,
+       AUD_DEVICE_READ,
+} AUD_DeviceTypes;
+
+// ====================================================================
+
+#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
+
+// ====================================================================
+
+static PyObject* AUDError;
+
+static const char* device_not_3d_error = "Device is not a 3D device!";
+
+// ====================================================================
+
+static void
+Factory_dealloc(Factory* self)
+{
+       if(self->factory)
+               delete self->factory;
+       Py_XDECREF(self->child_list);
+       Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+       Factory *self;
+
+       self = (Factory*)type->tp_alloc(type, 0);
+       if(self != NULL)
+       {
+               static const char *kwlist[] = {"filename", NULL};
+               const char* filename = NULL;
+
+               if(!PyArg_ParseTupleAndKeywords(args, kwds, "s:Factory", const_cast<char**>(kwlist), &filename))
+               {
+                       Py_DECREF(self);
+                       return NULL;
+               }
+
+               try
+               {
+                       self->factory = new AUD_FileFactory(filename);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(self);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Factory_sine_doc,
+                        "sine(frequency, rate=44100)\n\n"
+                        "Creates a sine factory which plays a sine wave.\n\n"
+                        ":arg frequency: The frequency of the sine wave in Hz.\n"
+                        ":type frequency: float\n"
+                        ":arg rate: The sampling rate in Hz. It's recommended to set this "
+                        "value to the playback device's samling rate to avoid resamping.\n"
+                        ":type rate: int\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`");
+
+static PyObject *
+Factory_sine(PyTypeObject* type, PyObject* args)
+{
+       float frequency;
+       int rate = 44100;
+
+       if(!PyArg_ParseTuple(args, "f|i:sine", &frequency, &rate))
+               return NULL;
+
+       Factory *self;
+
+       self = (Factory*)type->tp_alloc(type, 0);
+       if(self != NULL)
+       {
+               try
+               {
+                       self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)rate);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(self);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Factory_file_doc,
+                        "file(filename)\n\n"
+                        "Creates a factory object of a sound file.\n\n"
+                        ":arg filename: Path of the file.\n"
+                        ":type filename: string\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. warning:: If the file doesn't exist or can't be read you will "
+                        "not get an exception immediately, but when you try to start "
+                        "playback of that factory.");
+
+static PyObject *
+Factory_file(PyTypeObject* type, PyObject* args)
+{
+       const char* filename = NULL;
+
+       if(!PyArg_ParseTuple(args, "s:file", &filename))
+               return NULL;
+
+       Factory *self;
+
+       self = (Factory*)type->tp_alloc(type, 0);
+       if(self != NULL)
+       {
+               try
+               {
+                       self->factory = new AUD_FileFactory(filename);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(self);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Factory_lowpass_doc,
+                        "lowpass(frequency, Q=0.5)\n\n"
+                        "Creates a second order lowpass filter based on the transfer "
+                        "function H(s) = 1 / (s^2 + s/Q + 1)\n\n"
+                        ":arg frequency: The cut off trequency of the lowpass.\n"
+                        ":type frequency: float\n"
+                        ":arg Q: Q factor of the lowpass.\n"
+                        ":type Q: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`");
+
+static PyObject *
+Factory_lowpass(Factory* self, PyObject* args)
+{
+       float frequency;
+       float Q = 0.5;
+
+       if(!PyArg_ParseTuple(args, "f|f:lowpass", &frequency, &Q))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_LowpassFactory(self->factory, frequency, Q);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_delay_doc,
+                        "delay(time)\n\n"
+                        "Delays by playing adding silence in front of the other factory's "
+                        "data.\n\n"
+                        ":arg time: How many seconds of silence should be added before "
+                        "the factory.\n"
+                        ":type time: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`");
+
+static PyObject *
+Factory_delay(Factory* self, PyObject* args)
+{
+       float delay;
+
+       if(!PyArg_ParseTuple(args, "f:delay", &delay))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_DelayFactory(self->factory, delay);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_join_doc,
+                        "join(factory)\n\n"
+                        "Plays two factories in sequence.\n\n"
+                        ":arg factory: The factory to play second.\n"
+                        ":type factory: :class:`Factory`\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: The two factories have to have the same specifications "
+                        "(channels and samplerate).");
+
+static PyObject *
+Factory_join(Factory* self, PyObject* object)
+{
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+
+       if(!PyObject_TypeCheck(object, type))
+       {
+               PyErr_SetString(PyExc_TypeError, "Object has to be of type Factory!");
+               return NULL;
+       }
+
+       Factory *parent;
+       Factory *child = (Factory*)object;
+
+       parent = (Factory*)type->tp_alloc(type, 0);
+       if(parent != NULL)
+       {
+               parent->child_list = Py_BuildValue("(OO)", self, object);
+
+               try
+               {
+                       parent->factory = new AUD_DoubleFactory(self->factory, child->factory);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_highpass_doc,
+                        "highpass(frequency, Q=0.5)\n\n"
+                        "Creates a second order highpass filter based on the transfer "
+                        "function H(s) = s^2 / (s^2 + s/Q + 1)\n\n"
+                        ":arg frequency: The cut off trequency of the highpass.\n"
+                        ":type frequency: float\n"
+                        ":arg Q: Q factor of the lowpass.\n"
+                        ":type Q: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`");
+
+static PyObject *
+Factory_highpass(Factory* self, PyObject* args)
+{
+       float frequency;
+       float Q = 0.5;
+
+       if(!PyArg_ParseTuple(args, "f|f:highpass", &frequency, &Q))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_HighpassFactory(self->factory, frequency, Q);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_limit_doc,
+                        "limit(start, end)\n\n"
+                        "Limits a factory within a specific start and end time.\n\n"
+                        ":arg start: Start time in seconds.\n"
+                        ":type start: float\n"
+                        ":arg end: End time in seconds.\n"
+                        ":type end: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`");
+
+static PyObject *
+Factory_limit(Factory* self, PyObject* args)
+{
+       float start, end;
+
+       if(!PyArg_ParseTuple(args, "ff:limit", &start, &end))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_LimiterFactory(self->factory, start, end);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_pitch_doc,
+                        "pitch(factor)\n\n"
+                        "Changes the pitch of a factory with a specific factor.\n\n"
+                        ":arg factor: The factor to change the pitch with.\n"
+                        ":type factor: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: This is done by changing the sample rate of the "
+                        "underlying factory, which has to be an integer, so the factor "
+                        "value rounded and the factor may not be 100 % accurate.\n\n"
+                        ".. note:: This is a filter function, you might consider using "
+                        ":attr:`Handle.pitch` instead.");
+
+static PyObject *
+Factory_pitch(Factory* self, PyObject* args)
+{
+       float factor;
+
+       if(!PyArg_ParseTuple(args, "f:pitch", &factor))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_PitchFactory(self->factory, factor);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_volume_doc,
+                        "volume(volume)\n\n"
+                        "Changes the volume of a factory.\n\n"
+                        ":arg volume: The new volume..\n"
+                        ":type volume: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
+                        ".. note:: This is a filter function, you might consider using "
+                        ":attr:`Handle.volume` instead.");
+
+static PyObject *
+Factory_volume(Factory* self, PyObject* args)
+{
+       float volume;
+
+       if(!PyArg_ParseTuple(args, "f:volume", &volume))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_VolumeFactory(self->factory, volume);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_fadein_doc,
+                        "fadein(start, length)\n\n"
+                        "Fades a factory in by raising the volume linearly in the given "
+                        "time interval.\n\n"
+                        ":arg start: Time in seconds when the fading should start.\n"
+                        ":type start: float\n"
+                        ":arg length: Time in seconds how long the fading should last.\n"
+                        ":type length: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: Before the fade starts it plays silence.");
+
+static PyObject *
+Factory_fadein(Factory* self, PyObject* args)
+{
+       float start, length;
+
+       if(!PyArg_ParseTuple(args, "ff:fadein", &start, &length))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_IN, start, length);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_fadeout_doc,
+                        "fadeout(start, length)\n\n"
+                        "Fades a factory in by lowering the volume linearly in the given "
+                        "time interval.\n\n"
+                        ":arg start: Time in seconds when the fading should start.\n"
+                        ":type start: float\n"
+                        ":arg length: Time in seconds how long the fading should last.\n"
+                        ":type length: float\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: After the fade this factory plays silence, so that "
+                        "the length of the factory is not altered.");
+
+static PyObject *
+Factory_fadeout(Factory* self, PyObject* args)
+{
+       float start, length;
+
+       if(!PyArg_ParseTuple(args, "ff:fadeout", &start, &length))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_OUT, start, length);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_loop_doc,
+                        "loop(count)\n\n"
+                        "Loops a factory.\n\n"
+                        ":arg count: How often the factory should be looped. "
+                        "Negative values mean endlessly.\n"
+                        ":type count: integer\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: This is a filter function, you might consider using "
+                        ":attr:`Handle.loop_count` instead.");
+
+static PyObject *
+Factory_loop(Factory* self, PyObject* args)
+{
+       int loop;
+
+       if(!PyArg_ParseTuple(args, "i:loop", &loop))
+               return NULL;
+
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_LoopFactory(self->factory, loop);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_mix_doc,
+                        "mix(factory)\n\n"
+                        "Mixes two factories.\n\n"
+                        ":arg factory: The factory to mix over the other.\n"
+                        ":type factory: :class:`Factory`\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: The two factories have to have the same specifications "
+                        "(channels and samplerate).");
+
+static PyObject *
+Factory_mix(Factory* self, PyObject* object)
+{
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+
+       if(!PyObject_TypeCheck(object, type))
+       {
+               PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
+               return NULL;
+       }
+
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+       Factory *child = (Factory*)object;
+
+       if(parent != NULL)
+       {
+               parent->child_list = Py_BuildValue("(OO)", self, object);
+
+               try
+               {
+                       parent->factory = new AUD_SuperposeFactory(self->factory, child->factory);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_pingpong_doc,
+                        "pingpong()\n\n"
+                        "Plays a factory forward and then backward.\n"
+                        "This is like joining a factory with its reverse.\n\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`");
+
+static PyObject *
+Factory_pingpong(Factory* self)
+{
+       PyTypeObject* type = ((PyObject*)self)->ob_type;
+       Factory *parent = (Factory*)type->tp_alloc(type, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_PingPongFactory(self->factory);
+               }
+               catch(AUD_Exception& e)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, e.str);
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Factory_reverse_doc,
+                        "reverse()\n\n"
+                        "Plays a factory reversed.\n\n"
+                        ":return: The created :class:`Factory` object.\n"
+                        ":rtype: :class:`Factory`\n\n"
+                        ".. note:: The factory has to have a finite length and has to be "
+                        "seekable. It's recommended to use this only with factories     with "
+                        "fast and accurate seeking, which is not true for encoded audio "
+                        "files, such ones should be buffered using :meth:`buffer` before "
+                        "being played reversed.\n\n"
+                        ".. warning:: If seeking is not accurate in the underlying factory "
+                        "you'll likely hear skips/jumps/cracks.